Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wiAkh-00038c-1g for pgsql-hackers@arkaria.postgresql.org; Fri, 10 Jul 2026 12:54:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wiAke-000I9w-3A for pgsql-hackers@arkaria.postgresql.org; Fri, 10 Jul 2026 12:54:45 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wiAke-000I9o-22 for pgsql-hackers@lists.postgresql.org; Fri, 10 Jul 2026 12:54:45 +0000 Received: from mail-vs1-xe32.google.com ([2607:f8b0:4864:20::e32]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wiAkc-00000000eaW-1HeG for pgsql-hackers@lists.postgresql.org; Fri, 10 Jul 2026 12:54:45 +0000 Received: by mail-vs1-xe32.google.com with SMTP id ada2fe7eead31-7391d5504b5so531350137.3 for ; Fri, 10 Jul 2026 05:54:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1783688081; cv=none; d=google.com; s=arc-20260327; b=MCZDtSoKxzu+QzBkGNwuAPugx0m6wQKRtScfRym/YhLcmau+NexQESaeqJZGSD688+ dFblk9H+olzmKkY9Fxl/yu1M2G5u+dJsecaOkyEK/P0EVKI2dxRVd8f2tte9BnFKqEHE yMYqWllxZtneVCdTBTjEKZzvSS7MXjVYglAkzPEAxNvmUajDX8had3+Jfs4yeCqXZXdk 7Xm5SC4l+oc+f9cFOAJ1hZj/j02wi1VDw+HeBAgIuMrI3dHEcFeixOAebC7KahRant65 7tMitnzYfkkEM/AD18xrtk6HU098w1NE9Cy7Bj3PDK9i/DrXcyjjk35x+cMUQQN6P4Ee kveg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=+v87FGP2EdmiZqrm537oAqpQzlY4frDtOD+c666pqpc=; fh=Qwy/OR5VqZpihss3nWYEeT8x0GG5ieYE82eO87ELm30=; b=UChmQzaq8warUsQaagZl0x7y86bf5yTI61TivtPF9vuiXdvsCuj6XErt7mkkDuVTDs GWWaRPx6JIYsOZNM/2dFmofBUk4dZ+V7IrxQ2SE5TO/iGkE7TqhsFYWDwJlqiANgQzlP 1oys5vmI7Pp3hueoN9WIwgfr2lcTE7NfMX2cannii/E9ndGH8V4SbZOM+BnzvaJFETr1 H0XyKhwdmJnOUPtpIYf9Vxv4Y3huFsSJMW8YvGP3xi3yIWiDbH4O90UZ/4Kh+jZnvOLn J9DdBsPRiAmKhmJYYv3lM2dTnYWIfOrpMPgyFfvmjK02k+THw/FAoTre4QLRvYqsldoY rl9w==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783688081; x=1784292881; darn=lists.postgresql.org; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:from:to:cc:subject:date:message-id:reply-to :content-type; bh=+v87FGP2EdmiZqrm537oAqpQzlY4frDtOD+c666pqpc=; b=KZ/isQV2MFt+b/jlXUaA6y2nNsaeasYMODCH4E3vlGOrG8013vJKnddBdx6bt/oQ2y L2ML+aFdMaqUZ7dTAZkbIyhcHtHEaw9CpGjMRZ51Mezb/+nBcEv3yInsBQNSI7F73Tp9 vBOncnae7WIQje3ZxrWCQ7EPJUGhqV01O7iF/OTW4LpR2JDh0Rid6CiFlExvwrXJhCF4 fXgxEB7KL3gPOwgRkkaEiEZgQwbBBTtpBGwg2yxf4p4N6ldP7qnn2zH+LoNu/aG6ln73 fq5oq+kKwkP/Zoe+QLBvmp+98+z83XMrfulHiEmCWSuYeZQbwIdnSVZwXS+SYbBuoYIj 53Cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783688081; x=1784292881; h=content-type:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to:content-type; bh=+v87FGP2EdmiZqrm537oAqpQzlY4frDtOD+c666pqpc=; b=PAW54KFeh6FLnLR43JqE8k0Q5P9nu4ExqsI2FqxwSXkvb0fPdh+M9BaWKFWGzfvIu0 0QlrcsLed9eBUaCGCCKGrJt6AD9Xj1u7kFgP64axgpxpkMWv4/pHo6Ctt5SFXRq97+/n UPXZJCTZRhFrjInTWETqEjB6tCdGpoWc2Bfg9gAVx/Y4CCfMa18rCv0qelIqhOjOaO7C Ox5j8RFBAUyb5V4ZzZMFsiSc4Oem/DD5Hs6GsMgU+TTDqyIYNIi7GcKHIhF2jyu00meU c/rYRgdhn97h875yZBDOt+Vw03xoD/ATnUu3UokyrzmAwrT5KeQ439H33upzL+i3VxX5 F7Sg== X-Gm-Message-State: AOJu0YyAafr8jp5kKWW+cdgp4YzSYIsMythe9pGDBSh6SfzmEApSFWOS mSEJ17U8RZGak4NrhIOWgSBvpLByyZ+GqTELWViNoi5VdCNJteaW584Zj267rm9fsQ6L/Rt6OhI MgVnjalB+eP5NfmdaElOvJkq48zc73+NAEp4gX8Y= X-Gm-Gg: AfdE7cmd2HxQL4Oy8AvV/7dMR5D+wb2JW7a1hzTU8iQ9ONETsXIVX/KLgFiCx7pISuH ThjSj3mocS6Zal06D/RGMrLD8l1zToFlsEkXxegaJikbCKtesuWkwxod9uGhYlPbbt9y9dR52vQ btdM5kZArl/UIFi7T6dTa5afZmNhDVe6L1W16iSw/f0iAT/Rq+fdMtOTAKuW7QyLuPFyW/uFSuD PeQkatsvfd0UXF75Bn+dJURiY2wf4xM+We2gV6GHUCIQKwlRZ/EMY0It0L2SU13LgSZTvk= X-Received: by 2002:a05:6102:41a6:b0:631:37cb:1e64 with SMTP id ada2fe7eead31-744e0010124mr7391229137.4.1783688080729; Fri, 10 Jul 2026 05:54:40 -0700 (PDT) MIME-Version: 1.0 References: <3f423bd9038afd4d38d8b916672055ad6c46ed2c.camel@cybertec.at> In-Reply-To: <3f423bd9038afd4d38d8b916672055ad6c46ed2c.camel@cybertec.at> From: prankware Date: Fri, 10 Jul 2026 15:54:27 +0300 X-Gm-Features: AUfX_mwxPTKHzWCe9ZghvfM9v7imW7onYDCuxzmJkShCCqlt8pqGaMOzdv9h71k Message-ID: Subject: Re: COALESCE patch To: pgsql-hackers@lists.postgresql.org Cc: Laurenz Albe , ilya.evdokimov@tantorlabs.com Content-Type: multipart/mixed; boundary="0000000000007148d20656413e42" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000007148d20656413e42 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks for the review =E2=80=94 the test cases were very helpful. You're right that v1 didn't improve the coalesce(col, const) case. The reason is that a comparison of two constants got the default 0.005 instead of its real result, and joins with a constant on both sides were skipped entirely. v2 (attached) fixes both, and these four examples now estimate close to the actual row counts. Regards, Egor Savelev, Tantor Labs LLC, https://tantorlabs.com =D0=BF=D1=82, 10 =D0=B8=D1=8E=D0=BB. 2026=E2=80=AF=D0=B3. =D0=B2 12:27, Lau= renz Albe : > > On Tue, 2026-06-30 at 16:48 +0300, prankware wrote: > > > The planner ignores column statistics when an equality has a COALESCE > > expression on one side. For a clause like COALESCE(a, b) =3D $1, or a j= oin on > > COALESCE(t1.a, t1.b) =3D COALESCE(t2.c, t2.d), there are no statistics = on the > > COALESCE node itself, so eqsel() and eqjoinsel() return the generic 0.0= 05 > > estimate while the per-column stats for a, b, c and d sit unused. The o= nly way > > around this today is an expression index or extended statistics on that= exact > > expression, which doesn't scale across many different COALESCE clauses. > > estimate_hash_bucket_stats() has the same gap: a COALESCE hash key gets= a > > default ndistinct and therefore a default bucket size. Since these expr= essions > > are common in joins and filters over nullable or fallback columns, the = default > > estimate can be far enough off to flip the join order or join method. > > > > The idea is to estimate straight from the existing per-column stats, wi= th no > > extra statistics object. COALESCE(arg_1, ..., arg_n) returns arg_i only= when > > arg_1 .. arg_{i-1} are all NULL, so the chance of reaching branch i is = the > > product of stanullfrac over the earlier branches. Selectivity of > > COALESCE(l_1..l_M) =3D COALESCE(r_1..r_N) is then the sum over branch p= airs of > > P(reach l_i) * P(reach r_j) * sel(l_i =3D r_j), and each sel(l_i =3D r_= j) is a > > recursive call back into eqsel()/eqjoinsel(). A non-COALESCE side is tr= eated as > > a one-branch list, so scalar COALESCE(a, b) =3D const falls out of the = same code, > > and the same decomposition feeds estimate_hash_bucket_stats(). If any b= ranch is > > missing stats, the code bails and today's behavior is unchanged. > > > > Feedback is welcome. > > I think the idea is good, and the performance cost is incurred only when > coalesce() expressions are present. I am a bit worried about the executi= on > time for queries that join two tables over lengthy coalesce clauses, as t= he > cost is O(n*m) because of the sum. But I think that such queries are ext= remely > rare, so I don't worry too much. > > I found that the estimates are good if I use expressions like > "coalesce(col1, col2)" in my query, but the estimates are as bad as befor= e > with the common case of "coalesce(col, constant)": > > CREATE TABLE b (col1 integer); > > /* three quarters NULL, the rest evenly distributed */ > INSERT INTO b > SELECT CASE WHEN random() >=3D 0.75 THEN random() * 1000 + 1 END > FROM generate_series(1, 10000); > > VACUUM (ANALYZE) b; > > /* force a hash join regardless of the estimates */ > SET work_mem =3D '512MB'; > SET enable_mergejoin =3D off; > SET enable_nestloop =3D off; > > > EXPLAIN (ANALYZE, SUMMARY OFF, BUFFERS OFF) > SELECT * > FROM b AS b1 > JOIN b AS b2 ON coalesce(b1.col1, 0) =3D coalesce(b2.col1, 0); > > Hash Join (... rows=3D500000 ...) (actual ... rows=3D55125006.00 ...) > Hash Cond: (COALESCE(b1.col1, 0) =3D COALESCE(b2.col1, 0)) > -> Seq Scan on b b1 (... rows=3D10000 ...) (actual ... rows=3D10000.= 00 ..) > -> Hash (... rows=3D10000 ...) (actual ... rows=3D10000.00 ...) > Buckets: 16384 Batches: 1 Memory Usage: 451kB > -> Seq Scan on b b2 (... rows=3D10000 ...) (actual ... rows=3D= 10000.00 ...) > > EXPLAIN (ANALYZE, SUMMARY OFF, BUFFERS OFF) > SELECT * > FROM b AS b1 > JOIN b AS b2 ON coalesce(b1.col1, 0) =3D coalesce(b2.col1, 1); > > Hash Join (... rows=3D500000 ...) (actual ... rows=3D16654.00 ...) > Hash Cond: (COALESCE(b1.col1, 0) =3D COALESCE(b2.col1, 1)) > -> Seq Scan on b b1 (... rows=3D10000 ...) (actual ... rows=3D10000.= 00 ...) > -> Hash (... rows=3D10000 ...) (actual ... rows=3D10000.00 ...) > Buckets: 16384 Batches: 1 Memory Usage: 451kB > -> Seq Scan on b b2 (... rows=3D10000 ...) (actual ... rows=3D= 10000.00 ...) > > > EXPLAIN (ANALYZE, SUMMARY OFF, BUFFERS OFF) > SELECT * FROM b WHERE coalesce(col1, 0) =3D 0; > > Seq Scan on b (... rows=3D40 ...) (actual ... rows=3D7424.00 ...) > Filter: (COALESCE(col1, 0) =3D 0) > Rows Removed by Filter: 2576 > > EXPLAIN (ANALYZE, SUMMARY OFF, BUFFERS OFF) > SELECT * FROM b WHERE coalesce(col1, 1) =3D 0; > > Seq Scan on b (... rows=3D40 ...) (actual ... rows=3D0.00 ...) > Filter: (COALESCE(col1, 1) =3D 0) > Rows Removed by Filter: 10000 > > > I think that the patch would be much more useful if it could improve > such estimates. > > Yours, > Laurenz Albe --0000000000007148d20656413e42 Content-Type: text/x-patch; charset="US-ASCII"; name="v2-0001-Coalesce-eqsel-eqjoinsel.patch" Content-Disposition: attachment; filename="v2-0001-Coalesce-eqsel-eqjoinsel.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mrext49y0 RnJvbSA1NTNlYjliMzAzNzZhNTllMDZhOTFhNDFhZGE2ZDljNmI3YmQ1YTRkIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBwcmFua3dhcmUgPGVzYXZlbGlldmNvZGVAZ21haWwuY29tPgpE YXRlOiBGcmksIDEwIEp1bCAyMDI2IDEzOjMxOjA3ICswMzAwClN1YmplY3Q6IFtQQVRDSCB2Ml0g Q29hbGVzY2UgZXFzZWwgZXFqb2luc2VsCgotLS0KIHNyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxm dW5jcy5jIHwgNDc0ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0KIDEgZmlsZSBjaGFu Z2VkLCA0NDQgaW5zZXJ0aW9ucygrKSwgMzAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvc3Jj L2JhY2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMgYi9zcmMvYmFja2VuZC91dGlscy9hZHQvc2Vs ZnVuY3MuYwppbmRleCA0ZWU3MGVmMGI3MC4uN2UzMDVkYTM1N2UgMTAwNjQ0Ci0tLSBhL3NyYy9i YWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jCisrKyBiL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9z ZWxmdW5jcy5jCkBAIC0zMDQsNiArMzA0LDI4OCBAQCBlcXNlbChQR19GVU5DVElPTl9BUkdTKQog CVBHX1JFVFVSTl9GTE9BVDgoKGZsb2F0OCkgZXFzZWxfaW50ZXJuYWwoZmNpbmZvLCBmYWxzZSkp OwogfQogCisvKgorICogRXh0cmFjdCB0aGUgZXN0aW1hYmxlIGJyYW5jaGVzIG9mIGEgQ29hbGVz Y2VFeHByLiAgU3RyaXBzIFJlbGFiZWxUeXBlLAorICogc2tpcHMgTlVMTC1jb25zdGFudCBicmFu Y2hlcywgYW5kIHN0b3BzIGF0IHRoZSBmaXJzdCBub24tTlVMTCBDb25zdAorICogKHNldHRpbmcg KnRlcm1pbmF0ZXNfd2l0aF9jb25zdCkuICBSZXR1cm5zIGZhbHNlIGlmIHRoZSBleHByZXNzaW9u CisgKiBpcyBjb25zdGFudCBvciBubyBicmFuY2hlcyByZW1haW4uCisgKi8KK3N0YXRpYyBib29s CittYXRjaF9jb2FsZXNjZV9qb2luX3NpZGUoTm9kZSAqc2lkZSwKKwkJCQkJCSBMaXN0ICoqc3Ry aXBwZWRfYXJncywKKwkJCQkJCSBib29sICp0ZXJtaW5hdGVzX3dpdGhfY29uc3QpCit7CisJQ29h bGVzY2VFeHByICpjOworCUxpc3RDZWxsICAgKmxjOworCUxpc3QJICAgKnJlc3VsdCA9IE5JTDsK KworCSp0ZXJtaW5hdGVzX3dpdGhfY29uc3QgPSBmYWxzZTsKKwkqc3RyaXBwZWRfYXJncyA9IE5J TDsKKworCWlmIChzaWRlID09IE5VTEwgfHwgIUlzQShzaWRlLCBDb2FsZXNjZUV4cHIpKQorCQly ZXR1cm4gZmFsc2U7CisKKwljID0gKENvYWxlc2NlRXhwciAqKSBzaWRlOworCisJaWYgKGxpc3Rf bGVuZ3RoKGMtPmFyZ3MpIDwgMikKKwkJcmV0dXJuIGZhbHNlOworCisJZm9yZWFjaChsYywgYy0+ YXJncykKKwl7CisJCU5vZGUJICAgKmFyZyA9IChOb2RlICopIGxmaXJzdChsYyk7CisKKwkJLyog c3RyaXAgUmVsYWJlbFR5cGUgKi8KKwkJd2hpbGUgKGFyZyAmJiBJc0EoYXJnLCBSZWxhYmVsVHlw ZSkpCisJCQlhcmcgPSAoTm9kZSAqKSAoKFJlbGFiZWxUeXBlICopIGFyZyktPmFyZzsKKworCQkv KiBsZWFkaW5nIENvbnN0IG1ha2VzIENPQUxFU0NFIGl0c2VsZiBjb25zdGFudCAqLworCQlpZiAo YXJnID09IE5VTEwgfHwgKGxjID09IGxpc3RfaGVhZChjLT5hcmdzKSAmJiBJc0EoYXJnLCBDb25z dCkpKQorCQl7CisJCQlsaXN0X2ZyZWUocmVzdWx0KTsKKwkJCXJldHVybiBmYWxzZTsKKwkJfQor CisJCWlmIChJc0EoYXJnLCBDb25zdCkpCisJCXsKKwkJCWlmICgoKENvbnN0ICopIGFyZyktPmNv bnN0dHlwZSAhPSBjLT5jb2FsZXNjZXR5cGUpCisJCQl7CisJCQkJbGlzdF9mcmVlKHJlc3VsdCk7 CisJCQkJcmV0dXJuIGZhbHNlOworCQkJfQorCisJCQkvKiBOVUxMIENvbnN0IGlzIHNraXBwZWQg Ki8KKwkJCWlmICghKChDb25zdCAqKSBhcmcpLT5jb25zdGlzbnVsbCkKKwkJCXsKKwkJCQlyZXN1 bHQgPSBsYXBwZW5kKHJlc3VsdCwgYXJnKTsKKwkJCQkqdGVybWluYXRlc193aXRoX2NvbnN0ID0g dHJ1ZTsKKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCWlmIChleHByVHlw ZShhcmcpICE9IGMtPmNvYWxlc2NldHlwZSkKKwkJCXsKKwkJCQlsaXN0X2ZyZWUocmVzdWx0KTsK KwkJCQlyZXR1cm4gZmFsc2U7CisJCQl9CisJCQlyZXN1bHQgPSBsYXBwZW5kKHJlc3VsdCwgYXJn KTsKKwkJfQorCX0KKworCWlmIChyZXN1bHQgPT0gTklMKQorCQlyZXR1cm4gZmFsc2U7CisKKwkq c3RyaXBwZWRfYXJncyA9IHJlc3VsdDsKKwlyZXR1cm4gdHJ1ZTsKK30KKworLyoKKyAqIEZpbGwg cHJlZml4X3Byb2JzW2ldID0gUHJvZF97ajxpfSBzdGFudWxsZnJhYyhhcmdzW2pdKSBmb3IgYSBz dHJpcHBlZAorICogQ09BTEVTQ0UgYXJnIGxpc3QuICBSZXR1cm5zIGZhbHNlIGlmIGFueSBub24t Q29uc3QgYXJnIGxhY2tzIHN0YXRpc3RpY3MuCisgKi8KK3N0YXRpYyBib29sCitnZXRfY29hbGVz Y2VfcHJlZml4X3Byb2JzKFBsYW5uZXJJbmZvICpyb290LCBMaXN0ICphcmdzLCBkb3VibGUgKnBy ZWZpeF9wcm9icykKK3sKKwlMaXN0Q2VsbCAgICpsYzsKKwlpbnQJCQlpID0gMDsKKwlkb3VibGUJ CXByZWZpeCA9IDEuMDsKKworCWZvcmVhY2gobGMsIGFyZ3MpCisJeworCQlOb2RlCSAgICphcmcg PSAoTm9kZSAqKSBsZmlyc3QobGMpOworCisJCXByZWZpeF9wcm9ic1tpKytdID0gcHJlZml4Owor CisJCS8qIG5vdGhpbmcgdG8gZm9sZCBmb3IgdGhlIGxhc3QgYXJnIG9yIGEgQ29uc3QgKi8KKwkJ aWYgKGxuZXh0KGFyZ3MsIGxjKSA9PSBOVUxMIHx8IElzQShhcmcsIENvbnN0KSkKKwkJCWNvbnRp bnVlOworCisJCXsKKwkJCVZhcmlhYmxlU3RhdERhdGEgdmQ7CisJCQlkb3VibGUJCXBfaTsKKwor CQkJZXhhbWluZV92YXJpYWJsZShyb290LCBhcmcsIDAsICZ2ZCk7CisJCQlpZiAoIUhlYXBUdXBs ZUlzVmFsaWQodmQuc3RhdHNUdXBsZSkpCisJCQl7CisJCQkJUmVsZWFzZVZhcmlhYmxlU3RhdHMo dmQpOworCQkJCXJldHVybiBmYWxzZTsKKwkJCX0KKwkJCXBfaSA9ICgoRm9ybV9wZ19zdGF0aXN0 aWMpIEdFVFNUUlVDVCh2ZC5zdGF0c1R1cGxlKSktPnN0YW51bGxmcmFjOworCQkJUmVsZWFzZVZh cmlhYmxlU3RhdHModmQpOworCisJCQlpZiAocF9pIDwgMC4wIHx8IHBfaSA+IDEuMCkKKwkJCQly ZXR1cm4gZmFsc2U7CisKKwkJCXByZWZpeCAqPSBwX2k7CisJCX0KKwl9CisKKwlyZXR1cm4gdHJ1 ZTsKK30KKworLyoKKyAqIENvbW1vbiBndXRzIG9mIGVxc2VsL2Vxam9pbnNlbCB3aGVuIG9uZSBv ciBib3RoIG9wZXJhbmRzIGFyZSBDb2FsZXNjZUV4cHIuCisgKiBDb21wdXRlczoKKyAqCisgKiAg IHNlbChDT0FMRVNDRShsXzEsLi4uLGxfTSkgPSBDT0FMRVNDRShyXzEsLi4uLHJfTikpID0KKyAq ICAgICAgIFN1bV97aSxqfSAgUF9MKHJlYWNoIGkpICogUF9SKHJlYWNoIGopICogc2VsKGxfaSA9 IHJfaikKKyAqCisgKiB3aGVyZSBQKHJlYWNoIGkpID0gUHJvZF97ajxpfSBzdGFudWxsZnJhYyhh cmdfaikuICBBIG5vbi1DT0FMRVNDRSBvcGVyYW5kCisgKiBpcyB0cmVhdGVkIGFzIGEgc2luZ2xl LWVsZW1lbnQgbGlzdC4KKyAqLworc3RhdGljIGJvb2wKK3RyeV9jb2FsZXNjZV9lcShQR19GVU5D VElPTl9BUkdTLCBkb3VibGUgKnNlbGVjX291dCkKK3sKKwlQbGFubmVySW5mbyAqcm9vdCA9IChQ bGFubmVySW5mbyAqKSBQR19HRVRBUkdfUE9JTlRFUigwKTsKKwlPaWQJCQlvcGVyYXRvciA9IFBH X0dFVEFSR19PSUQoMSk7CisJTGlzdAkgICAqYXJncyA9IChMaXN0ICopIFBHX0dFVEFSR19QT0lO VEVSKDIpOworCWJvb2wJCWlzX2Vxam9pbiA9IChmY2luZm8tPmZsaW5mbyAhPSBOVUxMICYmCisJ CQkJCQkJIGZjaW5mby0+ZmxpbmZvLT5mbl9vaWQgPT0gRl9FUUpPSU5TRUwpOworCVNwZWNpYWxK b2luSW5mbyAqc2ppbmZvID0gaXNfZXFqb2luID8KKwkJKFNwZWNpYWxKb2luSW5mbyAqKSBQR19H RVRBUkdfUE9JTlRFUig0KSA6IE5VTEw7CisJaW50CQkJZXFzZWxfdmFyUmVsaWQgPSBpc19lcWpv aW4gPyAwIDogUEdfR0VUQVJHX0lOVDMyKDMpOworCU9pZAkJCWNvbGxhdGlvbiA9IFBHX0dFVF9D T0xMQVRJT04oKTsKKwlOb2RlCSAgICpsZWZ0OworCU5vZGUJICAgKnJpZ2h0OworCUxpc3QJICAg KmxlZnRfYXJncyA9IE5JTDsKKwlMaXN0CSAgICpyaWdodF9hcmdzID0gTklMOworCWJvb2wJCWxl ZnRfaXNfY29hbGVzY2U7CisJYm9vbAkJcmlnaHRfaXNfY29hbGVzY2U7CisJYm9vbAkJbGVmdF90 ZXJtX2NvbnN0ID0gZmFsc2U7CisJYm9vbAkJcmlnaHRfdGVybV9jb25zdCA9IGZhbHNlOworCWRv dWJsZQkgICAqbGVmdF9wcmVmaXg7CisJZG91YmxlCSAgICpyaWdodF9wcmVmaXg7CisJZG91Ymxl CQlhY2Nfc2VsZWMgPSAwLjA7CisJTGlzdENlbGwgICAqbGxjOworCWludAkJCWxpOworCisJaWYg KGxpc3RfbGVuZ3RoKGFyZ3MpICE9IDIpCisJCXJldHVybiBmYWxzZTsKKworCWxlZnQgPSAoTm9k ZSAqKSBsaW5pdGlhbChhcmdzKTsKKwlyaWdodCA9IChOb2RlICopIGxzZWNvbmQoYXJncyk7CisK KwlsZWZ0X2lzX2NvYWxlc2NlID0gbWF0Y2hfY29hbGVzY2Vfam9pbl9zaWRlKGxlZnQsICZsZWZ0 X2FyZ3MsCisJCQkJCQkJCQkJCQkmbGVmdF90ZXJtX2NvbnN0KTsKKwlyaWdodF9pc19jb2FsZXNj ZSA9IG1hdGNoX2NvYWxlc2NlX2pvaW5fc2lkZShyaWdodCwgJnJpZ2h0X2FyZ3MsCisJCQkJCQkJ CQkJCQkgJnJpZ2h0X3Rlcm1fY29uc3QpOworCisJaWYgKCFsZWZ0X2lzX2NvYWxlc2NlICYmICFy aWdodF9pc19jb2FsZXNjZSkKKwkJcmV0dXJuIGZhbHNlOworCisJLyogb25lIHNpZGUgaXMgYSBD b2FsZXNjZUV4cHIgdGhhdCBtYXRjaF9jb2FsZXNjZV9qb2luX3NpZGUgcmVqZWN0ZWQgKi8KKwlp ZiAoKGxlZnRfaXNfY29hbGVzY2UgJiYgIXJpZ2h0X2lzX2NvYWxlc2NlICYmIElzQShyaWdodCwg Q29hbGVzY2VFeHByKSkgfHwKKwkJKHJpZ2h0X2lzX2NvYWxlc2NlICYmICFsZWZ0X2lzX2NvYWxl c2NlICYmIElzQShsZWZ0LCBDb2FsZXNjZUV4cHIpKSkKKwl7CisJCWxpc3RfZnJlZShsZWZ0X2Fy Z3MpOworCQlsaXN0X2ZyZWUocmlnaHRfYXJncyk7CisJCXJldHVybiBmYWxzZTsKKwl9CisKKwlp ZiAoIWxlZnRfaXNfY29hbGVzY2UpCisJeworCQlsZWZ0X2FyZ3MgPSBsaXN0X21ha2UxKGxlZnQp OworCQlsZWZ0X3Rlcm1fY29uc3QgPSBJc0EobGVmdCwgQ29uc3QpOworCX0KKwlpZiAoIXJpZ2h0 X2lzX2NvYWxlc2NlKQorCXsKKwkJcmlnaHRfYXJncyA9IGxpc3RfbWFrZTEocmlnaHQpOworCQly aWdodF90ZXJtX2NvbnN0ID0gSXNBKHJpZ2h0LCBDb25zdCk7CisJfQorCisJbGVmdF9wcmVmaXgg PSAoZG91YmxlICopIHBhbGxvYyhzaXplb2YoZG91YmxlKSAqIGxpc3RfbGVuZ3RoKGxlZnRfYXJn cykpOworCXJpZ2h0X3ByZWZpeCA9IChkb3VibGUgKikgcGFsbG9jKHNpemVvZihkb3VibGUpICog bGlzdF9sZW5ndGgocmlnaHRfYXJncykpOworCisJaWYgKCFnZXRfY29hbGVzY2VfcHJlZml4X3By b2JzKHJvb3QsIGxlZnRfYXJncywgbGVmdF9wcmVmaXgpIHx8CisJCSFnZXRfY29hbGVzY2VfcHJl Zml4X3Byb2JzKHJvb3QsIHJpZ2h0X2FyZ3MsIHJpZ2h0X3ByZWZpeCkpCisJeworCQlwZnJlZShs ZWZ0X3ByZWZpeCk7CisJCXBmcmVlKHJpZ2h0X3ByZWZpeCk7CisJCWxpc3RfZnJlZShsZWZ0X2Fy Z3MpOworCQlsaXN0X2ZyZWUocmlnaHRfYXJncyk7CisJCXJldHVybiBmYWxzZTsKKwl9CisKKwls aSA9IDA7CisJZm9yZWFjaChsbGMsIGxlZnRfYXJncykKKwl7CisJCU5vZGUJICAgKmxhcmcgPSAo Tm9kZSAqKSBsZmlyc3QobGxjKTsKKwkJYm9vbAkJbGNvbnN0ID0gSXNBKGxhcmcsIENvbnN0KTsK KwkJTGlzdENlbGwgICAqcmxjOworCQlpbnQJCQlyaSA9IDA7CisKKwkJaWYgKGxlZnRfcHJlZml4 W2xpXSA8IDEuMGUtMTIpCisJCQlicmVhazsKKworCQlmb3JlYWNoKHJsYywgcmlnaHRfYXJncykK KwkJeworCQkJTm9kZQkgICAqcmFyZyA9IChOb2RlICopIGxmaXJzdChybGMpOworCQkJYm9vbAkJ cmNvbnN0ID0gSXNBKHJhcmcsIENvbnN0KTsKKwkJCVNlbGVjdGl2aXR5IGNvbnRyaWI7CisKKwkJ CWlmIChyaWdodF9wcmVmaXhbcmldIDwgMS4wZS0xMikKKwkJCQlicmVhazsKKworCQkJaWYgKGxj b25zdCAmJiByY29uc3QpCisJCQl7CisJCQkJQ29uc3QJICAgKmxjID0gKENvbnN0ICopIGxhcmc7 CisJCQkJQ29uc3QJICAgKnJjID0gKENvbnN0ICopIHJhcmc7CisKKwkJCQlpZiAobGMtPmNvbnN0 aXNudWxsIHx8IHJjLT5jb25zdGlzbnVsbCkKKwkJCQkJY29udHJpYiA9IDAuMDsKKwkJCQllbHNl CisJCQkJCWNvbnRyaWIgPSBEYXR1bUdldEJvb2woT2lkRnVuY3Rpb25DYWxsMkNvbGwoZ2V0X29w Y29kZShvcGVyYXRvciksCisJCQkJCQkJCQkJCQkJCQkJY29sbGF0aW9uLAorCQkJCQkJCQkJCQkJ CQkJCWxjLT5jb25zdHZhbHVlLAorCQkJCQkJCQkJCQkJCQkJCXJjLT5jb25zdHZhbHVlKSkgPyAx LjAgOiAwLjA7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJTGlzdAkgICAqc3ViX2FyZ3MgPSBs aXN0X21ha2UyKGNvcHlPYmplY3QobGFyZyksCisJCQkJCQkJCQkJCQkgIGNvcHlPYmplY3QocmFy ZykpOworCisJCQkJaWYgKCFpc19lcWpvaW4gfHwgbGNvbnN0IHx8IHJjb25zdCkKKwkJCQl7CisJ CQkJCWNvbnRyaWIgPSBEYXR1bUdldEZsb2F0OChEaXJlY3RGdW5jdGlvbkNhbGw0Q29sbChlcXNl bCwKKwkJCQkJCQkJCQkJCQkJCQkJIGNvbGxhdGlvbiwKKwkJCQkJCQkJCQkJCQkJCQkJIFBvaW50 ZXJHZXREYXR1bShyb290KSwKKwkJCQkJCQkJCQkJCQkJCQkJIE9iamVjdElkR2V0RGF0dW0ob3Bl cmF0b3IpLAorCQkJCQkJCQkJCQkJCQkJCQkgUG9pbnRlckdldERhdHVtKHN1Yl9hcmdzKSwKKwkJ CQkJCQkJCQkJCQkJCQkJIEludDMyR2V0RGF0dW0oZXFzZWxfdmFyUmVsaWQpKSk7CisJCQkJfQor CQkJCWVsc2UKKwkJCQl7CisJCQkJCWNvbnRyaWIgPSBEYXR1bUdldEZsb2F0OChEaXJlY3RGdW5j dGlvbkNhbGw1Q29sbChlcWpvaW5zZWwsCisJCQkJCQkJCQkJCQkJCQkJCSBjb2xsYXRpb24sCisJ CQkJCQkJCQkJCQkJCQkJCSBQb2ludGVyR2V0RGF0dW0ocm9vdCksCisJCQkJCQkJCQkJCQkJCQkJ CSBPYmplY3RJZEdldERhdHVtKG9wZXJhdG9yKSwKKwkJCQkJCQkJCQkJCQkJCQkJIFBvaW50ZXJH ZXREYXR1bShzdWJfYXJncyksCisJCQkJCQkJCQkJCQkJCQkJCSBJbnQxNkdldERhdHVtKEpPSU5f SU5ORVIpLAorCQkJCQkJCQkJCQkJCQkJCQkgUG9pbnRlckdldERhdHVtKHNqaW5mbykpKTsKKwkJ CQl9CisKKwkJCQlsaXN0X2ZyZWUoc3ViX2FyZ3MpOworCQkJfQorCisJCQlDTEFNUF9QUk9CQUJJ TElUWShjb250cmliKTsKKwkJCWFjY19zZWxlYyArPSBsZWZ0X3ByZWZpeFtsaV0gKiByaWdodF9w cmVmaXhbcmldICogY29udHJpYjsKKworCQkJcmkrKzsKKwkJfQorCisJCWxpKys7CisJfQorCisJ cGZyZWUobGVmdF9wcmVmaXgpOworCXBmcmVlKHJpZ2h0X3ByZWZpeCk7CisJbGlzdF9mcmVlKGxl ZnRfYXJncyk7CisJbGlzdF9mcmVlKHJpZ2h0X2FyZ3MpOworCisJQ0xBTVBfUFJPQkFCSUxJVFko YWNjX3NlbGVjKTsKKwkqc2VsZWNfb3V0ID0gYWNjX3NlbGVjOworCXJldHVybiB0cnVlOworfQor CiAvKgogICogQ29tbW9uIGNvZGUgZm9yIGVxc2VsKCkgYW5kIG5lcXNlbCgpCiAgKi8KQEAgLTMy MCw2ICs2MDIsOSBAQCBlcXNlbF9pbnRlcm5hbChQR19GVU5DVElPTl9BUkdTLCBib29sIG5lZ2F0 ZSkKIAlib29sCQl2YXJvbmxlZnQ7CiAJZG91YmxlCQlzZWxlYzsKIAorCWlmICh0cnlfY29hbGVz Y2VfZXEoZmNpbmZvLCAmc2VsZWMpKQorCQlyZXR1cm4gc2VsZWM7CisKIAkvKgogCSAqIFdoZW4g YXNrZWQgYWJvdXQgPD4sIHdlIGRvIHRoZSBlc3RpbWF0aW9uIHVzaW5nIHRoZSBjb3JyZXNwb25k aW5nID0KIAkgKiBvcGVyYXRvciwgdGhlbiBjb252ZXJ0IHRvIDw+IHZpYSAiMS4wIC0gZXFfc2Vs ZWN0aXZpdHkgLSBudWxsZnJhYyIuCkBAIC0yNDIwLDYgKzI3MDUsOSBAQCBlcWpvaW5zZWwoUEdf RlVOQ1RJT05fQVJHUykKIAlib29sCQlqb2luX2lzX3JldmVyc2VkOwogCVJlbE9wdEluZm8gKmlu bmVyX3JlbDsKIAorCWlmICh0cnlfY29hbGVzY2VfZXEoZmNpbmZvLCAmc2VsZWMpKQorCQlQR19S RVRVUk5fRkxPQVQ4KChmbG9hdDgpIHNlbGVjKTsKKwogCWdldF9qb2luX3ZhcmlhYmxlcyhyb290 LCBhcmdzLCBzamluZm8sCiAJCQkJCSAgICZ2YXJkYXRhMSwgJnZhcmRhdGEyLCAmam9pbl9pc19y ZXZlcnNlZCk7CiAKQEAgLTQzNzYsNiArNDY2NCwxNTQgQEAgZXN0aW1hdGVfbXVsdGl2YXJpYXRl X2J1Y2tldHNpemUoUGxhbm5lckluZm8gKnJvb3QsIFJlbE9wdEluZm8gKmlubmVyLAogCXJldHVy biBvdGhlcmNsYXVzZXM7CiB9CiAKKy8qCisgKiBNb3N0LWNvbW1vbi12YWx1ZSBmcmVxdWVuY3kg Zm9yIHZhcmRhdGEuICBGYWxscyBiYWNrIHRvIDEvbnR1cGxlcyB3aGVuCisgKiBvbmx5IGEgaGlz dG9ncmFtIHNsb3QgaXMgcHJlc2VudC4gIFJldHVybnMgMC4wIGlmIG5vIHN0YXRpc3RpY3MgYXJl CisgKiBhdmFpbGFibGUuCisgKi8KK3N0YXRpYyB2b2lkCitnZXRfdmFyaWFibGVfbWN2X2ZyZXEo VmFyaWFibGVTdGF0RGF0YSAqdmFyZGF0YSwgU2VsZWN0aXZpdHkgKm1jdl9mcmVxKQoreworCUF0 dFN0YXRzU2xvdCBzc2xvdDsKKworCSptY3ZfZnJlcSA9IDAuMDsKKworCWlmICghSGVhcFR1cGxl SXNWYWxpZCh2YXJkYXRhLT5zdGF0c1R1cGxlKSkKKwkJcmV0dXJuOworCisJaWYgKGdldF9hdHRz dGF0c3Nsb3QoJnNzbG90LCB2YXJkYXRhLT5zdGF0c1R1cGxlLAorCQkJCQkJIFNUQVRJU1RJQ19L SU5EX01DViwgSW52YWxpZE9pZCwKKwkJCQkJCSBBVFRTVEFUU1NMT1RfTlVNQkVSUykpCisJewor CQlpZiAoc3Nsb3Qubm51bWJlcnMgPiAwKQorCQkJKm1jdl9mcmVxID0gc3Nsb3QubnVtYmVyc1sw XTsKKwkJZnJlZV9hdHRzdGF0c3Nsb3QoJnNzbG90KTsKKwl9CisJZWxzZSBpZiAoZ2V0X2F0dHN0 YXRzc2xvdCgmc3Nsb3QsIHZhcmRhdGEtPnN0YXRzVHVwbGUsCisJCQkJCQkJICBTVEFUSVNUSUNf S0lORF9ISVNUT0dSQU0sIEludmFsaWRPaWQsCisJCQkJCQkJICAwKSkKKwl7CisJCS8qIG5vIE1D VnMgYnV0IGhpc3RvZ3JhbSBwcmVzZW50OiBjb2x1bW4gaXMgbGlrZWx5IHVuaXF1ZSAqLworCQlp ZiAodmFyZGF0YS0+cmVsICYmIHZhcmRhdGEtPnJlbC0+dHVwbGVzID4gMCkKKwkJCSptY3ZfZnJl cSA9IDEuMCAvIHZhcmRhdGEtPnJlbC0+dHVwbGVzOworCX0KK30KKworLyoKKyAqIEVzdGltYXRl IGJ1Y2tldCBzdGF0cyBmb3IgYSBDb2FsZXNjZUV4cHIgaGFzaGtleSB3aGVuIGV4YW1pbmVfdmFy aWFibGUoKQorICogcmV0dXJuZWQgYSBkZWZhdWx0IG5kaXN0aW5jdC4gIFVzZXMgcGVyLWJyYW5j aCBuZGlzdGluY3QgYW5kIG1jdl9mcmVxLAorICogd2VpZ2h0ZWQgYnkgbnVsbCBmYWxsLXRocm91 Z2ggcHJvYmFiaWxpdHkuCisgKi8KK3N0YXRpYyBib29sCitoYXNoX2J1Y2tldF9zdGF0c19jb2Fs ZXNjZV9kaXNwYXRjaChQbGFubmVySW5mbyAqcm9vdCwKKwkJCQkJCQkJCU5vZGUgKmhhc2hrZXks CisJCQkJCQkJCQlkb3VibGUgbmJ1Y2tldHMsCisJCQkJCQkJCQlTZWxlY3Rpdml0eSAqbWN2X2Zy ZXEsCisJCQkJCQkJCQlTZWxlY3Rpdml0eSAqYnVja2V0c2l6ZV9mcmFjKQoreworCUxpc3QJICAg KnN0cmlwcGVkX2FyZ3M7CisJYm9vbAkJdGVybWluYXRlc193aXRoX2NvbnN0OworCWRvdWJsZQkg ICAqcHJlZml4OworCWludAkJCW5hcmdzOworCWludAkJCWk7CisJTGlzdENlbGwgICAqbGM7CisJ ZG91YmxlCQluZF9taXggPSAwLjA7CisJU2VsZWN0aXZpdHkgbWN2X21peCA9IDAuMDsKKwlkb3Vi bGUJCXJlbF9yb3dzX3Byb3h5ID0gMC4wOworCWRvdWJsZQkJcmVsX3R1cGxlc19wcm94eSA9IDAu MDsKKwlkb3VibGUJCWVzdGZyYWN0OworCisJaWYgKCFtYXRjaF9jb2FsZXNjZV9qb2luX3NpZGUo aGFzaGtleSwgJnN0cmlwcGVkX2FyZ3MsICZ0ZXJtaW5hdGVzX3dpdGhfY29uc3QpKQorCQlyZXR1 cm4gZmFsc2U7CisKKwluYXJncyA9IGxpc3RfbGVuZ3RoKHN0cmlwcGVkX2FyZ3MpOworCXByZWZp eCA9IChkb3VibGUgKikgcGFsbG9jKHNpemVvZihkb3VibGUpICogbmFyZ3MpOworCisJaWYgKCFn ZXRfY29hbGVzY2VfcHJlZml4X3Byb2JzKHJvb3QsIHN0cmlwcGVkX2FyZ3MsIHByZWZpeCkpCisJ eworCQlwZnJlZShwcmVmaXgpOworCQlsaXN0X2ZyZWUoc3RyaXBwZWRfYXJncyk7CisJCXJldHVy biBmYWxzZTsKKwl9CisKKwlpID0gMDsKKwlmb3JlYWNoKGxjLCBzdHJpcHBlZF9hcmdzKQorCXsK KwkJTm9kZQkgICAqYXJnID0gKE5vZGUgKikgbGZpcnN0KGxjKTsKKworCQlpZiAoSXNBKGFyZywg Q29uc3QpKQorCQl7CisJCQltY3ZfbWl4ID0gTWF4KG1jdl9taXgsIHByZWZpeFtpXSk7CisJCQlp ZiAocHJlZml4W2ldID4gMC4wKQorCQkJCW5kX21peCArPSAxLjA7CisJCX0KKwkJZWxzZQorCQl7 CisJCQlWYXJpYWJsZVN0YXREYXRhIHZkOworCQkJZG91YmxlCQluZF9pOworCQkJYm9vbAkJaXNk ZWZhdWx0OworCQkJU2VsZWN0aXZpdHkgbWN2X2k7CisKKwkJCWV4YW1pbmVfdmFyaWFibGUocm9v dCwgYXJnLCAwLCAmdmQpOworCQkJbmRfaSA9IGdldF92YXJpYWJsZV9udW1kaXN0aW5jdCgmdmQs ICZpc2RlZmF1bHQpOworCisJCQlpZiAoaXNkZWZhdWx0KQorCQkJeworCQkJCVJlbGVhc2VWYXJp YWJsZVN0YXRzKHZkKTsKKwkJCQlwZnJlZShwcmVmaXgpOworCQkJCWxpc3RfZnJlZShzdHJpcHBl ZF9hcmdzKTsKKwkJCQlyZXR1cm4gZmFsc2U7CisJCQl9CisKKwkJCWdldF92YXJpYWJsZV9tY3Zf ZnJlcSgmdmQsICZtY3ZfaSk7CisKKwkJCW5kX21peCA9IE1heChuZF9taXgsIG5kX2kpOworCQkJ bWN2X21peCA9IE1heChtY3ZfbWl4LCBwcmVmaXhbaV0gKiBtY3ZfaSk7CisKKwkJCWlmIChpID09 IDAgJiYgdmQucmVsICYmIHZkLnJlbC0+dHVwbGVzID4gMCkKKwkJCXsKKwkJCQlyZWxfcm93c19w cm94eSA9IHZkLnJlbC0+cm93czsKKwkJCQlyZWxfdHVwbGVzX3Byb3h5ID0gdmQucmVsLT50dXBs ZXM7CisJCQl9CisKKwkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZkKTsKKwkJfQorCisJCWkrKzsK Kwl9CisKKwlwZnJlZShwcmVmaXgpOworCWxpc3RfZnJlZShzdHJpcHBlZF9hcmdzKTsKKworCWlm IChyZWxfdHVwbGVzX3Byb3h5ID4gMC4wKQorCXsKKwkJbmRfbWl4ICo9IHJlbF9yb3dzX3Byb3h5 IC8gcmVsX3R1cGxlc19wcm94eTsKKwkJbmRfbWl4ID0gY2xhbXBfcm93X2VzdChuZF9taXgpOwor CX0KKworCWlmIChuZF9taXggPD0gMC4wKQorCQlyZXR1cm4gZmFsc2U7CisKKwlpZiAobmRfbWl4 ID4gbmJ1Y2tldHMpCisJCWVzdGZyYWN0ID0gMS4wIC8gbmJ1Y2tldHM7CisJZWxzZQorCQllc3Rm cmFjdCA9IDEuMCAvIG5kX21peDsKKworCUNMQU1QX1BST0JBQklMSVRZKG1jdl9taXgpOworCSpt Y3ZfZnJlcSA9IE1heCgqbWN2X2ZyZXEsIG1jdl9taXgpOworCUNMQU1QX1BST0JBQklMSVRZKCpt Y3ZfZnJlcSk7CisJZXN0ZnJhY3QgPSBNYXgoZXN0ZnJhY3QsICptY3ZfZnJlcSk7CisKKwlpZiAo ZXN0ZnJhY3QgPCAxLjBlLTYpCisJCWVzdGZyYWN0ID0gMS4wZS02OworCWVsc2UgaWYgKGVzdGZy YWN0ID4gMS4wKQorCQllc3RmcmFjdCA9IDEuMDsKKworCSpidWNrZXRzaXplX2ZyYWMgPSAoU2Vs ZWN0aXZpdHkpIGVzdGZyYWN0OworCisJcmV0dXJuIHRydWU7Cit9CisKIC8qCiAgKiBFc3RpbWF0 ZSBoYXNoIGJ1Y2tldCBzdGF0aXN0aWNzIHdoZW4gdGhlIHNwZWNpZmllZCBleHByZXNzaW9uIGlz IHVzZWQKICAqIGFzIGEgaGFzaCBrZXkgZm9yIHRoZSBnaXZlbiBudW1iZXIgb2YgYnVja2V0cy4K QEAgLTQ0MjksNDMgKzQ4NjUsMjEgQEAgZXN0aW1hdGVfaGFzaF9idWNrZXRfc3RhdHMoUGxhbm5l ckluZm8gKnJvb3QsIE5vZGUgKmhhc2hrZXksIGRvdWJsZSBuYnVja2V0cywKIAlkb3VibGUJCWVz dGZyYWN0LAogCQkJCW5kaXN0aW5jdDsKIAlib29sCQlpc2RlZmF1bHQ7Ci0JQXR0U3RhdHNTbG90 IHNzbG90OwogCiAJZXhhbWluZV92YXJpYWJsZShyb290LCBoYXNoa2V5LCAwLCAmdmFyZGF0YSk7 CiAKLQkvKiBJbml0aWFsaXplICptY3ZfZnJlcSB0byAidW5rbm93biIgKi8KLQkqbWN2X2ZyZXEg PSAwLjA7Ci0KLQkvKiBMb29rIHVwIHRoZSBmcmVxdWVuY3kgb2YgdGhlIG1vc3QgY29tbW9uIHZh bHVlLCBpZiBhdmFpbGFibGUgKi8KLQlpZiAoSGVhcFR1cGxlSXNWYWxpZCh2YXJkYXRhLnN0YXRz VHVwbGUpKQotCXsKLQkJaWYgKGdldF9hdHRzdGF0c3Nsb3QoJnNzbG90LCB2YXJkYXRhLnN0YXRz VHVwbGUsCi0JCQkJCQkJIFNUQVRJU1RJQ19LSU5EX01DViwgSW52YWxpZE9pZCwKLQkJCQkJCQkg QVRUU1RBVFNTTE9UX05VTUJFUlMpKQotCQl7Ci0JCQkvKgotCQkJICogVGhlIGZpcnN0IE1DViBz dGF0IGlzIGZvciB0aGUgbW9zdCBjb21tb24gdmFsdWUuCi0JCQkgKi8KLQkJCWlmIChzc2xvdC5u bnVtYmVycyA+IDApCi0JCQkJKm1jdl9mcmVxID0gc3Nsb3QubnVtYmVyc1swXTsKLQkJCWZyZWVf YXR0c3RhdHNzbG90KCZzc2xvdCk7Ci0JCX0KLQkJZWxzZSBpZiAoZ2V0X2F0dHN0YXRzc2xvdCgm c3Nsb3QsIHZhcmRhdGEuc3RhdHNUdXBsZSwKLQkJCQkJCQkJICBTVEFUSVNUSUNfS0lORF9ISVNU T0dSQU0sIEludmFsaWRPaWQsCi0JCQkJCQkJCSAgMCkpCi0JCXsKLQkJCS8qCi0JCQkgKiBJZiB0 aGVyZSBhcmUgbm8gcmVjb3JkZWQgTUNWcywgYnV0IHdlIGRvIGhhdmUgYSBoaXN0b2dyYW0sIHRo ZW4KLQkJCSAqIGFzc3VtZSB0aGF0IEFOQUxZWkUgZGV0ZXJtaW5lZCB0aGF0IHRoZSBjb2x1bW4g aXMgdW5pcXVlLgotCQkJICovCi0JCQlpZiAodmFyZGF0YS5yZWwgJiYgdmFyZGF0YS5yZWwtPnR1 cGxlcyA+IDApCi0JCQkJKm1jdl9mcmVxID0gMS4wIC8gdmFyZGF0YS5yZWwtPnR1cGxlczsKLQkJ fQotCX0KKwlnZXRfdmFyaWFibGVfbWN2X2ZyZXEoJnZhcmRhdGEsIG1jdl9mcmVxKTsKIAogCS8q IEdldCBudW1iZXIgb2YgZGlzdGluY3QgdmFsdWVzICovCiAJbmRpc3RpbmN0ID0gZ2V0X3Zhcmlh YmxlX251bWRpc3RpbmN0KCZ2YXJkYXRhLCAmaXNkZWZhdWx0KTsKIAorCWlmIChpc2RlZmF1bHQg JiYgaGFzaF9idWNrZXRfc3RhdHNfY29hbGVzY2VfZGlzcGF0Y2gocm9vdCwgaGFzaGtleSwgbmJ1 Y2tldHMsCisJCQkJCQkJCQkJCQkJCSBtY3ZfZnJlcSwgYnVja2V0c2l6ZV9mcmFjKSkKKwl7CisJ CVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRhdGEpOworCQlyZXR1cm47CisJfQorCiAJLyoKIAkg KiBJZiBuZGlzdGluY3QgaXNuJ3QgcmVhbCwgcHVudC4gIFdlIG5vcm1hbGx5IHJldHVybiAwLjEs IGJ1dCBpZiB0aGUKIAkgKiBtY3ZfZnJlcSBpcyBrbm93biB0byBiZSBldmVuIGhpZ2hlciB0aGFu IHRoYXQsIHVzZSBpdCBpbnN0ZWFkLgoKYmFzZS1jb21taXQ6IGRmY2UxOWMyMzAwYWIwMGE4YzQx Mzg2ZTQ5ZGZkZDZhM2M4ZWRhZTkKLS0gCjIuNDMuMAoK --0000000000007148d20656413e42--