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 1wCOZT-001wEn-0B for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 21:11:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wCOZR-008nAg-11 for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 21:11:50 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCOZQ-008nAX-2U for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 21:11:49 +0000 Received: from mail-oo1-xc29.google.com ([2607:f8b0:4864:20::c29]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wCOZO-00000000rlm-2MIk for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 21:11:48 +0000 Received: by mail-oo1-xc29.google.com with SMTP id 006d021491bc7-6841e6a5e51so2643566eaf.3 for ; Mon, 13 Apr 2026 14:11:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776114706; cv=none; d=google.com; s=arc-20240605; b=aCeTir6mDS07WA5Av6REwKrJwTm+Btsa6widMRJ8ZtmSGk/FFn+4oW6y4+1VuGbRut dSPyrQ+klmY1vuOL/B7KbwlVCZHixajjwKvI0szja3qp8pFLUjnOvVdyC1pMeJzvpxT5 iB4p8tad77hhVUg/U3ujAvBi+dbDJ7suSVMoyn5y8HCdkFy1LB8BfoxGC1DiBHtDEpln TpfltS4u4nE/RAxqxyBcaUMakT/WSDHYLBns53RVsk29PumhLeyzLpAeRJkwgLVykxlA AC9xC2eNxTOye5SUmqpo4B0i2kzljhyBabWvqP8OYNpgxOGhbvt8GWZQUYQiGLY+R4pv 72Rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=NXAwHrhIiLvaj8Vj8KcCjpUXjERtieMnDMlIlB5bSTQ=; fh=nwNxTtLLPTU0ewfLM7SSbrjMajMl+wwnFkCY/fi90vE=; b=BbMkgnWr9OoBV5g4cs6vwj/PcfRG0A+C9SLeC/0fRfvWswBSd5TF9LDPZWZtbnRgJn gTIdUteLzd+MIluGMOYZGaZ+b66l0sVmLEtrd5Cb3zQcMeFRaBAuEUh2xw6fuM2Uha0K LmsM+E8kru9OoPmwhJt/SNmcQAo1g691XYda09umhM+UcdxpOnIjECoFQ46B0UYEx5XM ZoAY3pQwhoIRMK5zzg04Hcs0T1mqUowEMk2PNGpllZ1e7bWd1Pz+RwLMkV8VfJqNGYNr mCP7dTp9t1xQVZjvIB3eAk9H+ZieiRj5sd2+ur0WgV6nyh/Y+z/zwZN9eSqnH7IvQXQ9 ixLg==; 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=1776114706; x=1776719506; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=NXAwHrhIiLvaj8Vj8KcCjpUXjERtieMnDMlIlB5bSTQ=; b=dur5KJAAMeVYeXzbx7CzFHbKDfgjssZlYaVGS+R6WUSHI2ifQ8UGamXJ+0ys5BJrZO aKgkGGrOJfHO6Er+w0O6H36cTPXNUUVPUuWYP6G/Ua7EsG4oflm/QcGsssiIC5mkfZ3+ AL4vDCspSyxRCdjedVhunshFzy7ga0LONt10oYAIL0ijg4LdlSR3vH45JzlRh8kh2Qk/ 4B0Ennf1j51pnE7lElg8al9IqkcGKX+yuJawkY5v1MCdbb1fZyzHUfYhVfTSCmanNz57 d7YMNaYOKAgVrPGcRtrJCzJloMOpFwAmZDx5laaUL7wBOl9YfQS1XXk6K9CV+f8AR5zo Ds3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776114706; x=1776719506; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NXAwHrhIiLvaj8Vj8KcCjpUXjERtieMnDMlIlB5bSTQ=; b=NsK7gXRmxBE9orCrLbwWQ0Wv7fwxJAI579ljX+XPAGftCeMz22ZS97AzympNKe8/Xm ruxfa+vOZOIoP0B0M+zZzBB6WV52dgoSG1QTazqaSyUKH6VbFzKpqfz8NfQhNxxgE4ia QiPLFF3AnMD8Q1q78qKy4bVpDKMGzQDE5a2r9gQpNd+E7dezlszLxZ0TZLmFgR8Zj+4M WgrACowP8eOmw15lvybkIBEpNRBXEyW35BdzyfQ8zIEatHgtcWV0A0GSgn6L4QCuAJBJ R/lCWZS0bZ97kAnZKdyzWYucm46IiVl+URVZK0v9/V18sUy95VpqqSy8yzliAb4E1P7/ F8xw== X-Gm-Message-State: AOJu0YxfPVyacK8Byx5M1MlI6SDdpnuCMQh6ny7SVnbUYSt7gdj76UNZ KqMlk9VnFLn/S1s/V6NTBlrefznT8C3wHzJ7lstS3OG511uKR0v6BM7SkQb3/+D2ytBSzZK30Q9 l/DIZLH6/H/NFJK55y1ypH72FRgHuYLcTwS9a X-Gm-Gg: AeBDiesCUVaX0v8UUMOq8EFxXNjAtJUdJTrBfKZJgYQXZ5bcTi0fEgmNGpOeklK293h kfyXsFSYNH6uaYUs3BPmA4b/008FhNdgedb7zPZQoGhWQWPa2/guAwMdn/IfQ6X9takZdzxQOos gDV0eqb0zZNZrwFLr2XV6S7coNi3KsQx1OhnzSSJGpsVoEuqsGB1yqbBGfgXcAxpsMLh+Bq8NlY 1SE9gW/9tge9rcVhGKjVL87sKf7bjkDU6NjGedlg7+xTsTHgltAQ/Oy77Nv83jv+AYZg0Bw9ETP fHeMPg== X-Received: by 2002:a05:6820:221a:b0:68d:b45:4315 with SMTP id 006d021491bc7-68d0b454569mr6019230eaf.23.1776114706049; Mon, 13 Apr 2026 14:11:46 -0700 (PDT) MIME-Version: 1.0 From: John Mikk Date: Tue, 14 Apr 2026 00:11:34 +0300 X-Gm-Features: AQROBzA73tYC-OQ1HeuwwIDXwlS7CnW-vY9dNl6KakDsbb52dXSJgbqNs22aN_k Message-ID: Subject: POC: Comparison of partitioning key values To: pgsql-hackers@lists.postgresql.org Content-Type: multipart/mixed; boundary="000000000000228c27064f5dee97" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000228c27064f5dee97 Content-Type: multipart/alternative; boundary="000000000000228c26064f5dee95" --000000000000228c26064f5dee95 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hackers, Hi! When executing the SQL script, we discovered strange behavior =E2=80=94 one= of the partitions cannot be created. ```sql drop table if exists grid2 cascade; create table grid2(x bigint, y bigint) partition by range (x,y); create table g2_part1 partition of grid2 for values from (1,3) to (7,11); create table g2_part2 partition of grid2 for values from (7,11) to (13,15); create table g2_part3 partition of grid2 for values from (13,15) to (15,17)= ; create table g2_part4 partition of grid2 for values from (15,17) to (19,21)= ; -- create table g2_part5 partition of grid2 for values from (5,15) to (13,17); -- [42P17] ERROR: partition "g2_part5" would overlap partition "g2_part1" ``` Why is that? According to the documentation, the row comparison rule for tables applies (subsection 9.25.5). However, in the case of row comparison, it is possible to override comparison operators, which is not the case when defining partitions. There is no way to override the comparison operator for partition ranges. And is this general approach always correct in the case of partitioning? For example, the following approach seems quite valid: If we look at the relative positions of the ranges for each partitioning key (of a single table) on a plane, assuming that the from and to values of the partitioning key in for values are points on the main diagonal of a rectangle representing possible key values for the partition, then there appear to be no obstacles to creating the last partition in the provided SQL script. Illustrative Python script: ```python import matplotlib.pyplot as plt import matplotlib.patches as patches fig, ax =3D plt.subplots() def key(point, radius=3D0.1, color=3D'red', ax=3Dax): circle =3D patches.Circle(point, radius=3Dradius, color=3Dcolor, alpha=3D1) ax.add_patch(circle) return def range(lower, upper, label=3D'', facecolor=3D'blue', edgecolor=3D'red', alpha=3D0.5, ax=3Dax): x1, y1 =3D lower x2, y2 =3D upper x_min, y_min =3D (min(x1, x2), min(y1, y2)) width, height =3D (abs(x2 - x1), abs(y2 - y1)) rectangle =3D patches.Rectangle( (x_min, y_min), width, height, facecolor=3Dfacecolor, edgecolor=3Dedgecolor, alpha=3Dalpha ) ax.add_patch(rectangle) if label: text_x, text_y =3D (x_min, y_min) ax.text(text_x, text_y, label, fontsize=3D8, color=3D'white', ha=3D'left', va=3D'bottom') return rectangle # Range, Key. ------------------------- range( (1, 3, ), (7, 11, ), 'g2_part1') range( (7, 11, ), (13, 15, ), 'g2_part2') range( (13, 15, ), (15, 17, ), 'g2_part3') range( (15, 17, ), (19, 21, ), 'g2_part4') range( (5, 15, ), (13, 17, ), 'g2_part5', 'black') # Show. ------------------------------- plt.xlim(0, 25) plt.ylim(0, 25) plt.gca().set_aspect('equal') plt.grid(True, alpha=3D0.3) plt.show() ``` Let us provide a generalized reasoning: Suppose we have a range-partitioned table with a partitioning key consisting of n attributes. Let us consider the from and to values of the partitioning key from the for values clause as points on the main diagonal of an n-dimensional parallelepiped of permissible key values for a specific partition. Of course, our set is finite, but this perspective on the partitioning key allows us to use a fact from multidimensional geometry: Let the first parallelepiped be defined by the main diagonal points A =3D (a_1, a_2, ..., a_n) and A' =3D (a_1', a_2', ..., a_n'), where a_i < = a_i' for all i, and the second parallelepiped be defined by the main diagonal points B =3D (b_1, b_2, ..., b_n) and B' =3D (b_1', b_2', ..., b_n'), where b_i < = b_i' for all i. In this case, the following theorem (statement) holds true: Two parallelepipeds do not intersect if and only if there exists at least one coordinate k (from 1 to n) for which the projection intervals on this axis do not intersect; that is, the intersection of [a_k, a_k'] and [b_k, b_k'] is an empty set, or equivalently, the condition (a_k' < b_k) OR (b_k' < a_k) holds for one of the k values. In other words, this fact establishes: first, when two figures do not intersect and are separated by a hyperplane x_k =3D const; and second, the necessary and sufficient condition for the figures to intersect, given that all projections intersect. The latter remains valid for a parallelepiped reduced to a point and can determine whether a new key belongs to a particular partition. The experimental patch I am proposing (v1-0001-partition-by-range.patch) introduces changes to the source code based on the described approach, so that the partition from the example can be created. Moreover, the algorithm for determining the partition of a new key during an insert operation is even more mysterious in the current implementation; my patch corrects this. In the proposed patch, writing to output directly via fprintf is hardcoded. This allows obtaining a plain text list of existing and added ranges after each operation for the illustrative Python script. A segmentation fault will occur during update and delete operations. Or would adding an override for the range comparison operator be a more flexible and correct approach? I would like to hear your opinion, dear hackers! --000000000000228c26064f5dee95 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hackers, Hi!

When executing the = SQL script, we discovered strange behavior =E2=80=94 one of the partitions = cannot be created.

```sql
drop table if exists grid2 cascade;

create ta= ble grid2(x bigint, y bigint) partition by range (x,y);

create table= g2_part1 partition of grid2 for values from (1,3) to (7,11);
create tab= le g2_part2 partition of grid2 for values from (7,11) to (13,15);
create= table g2_part3 partition of grid2 for values from (13,15) to (15,17);
c= reate table g2_part4 partition of grid2 for values from (15,17) to (19,21);=
--
create table g2_part5 partition of grid2 for values from (5,15) t= o (13,17);
-- [42P17] ERROR: partition "g2_part5" would overla= p partition "g2_part1"
```

Why is that?
=
According to the documentation, the row comparison rule for tables appl= ies (subsection 9.25.5).
However, in the case of row comparison, it is p= ossible to override comparison operators, which is not the case when defini= ng partitions.
There is no way to override the comparison operator for p= artition ranges. And is this general approach always correct in the case of= partitioning?

For example, the following approach seems quite valid= :

If we look at the relative positions of the ranges for each partit= ioning key (of a single table) on a plane, assuming that the from and to va= lues of the partitioning key in for values are points on the main diagonal = of a rectangle representing possible key values for the partition, then the= re appear to be no obstacles to creating the last partition in the provided= SQL script.

Illustrative Python script:

```python
= import matplotlib.pyplot as plt
import matplotlib.patches as patches
=
fig, ax =3D plt.subplots()

def key(point, radius=3D0.1, color=3D= 'red', ax=3Dax):
circle =3D patches.Circle(point, radius=3Dradiu= s, color=3Dcolor, alpha=3D1)
ax.add_patch(circle)
return

def r= ange(lower, upper, label=3D'', facecolor=3D'blue', edgecolo= r=3D'red', alpha=3D0.5, ax=3Dax):
x1, y1 =3D lower
x2, y2 =3D= upper

x_min, y_min =3D (min(x1, x2), min(y1, y2))
width, height = =3D (abs(x2 - x1), abs(y2 - y1))

rectangle =3D patches.Rectangle((x_min, y_min), width, height,
facecolor=3Dfacecolor, edgecolor=3Dedgec= olor, alpha=3Dalpha
)

ax.add_patch(rectangle)

if label:text_x, text_y =3D (x_min, y_min)
ax.text(text_x, text_y, label, fontsi= ze=3D8, color=3D'white', ha=3D'left', va=3D'bottom'= )

return rectangle

# Range, Key. -------------------------range( (1, 3, ), (7, 11, ), 'g2_part1')
range( (7, 11, ), (13, = 15, ), 'g2_part2')
range( (13, 15, ), (15, 17, ), 'g2_part3&= #39;)
range( (15, 17, ), (19, 21, ), 'g2_part4')
range( (5, 1= 5, ), (13, 17, ), 'g2_part5', 'black')

# Show. -----= --------------------------
plt.xlim(0, 25)
plt.ylim(0, 25)
plt.gca= ().set_aspect('equal')
plt.grid(True, alpha=3D0.3)
plt.show()=
```

<= /span>Let us provide a generalized reasoning:
Suppose we have a range-partitioned table with a partitioning key consist= ing of n attributes.
Let us consider the from and to values of the parti= tioning key from the for values clause as points on the main diagonal of an= n-dimensional parallelepiped of permissible key values for a specific part= ition.
Of course, our set is finite, but this perspective on the partiti= oning key allows us to use a fact from multidimensional geometry:

Le= t the first parallelepiped be defined by the main diagonal points
A =3D = (a_1, a_2, ..., a_n) and A' =3D (a_1', a_2', ..., a_n'), wh= ere a_i < a_i' for all i,
and the second parallelepiped be define= d by the main diagonal points
B =3D (b_1, b_2, ..., b_n) and B' =3D = (b_1', b_2', ..., b_n'), where b_i < b_i' for all i.
=
In this case, the following theorem (statement) holds true:

Two = parallelepipeds do not intersect if and only if there exists at least one c= oordinate k (from 1 to n) for which the projection intervals on this axis d= o not intersect; that is, the intersection of
[a_k, a_k'] and [b_k, b_k'] is an empty s= et, or equivalently, the condition (a_k' < b_k) OR (b_k' < a_= k) holds for one of the k values.

In other words, this fact establis= hes: first, when two figures do not intersect and are separated by a hyperp= lane x_k =3D const; and second, the necessary and sufficient condition for = the figures to intersect, given that all projections intersect. The latter = remains valid for a parallelepiped reduced to a point and can determine whe= ther a new key belongs to a particular partition.

The experimental p= atch I am proposing (v1-0001-partition-by-range.patch) introduces changes t= o the source code based on the described approach, so that the partition fr= om the example can be created.

Moreover, the algorithm for determini= ng the partition of a new key during an insert operation is even more myste= rious in the current implementation; my patch corrects this.

In the = proposed patch, writing to output directly via fprintf is hardcoded. This a= llows obtaining a plain text list of existing and added ranges after each o= peration for the illustrative Python script.

A segmentation fault wi= ll occur during update and delete operations.

Or would adding an ove= rride for the range comparison operator be a more flexible and correct appr= oach?

I would like to hear your opinion, dear hackers!
<= /div> --000000000000228c26064f5dee95-- --000000000000228c27064f5dee97 Content-Type: text/x-patch; charset="US-ASCII"; name="v1-0001-poc-partition-by-range.patch" Content-Disposition: attachment; filename="v1-0001-poc-partition-by-range.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnxoil4y0 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL2V4ZWN1dG9yL2V4ZWNQYXJ0aXRpb24uYyBiL3NyYy9i YWNrZW5kL2V4ZWN1dG9yL2V4ZWNQYXJ0aXRpb24uYwppbmRleCBkOTZkNGY5OTQ3Yi4uMTA5M2Ni NTA0NGMgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL2V4ZWN1dG9yL2V4ZWNQYXJ0aXRpb24uYwor KysgYi9zcmMvYmFja2VuZC9leGVjdXRvci9leGVjUGFydGl0aW9uLmMKQEAgLTE2ODAsNyArMTY4 MCw3IEBAIGdldF9wYXJ0aXRpb25fZm9yX3R1cGxlKFBhcnRpdGlvbkRpc3BhdGNoIHBkLCBjb25z dCBEYXR1bSAqdmFsdWVzLCBjb25zdCBib29sICppCiAJCQkJaWYgKHJhbmdlX3BhcnRrZXlfaGFz X251bGwpCiAJCQkJCWJyZWFrOwogCi0JCQkJaWYgKHBhcnRkZXNjLT5sYXN0X2ZvdW5kX2NvdW50 ID49IFBBUlRJVElPTl9DQUNIRURfRklORF9USFJFU0hPTEQpCisJCQkJaWYgKHBhcnRkZXNjLT5s YXN0X2ZvdW5kX2NvdW50ID49IFBBUlRJVElPTl9DQUNIRURfRklORF9USFJFU0hPTEQgJiYgZmFs c2UgLyogdGVtcG9yYXJ5IGRpc2FibGUgKi8pCiAJCQkJewogCQkJCQlpbnQJCQlsYXN0X2RhdHVt X29mZnNldCA9IHBhcnRkZXNjLT5sYXN0X2ZvdW5kX2RhdHVtX2luZGV4OwogCQkJCQlEYXR1bQkg ICAqbGFzdERhdHVtcyA9IGJvdW5kaW5mby0+ZGF0dW1zW2xhc3RfZGF0dW1fb2Zmc2V0XTsKZGlm ZiAtLWdpdCBhL3NyYy9iYWNrZW5kL3BhcnRpdGlvbmluZy9wYXJ0Ym91bmRzLmMgYi9zcmMvYmFj a2VuZC9wYXJ0aXRpb25pbmcvcGFydGJvdW5kcy5jCmluZGV4IGY4NjdkMWI3NWE1Li41YjYwOTlj N2IzYiAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvcGFydGl0aW9uaW5nL3BhcnRib3VuZHMuYwor KysgYi9zcmMvYmFja2VuZC9wYXJ0aXRpb25pbmcvcGFydGJvdW5kcy5jCkBAIC0yMjQsNyArMjI0 LDggQEAgc3RhdGljIGludDMyIHBhcnRpdGlvbl9yYm91bmRfY21wKGludCBwYXJ0bmF0dHMsIEZt Z3JJbmZvICpwYXJ0c3VwZnVuYywKIHN0YXRpYyBpbnQJcGFydGl0aW9uX3JhbmdlX2JzZWFyY2go aW50IHBhcnRuYXR0cywgRm1nckluZm8gKnBhcnRzdXBmdW5jLAogCQkJCQkJCQkJT2lkICpwYXJ0 Y29sbGF0aW9uLAogCQkJCQkJCQkJUGFydGl0aW9uQm91bmRJbmZvIGJvdW5kaW5mbywKLQkJCQkJ CQkJCVBhcnRpdGlvblJhbmdlQm91bmQgKnByb2JlLCBpbnQzMiAqY21wdmFsKTsKKwkJCQkJCQkJ CVBhcnRpdGlvblJhbmdlQm91bmQgKmxvd2VyLAorCQkJCQkJCQkJUGFydGl0aW9uUmFuZ2VCb3Vu ZCAqdXBwZXIpOwogc3RhdGljIEV4cHIgKm1ha2VfcGFydGl0aW9uX29wX2V4cHIoUGFydGl0aW9u S2V5IGtleSwgaW50IGtleW51bSwKIAkJCQkJCQkJCXVpbnQxNiBzdHJhdGVneSwgRXhwciAqYXJn MSwgRXhwciAqYXJnMik7CiBzdGF0aWMgT2lkCWdldF9wYXJ0aXRpb25fb3BlcmF0b3IoUGFydGl0 aW9uS2V5IGtleSwgaW50IGNvbCwKQEAgLTY3Nyw4ICs2NzgsNyBAQCBjcmVhdGVfcmFuZ2VfYm91 bmRzKFBhcnRpdGlvbkJvdW5kU3BlYyAqKmJvdW5kc3BlY3MsIGludCBucGFydHMsCiB7CiAJUGFy dGl0aW9uQm91bmRJbmZvIGJvdW5kaW5mbzsKIAlQYXJ0aXRpb25SYW5nZUJvdW5kICoqcmJvdW5k cyA9IE5VTEw7Ci0JUGFydGl0aW9uUmFuZ2VCb3VuZCAqKmFsbF9ib3VuZHMsCi0JCQkgICAqcHJl djsKKwlQYXJ0aXRpb25SYW5nZUJvdW5kICoqYWxsX2JvdW5kczsKIAlpbnQJCQlpLAogCQkJCWss CiAJCQkJcGFydG5hdHRzOwpAQCAtNzI4LDYxICs3MjgsMTIgQEAgY3JlYXRlX3JhbmdlX2JvdW5k cyhQYXJ0aXRpb25Cb3VuZFNwZWMgKipib3VuZHNwZWNzLCBpbnQgbnBhcnRzLAogCUFzc2VydChu ZGF0dW1zID09IG5wYXJ0cyAqIDIgfHwKIAkJICAgKGRlZmF1bHRfaW5kZXggIT0gLTEgJiYgbmRh dHVtcyA9PSAobnBhcnRzIC0gMSkgKiAyKSk7CiAKLQkvKiBTb3J0IGFsbCB0aGUgYm91bmRzIGlu IGFzY2VuZGluZyBvcmRlciAqLwotCXFzb3J0X2FyZyhhbGxfYm91bmRzLCBuZGF0dW1zLAotCQkJ ICBzaXplb2YoUGFydGl0aW9uUmFuZ2VCb3VuZCAqKSwKLQkJCSAgcXNvcnRfcGFydGl0aW9uX3Ji b3VuZF9jbXAsCi0JCQkgIGtleSk7Ci0KLQkvKiBTYXZlIGRpc3RpbmN0IGJvdW5kcyBmcm9tIGFs bF9ib3VuZHMgaW50byByYm91bmRzLiAqLwogCXJib3VuZHMgPSAoUGFydGl0aW9uUmFuZ2VCb3Vu ZCAqKikKIAkJcGFsbG9jKG5kYXR1bXMgKiBzaXplb2YoUGFydGl0aW9uUmFuZ2VCb3VuZCAqKSk7 CiAJayA9IDA7Ci0JcHJldiA9IE5VTEw7CiAJZm9yIChpID0gMDsgaSA8IG5kYXR1bXM7IGkrKykK IAl7Ci0JCVBhcnRpdGlvblJhbmdlQm91bmQgKmN1ciA9IGFsbF9ib3VuZHNbaV07Ci0JCWJvb2wJ CWlzX2Rpc3RpbmN0ID0gZmFsc2U7Ci0JCWludAkJCWo7Ci0KLQkJLyogSXMgdGhlIGN1cnJlbnQg Ym91bmQgZGlzdGluY3QgZnJvbSB0aGUgcHJldmlvdXMgb25lPyAqLwotCQlmb3IgKGogPSAwOyBq IDwga2V5LT5wYXJ0bmF0dHM7IGorKykKLQkJewotCQkJRGF0dW0JCWNtcHZhbDsKLQotCQkJaWYg KHByZXYgPT0gTlVMTCB8fCBjdXItPmtpbmRbal0gIT0gcHJldi0+a2luZFtqXSkKLQkJCXsKLQkJ CQlpc19kaXN0aW5jdCA9IHRydWU7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0KLQkJCS8qCi0JCQkgKiBJ ZiB0aGUgYm91bmRzIGFyZSBib3RoIE1JTlZBTFVFIG9yIE1BWFZBTFVFLCBzdG9wIG5vdyBhbmQg dHJlYXQKLQkJCSAqIHRoZW0gYXMgZXF1YWwsIHNpbmNlIGFueSB2YWx1ZXMgYWZ0ZXIgdGhpcyBw b2ludCBtdXN0IGJlCi0JCQkgKiBpZ25vcmVkLgotCQkJICovCi0JCQlpZiAoY3VyLT5raW5kW2pd ICE9IFBBUlRJVElPTl9SQU5HRV9EQVRVTV9WQUxVRSkKLQkJCQlicmVhazsKLQotCQkJY21wdmFs ID0gRnVuY3Rpb25DYWxsMkNvbGwoJmtleS0+cGFydHN1cGZ1bmNbal0sCi0JCQkJCQkJCQkgICBr ZXktPnBhcnRjb2xsYXRpb25bal0sCi0JCQkJCQkJCQkgICBjdXItPmRhdHVtc1tqXSwKLQkJCQkJ CQkJCSAgIHByZXYtPmRhdHVtc1tqXSk7Ci0JCQlpZiAoRGF0dW1HZXRJbnQzMihjbXB2YWwpICE9 IDApCi0JCQl7Ci0JCQkJaXNfZGlzdGluY3QgPSB0cnVlOwotCQkJCWJyZWFrOwotCQkJfQotCQl9 Ci0KLQkJLyoKLQkJICogT25seSBpZiB0aGUgYm91bmQgaXMgZGlzdGluY3Qgc2F2ZSBpdCBpbnRv IGEgdGVtcG9yYXJ5IGFycmF5LCBpLmUsCi0JCSAqIHJib3VuZHMgd2hpY2ggaXMgbGF0ZXIgY29w aWVkIGludG8gYm91bmRpbmZvIGRhdHVtcyBhcnJheS4KLQkJICovCi0JCWlmIChpc19kaXN0aW5j dCkKIAkJCXJib3VuZHNbaysrXSA9IGFsbF9ib3VuZHNbaV07Ci0KLQkJcHJldiA9IGN1cjsKIAl9 CiAKIAlwZnJlZShhbGxfYm91bmRzKTsKQEAgLTMxMjcsNiArMzA3OCw3IEBAIGNoZWNrX25ld19w YXJ0aXRpb25fYm91bmQoY2hhciAqcmVsbmFtZSwgUmVsYXRpb24gcGFyZW50LAogCiAJCQkJaWYg KHBhcnRkZXNjLT5ucGFydHMgPiAwKQogCQkJCXsKKwkJCQkJLyogaWYga2V5LT5wYXJ0bmF0dHMg PT0gMSBvciA/IGJvdW5kaW5mby0+bmRhdHVtcyAqLwogCQkJCQlpbnQJCQlvZmZzZXQ7CiAKIAkJ CQkJQXNzZXJ0KGJvdW5kaW5mbyAmJgpAQCAtMzE1Miw2OCArMzEwNCwxMCBAQCBjaGVja19uZXdf cGFydGl0aW9uX2JvdW5kKGNoYXIgKnJlbG5hbWUsIFJlbGF0aW9uIHBhcmVudCwKIAkJCQkJb2Zm c2V0ID0gcGFydGl0aW9uX3JhbmdlX2JzZWFyY2goa2V5LT5wYXJ0bmF0dHMsCiAJCQkJCQkJCQkJ CQkJIGtleS0+cGFydHN1cGZ1bmMsCiAJCQkJCQkJCQkJCQkJIGtleS0+cGFydGNvbGxhdGlvbiwK LQkJCQkJCQkJCQkJCQkgYm91bmRpbmZvLCBsb3dlciwKLQkJCQkJCQkJCQkJCQkgJmNtcHZhbCk7 CisJCQkJCQkJCQkJCQkJIGJvdW5kaW5mbywgbG93ZXIsIHVwcGVyKTsKIAotCQkJCQlpZiAoYm91 bmRpbmZvLT5pbmRleGVzW29mZnNldCArIDFdIDwgMCkKLQkJCQkJewotCQkJCQkJLyoKLQkJCQkJ CSAqIENoZWNrIHRoYXQgdGhlIG5ldyBwYXJ0aXRpb24gd2lsbCBmaXQgaW4gdGhlIGdhcC4KLQkJ CQkJCSAqIEZvciBpdCB0byBmaXQsIHRoZSBuZXcgdXBwZXIgYm91bmQgbXVzdCBiZSBsZXNzCi0J CQkJCQkgKiB0aGFuIG9yIGVxdWFsIHRvIHRoZSBsb3dlciBib3VuZCBvZiB0aGUgbmV4dAotCQkJ CQkJICogcGFydGl0aW9uLCBpZiB0aGVyZSBpcyBvbmUuCi0JCQkJCQkgKi8KLQkJCQkJCWlmIChv ZmZzZXQgKyAxIDwgYm91bmRpbmZvLT5uZGF0dW1zKQotCQkJCQkJewotCQkJCQkJCURhdHVtCSAg ICpkYXR1bXM7Ci0JCQkJCQkJUGFydGl0aW9uUmFuZ2VEYXR1bUtpbmQgKmtpbmQ7Ci0JCQkJCQkJ Ym9vbAkJaXNfbG93ZXI7Ci0KLQkJCQkJCQlkYXR1bXMgPSBib3VuZGluZm8tPmRhdHVtc1tvZmZz ZXQgKyAxXTsKLQkJCQkJCQlraW5kID0gYm91bmRpbmZvLT5raW5kW29mZnNldCArIDFdOwotCQkJ CQkJCWlzX2xvd2VyID0gKGJvdW5kaW5mby0+aW5kZXhlc1tvZmZzZXQgKyAxXSA9PSAtMSk7Ci0K LQkJCQkJCQljbXB2YWwgPSBwYXJ0aXRpb25fcmJvdW5kX2NtcChrZXktPnBhcnRuYXR0cywKLQkJ CQkJCQkJCQkJCQkJICBrZXktPnBhcnRzdXBmdW5jLAotCQkJCQkJCQkJCQkJCQkgIGtleS0+cGFy dGNvbGxhdGlvbiwKLQkJCQkJCQkJCQkJCQkJICBkYXR1bXMsIGtpbmQsCi0JCQkJCQkJCQkJCQkJ CSAgaXNfbG93ZXIsIHVwcGVyKTsKLQkJCQkJCQlpZiAoY21wdmFsIDwgMCkKLQkJCQkJCQl7Ci0J CQkJCQkJCS8qCi0JCQkJCQkJCSAqIFBvaW50IHRvIHByb2JsZW1hdGljIGtleSBpbiB0aGUgdXBw ZXIKLQkJCQkJCQkJICogZGF0dW1zIGxpc3QuCi0JCQkJCQkJCSAqLwotCQkJCQkJCQlQYXJ0aXRp b25SYW5nZURhdHVtICpkYXR1bSA9Ci0JCQkJCQkJCQlsaXN0X250aChzcGVjLT51cHBlcmRhdHVt cywgYWJzKGNtcHZhbCkgLSAxKTsKLQotCQkJCQkJCQkvKgotCQkJCQkJCQkgKiBUaGUgbmV3IHBh cnRpdGlvbiBvdmVybGFwcyB3aXRoIHRoZQotCQkJCQkJCQkgKiBleGlzdGluZyBwYXJ0aXRpb24g YmV0d2VlbiBvZmZzZXQgKyAxIGFuZAotCQkJCQkJCQkgKiBvZmZzZXQgKyAyLgotCQkJCQkJCQkg Ki8KLQkJCQkJCQkJb3ZlcmxhcCA9IHRydWU7Ci0JCQkJCQkJCW92ZXJsYXBfbG9jYXRpb24gPSBk YXR1bS0+bG9jYXRpb247Ci0JCQkJCQkJCXdpdGggPSBib3VuZGluZm8tPmluZGV4ZXNbb2Zmc2V0 ICsgMl07Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWVsc2UKLQkJCQkJewotCQkJ CQkJLyoKLQkJCQkJCSAqIFRoZSBuZXcgcGFydGl0aW9uIG92ZXJsYXBzIHdpdGggdGhlIGV4aXN0 aW5nCi0JCQkJCQkgKiBwYXJ0aXRpb24gYmV0d2VlbiBvZmZzZXQgYW5kIG9mZnNldCArIDEuCi0J CQkJCQkgKi8KLQkJCQkJCVBhcnRpdGlvblJhbmdlRGF0dW0gKmRhdHVtOwotCi0JCQkJCQkvKgot CQkJCQkJICogUG9pbnQgdG8gcHJvYmxlbWF0aWMga2V5IGluIHRoZSBsb3dlciBkYXR1bXMgbGlz dDsKLQkJCQkJCSAqIGlmIHdlIGhhdmUgZXF1YWxpdHksIHBvaW50IHRvIHRoZSBmaXJzdCBvbmUu Ci0JCQkJCQkgKi8KLQkJCQkJCWRhdHVtID0gY21wdmFsID09IDAgPyBsaW5pdGlhbChzcGVjLT5s b3dlcmRhdHVtcykgOgotCQkJCQkJCWxpc3RfbnRoKHNwZWMtPmxvd2VyZGF0dW1zLCBhYnMoY21w dmFsKSAtIDEpOworCQkJCQlpZiAob2Zmc2V0ID4gLTEpIHsKIAkJCQkJCW92ZXJsYXAgPSB0cnVl OwotCQkJCQkJb3ZlcmxhcF9sb2NhdGlvbiA9IGRhdHVtLT5sb2NhdGlvbjsKIAkJCQkJCXdpdGgg PSBib3VuZGluZm8tPmluZGV4ZXNbb2Zmc2V0ICsgMV07CiAJCQkJCX0KIAkJCQl9CkBAIC0zNjQ2 LDM0ICszNTQwLDEzMyBAQCBzdGF0aWMgaW50CiBwYXJ0aXRpb25fcmFuZ2VfYnNlYXJjaChpbnQg cGFydG5hdHRzLCBGbWdySW5mbyAqcGFydHN1cGZ1bmMsCiAJCQkJCQlPaWQgKnBhcnRjb2xsYXRp b24sCiAJCQkJCQlQYXJ0aXRpb25Cb3VuZEluZm8gYm91bmRpbmZvLAotCQkJCQkJUGFydGl0aW9u UmFuZ2VCb3VuZCAqcHJvYmUsIGludDMyICpjbXB2YWwpCisJCQkJCQlQYXJ0aXRpb25SYW5nZUJv dW5kICpsb3dlciwKKwkJCQkJCVBhcnRpdGlvblJhbmdlQm91bmQgKnVwcGVyKQogewotCWludAkJ CWxvLAotCQkJCWhpLAotCQkJCW1pZDsKKwlpbnQgb2Zmc2V0ID0gLTE7CisJaW50IGQsIHBhcnRh dHRyOworCWludDMyIGNtcHZhbDEsIGNtcHZhbDI7CiAKLQlsbyA9IC0xOwotCWhpID0gYm91bmRp bmZvLT5uZGF0dW1zIC0gMTsKLQl3aGlsZSAobG8gPCBoaSkKKwlEYXR1bSAqbG93ZXJfZGF0dW1z LCAqdXBwZXJfZGF0dW1zOworCisJZnByaW50ZihzdGRvdXQsIkZ1bmMgOiBwYXJ0aXRpb25fcmFu Z2VfYnNlYXJjaCA6IFxuIik7CisJZnByaW50ZihzdGRvdXQsIlxuIyBQYXJ0aXRpb24gYnkgcmFu Z2UgKHJlbGV2YW50IGZvciAyRCBwYXJ0aXRpb24ga2V5LCBmb3IgUHl0aG9uIHNjcmlwdCkgOiBc biIpOworCisJLyogTmV3IHRoZSBwYXJ0aXRpb24gYnkgcmFuZ2UgKi8KKwlwYXJ0YXR0ciA9IDA7 CisJZnByaW50ZihzdGRvdXQsInJhbmdlKCgiKTsKKwl3aGlsZSAocGFydGF0dHIgPCBwYXJ0bmF0 dHMpIHsKKwkJZnByaW50ZihzdGRvdXQsICIlbHUsICIsIGxvd2VyLT5kYXR1bXNbcGFydGF0dHJd KTsKKwkJcGFydGF0dHIrKzsKKwl9CisJZnByaW50ZihzdGRvdXQsIiksICIpOworCisJcGFydGF0 dHIgPSAwOworCWZwcmludGYoc3Rkb3V0LCIoIik7CisJd2hpbGUgKHBhcnRhdHRyIDwgcGFydG5h dHRzKSB7CisJCWZwcmludGYoc3Rkb3V0LCAiJWx1LCAiLCB1cHBlci0+ZGF0dW1zW3BhcnRhdHRy XSk7CisJCXBhcnRhdHRyKys7CisJfQorCWZwcmludGYoc3Rkb3V0LCIpLCAnbmV3JywgZmFjZWNv bG9yPSdibGFjaycsIGVkZ2Vjb2xvcj0neWVsbG93JylcbiIpOworCisJLyogRXhpc3RpbmcgdGhl IHBhcnRpdGlvbiBieSByYW5nZSAqLworCWQgPSAwOworCXdoaWxlICggZCA8IGJvdW5kaW5mby0+ bmRhdHVtcyAtIDEgKQogCXsKLQkJbWlkID0gKGxvICsgaGkgKyAxKSAvIDI7Ci0JCSpjbXB2YWwg PSBwYXJ0aXRpb25fcmJvdW5kX2NtcChwYXJ0bmF0dHMsIHBhcnRzdXBmdW5jLAotCQkJCQkJCQkJ ICAgcGFydGNvbGxhdGlvbiwKLQkJCQkJCQkJCSAgIGJvdW5kaW5mby0+ZGF0dW1zW21pZF0sCi0J CQkJCQkJCQkgICBib3VuZGluZm8tPmtpbmRbbWlkXSwKLQkJCQkJCQkJCSAgIChib3VuZGluZm8t PmluZGV4ZXNbbWlkXSA9PSAtMSksCi0JCQkJCQkJCQkgICBwcm9iZSk7Ci0JCWlmICgqY21wdmFs IDw9IDApCisJCWlmICggYm91bmRpbmZvLT5pbmRleGVzW2RdID09IC0xICYmIGJvdW5kaW5mby0+ aW5kZXhlc1tkKzFdID4gLTEgKQogCQl7Ci0JCQlsbyA9IG1pZDsKLQkJCWlmICgqY21wdmFsID09 IDApCi0JCQkJYnJlYWs7CisJCQlsb3dlcl9kYXR1bXMgPSBib3VuZGluZm8tPmRhdHVtc1tkXTsK KwkJCXVwcGVyX2RhdHVtcyA9IGJvdW5kaW5mby0+ZGF0dW1zW2QrMV07CisKKwkJCXBhcnRhdHRy ID0gMDsKKwkJCWZwcmludGYoc3Rkb3V0LCJyYW5nZSgoIik7CisJCQl3aGlsZSAocGFydGF0dHIg PCBwYXJ0bmF0dHMpIHsKKwkJCQlmcHJpbnRmKHN0ZG91dCwgIiVsdSwgIiwgbG93ZXJfZGF0dW1z W3BhcnRhdHRyXSk7CisJCQkJcGFydGF0dHIrKzsKKwkJCX0KKwkJCWZwcmludGYoc3Rkb3V0LCIp LCAiKTsKKworCQkJcGFydGF0dHIgPSAwOworCQkJZnByaW50ZihzdGRvdXQsIigiKTsKKwkJCXdo aWxlIChwYXJ0YXR0ciA8IHBhcnRuYXR0cykgeworCQkJCWZwcmludGYoc3Rkb3V0LCAiJWx1LCAi LCB1cHBlcl9kYXR1bXNbcGFydGF0dHJdKTsKKwkJCQlwYXJ0YXR0cisrOworCQkJfQorCQkJZnBy aW50ZihzdGRvdXQsIiksJ3AtJWQnKVxuIiwgYm91bmRpbmZvLT5pbmRleGVzW2QrMV0pOworCisJ CQlkKz0yOwogCQl9CiAJCWVsc2UKLQkJCWhpID0gbWlkIC0gMTsKKwkJCWQrKzsKIAl9CisJZnBy aW50ZihzdGRvdXQsIlxuIik7CisJZmZsdXNoKHN0ZG91dCk7CiAKLQlyZXR1cm4gbG87CisJLyog U2VhcmNoIGFsZ29yaXRobSAqLworCWQgPSAwOworCXdoaWxlICggZCA8IGJvdW5kaW5mby0+bmRh dHVtcyApCisJeworCQlpZiAoIChib3VuZGluZm8tPmluZGV4ZXNbZF0gPT0gLTEpICYmIChib3Vu ZGluZm8tPmluZGV4ZXNbZCsxXSA+IC0xKSApCisJCXsKKwkJCWxvd2VyX2RhdHVtcyA9IGJvdW5k aW5mby0+ZGF0dW1zW2RdOworCQkJdXBwZXJfZGF0dW1zID0gYm91bmRpbmZvLT5kYXR1bXNbZCsx XTsKKworCQkJcGFydGF0dHIgPSAwOworCQkJd2hpbGUgKHBhcnRhdHRyIDwgcGFydG5hdHRzKQor CQkJeworCQkJCWNtcHZhbDEgPSBEYXR1bUdldEludDMyKEZ1bmN0aW9uQ2FsbDJDb2xsKCZwYXJ0 c3VwZnVuY1twYXJ0YXR0cl0sIHBhcnRjb2xsYXRpb25bcGFydGF0dHJdLAorCQkJCQkJCQkJCQkJ CQkgdXBwZXJfZGF0dW1zW3BhcnRhdHRyXSwgbG93ZXItPmRhdHVtc1twYXJ0YXR0cl0pKTsKKwor CQkJCWNtcHZhbDIgPSBEYXR1bUdldEludDMyKEZ1bmN0aW9uQ2FsbDJDb2xsKCZwYXJ0c3VwZnVu Y1twYXJ0YXR0cl0sIHBhcnRjb2xsYXRpb25bcGFydGF0dHJdLAorCQkJCQkJCQkJCQkJCQkgdXBw ZXItPmRhdHVtc1twYXJ0YXR0cl0sIGxvd2VyX2RhdHVtc1twYXJ0YXR0cl0pKTsKKworCQkJCS8q IFN0ZXAgb2YgdGhlIHNlYXJjaCBhbGdvcml0aG0gKi8KKwkJCQkvKiBkYXR1bXNfbG93ZXJbcGFy dGF0dHJdLCBkYXR1bXNfdXBwZXJbcGFydGF0dHJdIDsKKwkJCQkgKiBwcm9iZS0+ZGF0dW1zW3Bh cnRhdHRyXSwgdXBwZXItPmRhdHVtc1twYXJ0YXR0cl07CisJCQkJICogYSxhJzsgYixiJyAtPiBh X2snIDwgYl9rIE9SIGJfaycgPCBhX2sKKwkJCQkgKi8KKwkJCQlmcHJpbnRmKHN0ZG91dCwgIlJh bmdlIDogRXhpc3RzKCAlbHUsICVsdSksIE5ldyggJWx1LCAlbHUpXG4iLAorCQkJCQlsb3dlcl9k YXR1bXNbcGFydGF0dHJdLCB1cHBlcl9kYXR1bXNbcGFydGF0dHJdLAorCQkJCQlsb3dlci0+ZGF0 dW1zW3BhcnRhdHRyXSwgdXBwZXItPmRhdHVtc1twYXJ0YXR0cl0pOworCQkJCWZwcmludGYoc3Rk b3V0LCAiQ29uZGl0aW9uOiAxKSAlbHUgPCAlbHUgOiByZXN1bHQgPSAlZCBvciAyKSAlbHUgPCAl bHUgOiByZXN1bHQgPSAlZDsgYXR0ciA9ICVkOyAiLAorCQkJCQl1cHBlcl9kYXR1bXNbcGFydGF0 dHJdLCBsb3dlci0+ZGF0dW1zW3BhcnRhdHRyXSwgY21wdmFsMSwKKwkJCQkJdXBwZXItPmRhdHVt c1twYXJ0YXR0cl0sIGxvd2VyX2RhdHVtc1twYXJ0YXR0cl0sIGNtcHZhbDIsCisJCQkJCXBhcnRh dHRyKTsKKworCQkJCWlmICggY21wdmFsMSA8IDEgfHwgY21wdmFsMiA8IDEgKQorCQkJCXsKKwkJ CQkJLyogVGhlIHBhcnRpdGlvbiByYW5nZSBwYXNzZWQgdGhlIGNoZWNrIC0gdGhlcmUgYXJlIG5v IGludGVyc2VjdGlvbnMKKwkJCQkJICogd2l0aCB0aGUgbmV3IHBhcnRpdGlvbiByYW5nZS4KKwkJ CQkJICogVGhlbiBleGl0IHRoZSBsb29wIHdpdGggdGhlIHZhbHVlIHBhcnRuYXR0cysrCisJCQkJ CSAqLworCQkJCQlwYXJ0YXR0ciA9IHBhcnRuYXR0czsKKwkJCQkJZnByaW50ZihzdGRvdXQsICJb Q0hFQ0sgT0tdLiIpOworCQkJCX0KKworCQkJCXBhcnRhdHRyKys7CisJCQkJZnByaW50ZihzdGRv dXQsIlxuIik7CisJCQkJZmZsdXNoKHN0ZG91dCk7CisJCQl9CisKKwkJCWlmIChwYXJ0YXR0ciA9 PSBwYXJ0bmF0dHMpCisJCQl7CisJCQkJLyogVGhpcyBjb25kaXRpb24gbWVhbnMgdGhhdCBpbiB0 aGUgd2hpbGUgbG9vcCBmb3IgYWxsIDxwYXJ0YXR0cj4sCisJCQkJICogdGhlcmUgaXMgYW4gaW50 ZXJzZWN0aW9uIG9mIHJhbmdlcyBhY3Jvc3MgYWxsIHBhcnRpdGlvbiBrZXkgdmFsdWUuCisJCQkJ ICogVGhlcmVmb3JlLCB3ZSBjYW4gc2tpcCBmdXJ0aGVyIHBhcnRpdGlvbiByYW5nZSBjaGVja3Mu CisJCQkJICovCisJCQkJb2Zmc2V0ID0gZDsKKwkJCQlkID0gYm91bmRpbmZvLT5uZGF0dW1zICsg MzsKKwkJCX0KKwkJCWQrPTI7CisJCX0KKwkJZWxzZQorCQkJZCsrOworCX0KKworCWZwcmludGYo c3Rkb3V0LCJOZXcgdGhlIHBhcnRpdGlvbiBieSByYW5nZSA6ICVzLlxuIiwgKGQgPT0gYm91bmRp bmZvLT5uZGF0dW1zICsgMykgPyAiRVJST1IiIDogIk9LIiApOworCWZmbHVzaChzdGRvdXQpOwor CisJcmV0dXJuIG9mZnNldDsKIH0KIAogLyoKQEAgLTM2ODksMzYgKzM2ODIsMTAzIEBAIHBhcnRp dGlvbl9yYW5nZV9kYXR1bV9ic2VhcmNoKEZtZ3JJbmZvICpwYXJ0c3VwZnVuYywgT2lkICpwYXJ0 Y29sbGF0aW9uLAogCQkJCQkJCSAgUGFydGl0aW9uQm91bmRJbmZvIGJvdW5kaW5mbywKIAkJCQkJ CQkgIGludCBudmFsdWVzLCBjb25zdCBEYXR1bSAqdmFsdWVzLCBib29sICppc19lcXVhbCkKIHsK LQlpbnQJCQlsbywKLQkJCQloaSwKLQkJCQltaWQ7CisJaW50IG9mZnNldCA9IC0xOworCWludCBk LCBwYXJ0YXR0cjsKKwlpbnQzMiBjbXB2YWwxLCBjbXB2YWwyOworCisJRGF0dW0gKmxvd2VyX2Rh dHVtcywgKnVwcGVyX2RhdHVtczsKKwlmcHJpbnRmKHN0ZG91dCwiRnVuYyA6IHBhcnRpdGlvbl9y YW5nZV9kYXR1bV9ic2VhcmNoIDogbnZhbHVlcyA9ICVkXG4iLCBudmFsdWVzKTsKKwlmcHJpbnRm KHN0ZG91dCwiXG4jIFBhcnRpdGlvbiBieSByYW5nZSAocmVsZXZhbnQgZm9yIDJEIHBhcnRpdGlv biBrZXksIGZvciBQeXRob24gc2NyaXB0KSA6IFxuIik7CisKKwkvKiBOZXcgdGhlIHBhcnRpdGlv biBrZXkgKi8KKwlwYXJ0YXR0ciA9IDA7CisJZnByaW50ZihzdGRvdXQsImtleSgoIik7CisJd2hp bGUgKHBhcnRhdHRyIDwgbnZhbHVlcykgeworCQlmcHJpbnRmKHN0ZG91dCwgIiVsdSwgIiwgdmFs dWVzW3BhcnRhdHRyXSk7CisJCXBhcnRhdHRyKys7CisJfQorCWZwcmludGYoc3Rkb3V0LCIpLCAw LjMpXG4iKTsKIAotCWxvID0gLTE7Ci0JaGkgPSBib3VuZGluZm8tPm5kYXR1bXMgLSAxOwotCXdo aWxlIChsbyA8IGhpKQorCS8qIEV4aXN0aW5nIHRoZSBwYXJ0aXRpb24gYnkgcmFuZ2UgKi8KKwlk ID0gMDsKKwl3aGlsZSAoIGQgPCBib3VuZGluZm8tPm5kYXR1bXMgLSAxICkKIAl7Ci0JCWludDMy CQljbXB2YWw7CisJCWlmICggYm91bmRpbmZvLT5pbmRleGVzW2RdID09IC0xICYmIGJvdW5kaW5m by0+aW5kZXhlc1tkKzFdID4gLTEgKQorCQl7CisJCQlsb3dlcl9kYXR1bXMgPSBib3VuZGluZm8t PmRhdHVtc1tkXTsKKwkJCXVwcGVyX2RhdHVtcyA9IGJvdW5kaW5mby0+ZGF0dW1zW2QrMV07CisK KwkJCXBhcnRhdHRyID0gMDsKKwkJCWZwcmludGYoc3Rkb3V0LCJyYW5nZSgoIik7CisJCQl3aGls ZSAocGFydGF0dHIgPCBudmFsdWVzKSB7CisJCQkJZnByaW50ZihzdGRvdXQsICIlbHUsICIsIGxv d2VyX2RhdHVtc1twYXJ0YXR0cl0pOworCQkJCXBhcnRhdHRyKys7CisJCQl9CisJCQlmcHJpbnRm KHN0ZG91dCwiKSwgIik7CiAKLQkJbWlkID0gKGxvICsgaGkgKyAxKSAvIDI7Ci0JCWNtcHZhbCA9 IHBhcnRpdGlvbl9yYm91bmRfZGF0dW1fY21wKHBhcnRzdXBmdW5jLAotCQkJCQkJCQkJCQlwYXJ0 Y29sbGF0aW9uLAotCQkJCQkJCQkJCQlib3VuZGluZm8tPmRhdHVtc1ttaWRdLAotCQkJCQkJCQkJ CQlib3VuZGluZm8tPmtpbmRbbWlkXSwKLQkJCQkJCQkJCQkJdmFsdWVzLAotCQkJCQkJCQkJCQlu dmFsdWVzKTsKLQkJaWYgKGNtcHZhbCA8PSAwKQorCQkJcGFydGF0dHIgPSAwOworCQkJZnByaW50 ZihzdGRvdXQsIigiKTsKKwkJCXdoaWxlIChwYXJ0YXR0ciA8IG52YWx1ZXMpIHsKKwkJCQlmcHJp bnRmKHN0ZG91dCwgIiVsdSwgIiwgdXBwZXJfZGF0dW1zW3BhcnRhdHRyXSk7CisJCQkJcGFydGF0 dHIrKzsKKwkJCX0KKwkJCWZwcmludGYoc3Rkb3V0LCIpLCdwLSVkJylcbiIsIGJvdW5kaW5mby0+ aW5kZXhlc1tkKzFdKTsKKworCQkJZCs9MjsKKwkJfQorCQllbHNlCisJCQlkKys7CisJfQorCWZw cmludGYoc3Rkb3V0LCJcbiIpOworCWZmbHVzaChzdGRvdXQpOworCisJLyogU2VhcmNoIGFsZ29y aXRobSAqLworCWQgPSAwOworCXdoaWxlICggZCA8IGJvdW5kaW5mby0+bmRhdHVtcyApCisJewor CQlpZiAoIChib3VuZGluZm8tPmluZGV4ZXNbZF0gPT0gLTEpICYmIChib3VuZGluZm8tPmluZGV4 ZXNbZCsxXSA+IC0xKSApCiAJCXsKLQkJCWxvID0gbWlkOwotCQkJKmlzX2VxdWFsID0gKGNtcHZh bCA9PSAwKTsKKwkJCWxvd2VyX2RhdHVtcyA9IGJvdW5kaW5mby0+ZGF0dW1zW2RdOworCQkJdXBw ZXJfZGF0dW1zID0gYm91bmRpbmZvLT5kYXR1bXNbZCsxXTsKIAotCQkJaWYgKCppc19lcXVhbCkK LQkJCQlicmVhazsKKwkJCXBhcnRhdHRyID0gMDsKKwkJCXdoaWxlIChwYXJ0YXR0ciA8IG52YWx1 ZXMpCisJCQl7CisJCQkJY21wdmFsMSA9IERhdHVtR2V0SW50MzIoRnVuY3Rpb25DYWxsMkNvbGwo JnBhcnRzdXBmdW5jW3BhcnRhdHRyXSwgcGFydGNvbGxhdGlvbltwYXJ0YXR0cl0sCisJCQkJCQkJ CQkJCQkJCSBsb3dlcl9kYXR1bXNbcGFydGF0dHJdLCB2YWx1ZXNbcGFydGF0dHJdKSk7CisKKwkJ CQljbXB2YWwyID0gRGF0dW1HZXRJbnQzMihGdW5jdGlvbkNhbGwyQ29sbCgmcGFydHN1cGZ1bmNb cGFydGF0dHJdLCBwYXJ0Y29sbGF0aW9uW3BhcnRhdHRyXSwKKwkJCQkJCQkJCQkJCQkJIHZhbHVl c1twYXJ0YXR0cl0sIHVwcGVyX2RhdHVtc1twYXJ0YXR0cl0pKTsKKworCQkJCS8qIFN0ZXAgb2Yg dGhlIHNlYXJjaCBhbGdvcml0aG0gKi8KKwkJCQlmcHJpbnRmKHN0ZG91dCwgIlJhbmdlIDogRXhp c3RzKCVsdSwgJWx1KSwgS2V5KCVsdSlcbiIsICBsb3dlcl9kYXR1bXNbcGFydGF0dHJdLCB1cHBl cl9kYXR1bXNbcGFydGF0dHJdLCB2YWx1ZXNbcGFydGF0dHJdKTsKKworCQkJCWlmICggIShjbXB2 YWwxIDwgMSAmJiBjbXB2YWwyIDwgMSkgKQorCQkJCXsKKwkJCQkJcGFydGF0dHIgPSBudmFsdWVz OworCQkJCQlmcHJpbnRmKHN0ZG91dCwgIltLRVkgT1VUIFJBTkdFXS4iKTsKKwkJCQl9CisKKwkJ CQlwYXJ0YXR0cisrOworCQkJCWZwcmludGYoc3Rkb3V0LCJcbiIpOworCQkJCWZmbHVzaChzdGRv dXQpOworCQkJfQorCisJCQlpZiAocGFydGF0dHIgPT0gbnZhbHVlcykKKwkJCXsKKwkJCQlvZmZz ZXQgPSBkOworCQkJCWQgPSBib3VuZGluZm8tPm5kYXR1bXMgKyAzOworCQkJfQorCQkJZCs9MjsK IAkJfQogCQllbHNlCi0JCQloaSA9IG1pZCAtIDE7CisJCQlkKys7CiAJfQogCi0JcmV0dXJuIGxv OworCWZwcmludGYoc3Rkb3V0LCJOZXcgcGFydGl0aW9uIGtleSA6ICVzLlxuIiwgKGQgPT0gYm91 bmRpbmZvLT5uZGF0dW1zICsgMykgPyAiT0siIDogIkVSUk9SIiApOworCWZmbHVzaChzdGRvdXQp OworCisJcmV0dXJuIG9mZnNldDsKIH0KIAogLyoKZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL3Bh cnRpdGlvbmluZy9wYXJ0ZGVzYy5jIGIvc3JjL2JhY2tlbmQvcGFydGl0aW9uaW5nL3BhcnRkZXNj LmMKaW5kZXggYzNkMjc1Zjg3MjYuLjc3ZWYxMTYxNzJjIDEwMDY0NAotLS0gYS9zcmMvYmFja2Vu ZC9wYXJ0aXRpb25pbmcvcGFydGRlc2MuYworKysgYi9zcmMvYmFja2VuZC9wYXJ0aXRpb25pbmcv cGFydGRlc2MuYwpAQCAtNzEsNyArNzEsNyBAQCBQYXJ0aXRpb25EZXNjCiBSZWxhdGlvbkdldFBh cnRpdGlvbkRlc2MoUmVsYXRpb24gcmVsLCBib29sIG9taXRfZGV0YWNoZWQpCiB7CiAJQXNzZXJ0 KHJlbC0+cmRfcmVsLT5yZWxraW5kID09IFJFTEtJTkRfUEFSVElUSU9ORURfVEFCTEUpOwotCisJ cmV0dXJuIFJlbGF0aW9uQnVpbGRQYXJ0aXRpb25EZXNjKHJlbCwgb21pdF9kZXRhY2hlZCk7CiAJ LyoKIAkgKiBJZiByZWxjYWNoZSBoYXMgYSBwYXJ0aXRpb24gZGVzY3JpcHRvciwgdXNlIHRoYXQu ICBIb3dldmVyLCB3ZSBjYW4gb25seQogCSAqIGRvIHNvIHdoZW4gd2UgYXJlIGFza2VkIHRvIGlu Y2x1ZGUgYWxsIHBhcnRpdGlvbnMgaW5jbHVkaW5nIGRldGFjaGVkOwpAQCAtMzA3LDkgKzMwNywz MCBAQCByZXRyeToKIAkgKiBDcmVhdGUgUGFydGl0aW9uQm91bmRJbmZvIGFuZCBtYXBwaW5nLCB3 b3JraW5nIGluIHRoZSBjYWxsZXIncyBjb250ZXh0LgogCSAqIFRoaXMgY291bGQgZmFpbCwgYnV0 IHdlIGhhdmVuJ3QgZG9uZSBhbnkgZGFtYWdlIGlmIHNvLgogCSAqLwotCWlmIChucGFydHMgPiAw KQorCWlmIChucGFydHMgPiAwKSB7CiAJCWJvdW5kaW5mbyA9IHBhcnRpdGlvbl9ib3VuZHNfY3Jl YXRlKGJvdW5kc3BlY3MsIG5wYXJ0cywga2V5LCAmbWFwcGluZyk7CiAKKwkJaW50IGQgPSAwLCBw YXJ0YXR0cjsKKworCQlmcHJpbnRmKHN0ZG91dCwiQm91bmRJbmZvIDogXG4iKTsKKwkJd2hpbGUg KCBkIDwgYm91bmRpbmZvLT5uZGF0dW1zICkKKwkJeworCQkJLypjdXJfZGF0dW0gPSBib3VuZGlu Zm8tPmRhdHVtc1tkXTsqLworCQkJZnByaW50ZihzdGRvdXQsIkluZGV4ID0gJWQsIFJhbmdlICgi LGJvdW5kaW5mby0+aW5kZXhlc1tkXSk7CisKKwkJCXBhcnRhdHRyID0gMDsKKwkJCXdoaWxlIChw YXJ0YXR0ciA8IGtleS0+cGFydG5hdHRzKQorCQkJeworCQkJCWZwcmludGYoc3Rkb3V0LCIgJWx1 LCAiLCBib3VuZGluZm8tPmRhdHVtc1tkXVtwYXJ0YXR0cl0pOworCQkJCXBhcnRhdHRyKys7CisJ CQl9CisJCQlmcHJpbnRmKHN0ZG91dCwiKTtcbiIpOworCQkJZmZsdXNoKHN0ZG91dCk7CisKKwkJ CWQrKzsKKwkJfQorCX0KKwogCS8qCiAJICogTm93IGJ1aWxkIHRoZSBhY3R1YWwgcmVsY2FjaGUg cGFydGl0aW9uIGRlc2NyaXB0b3IsIGNvcHlpbmcgYWxsIHRoZQogCSAqIGRhdGEgaW50byBhIG5l dywgc21hbGwgY29udGV4dC4gIEFzIHBlciBhYm92ZSBjb21tZW50LCB3ZSBkb24ndCBtYWtlCg== --000000000000228c27064f5dee97--