Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9e7432f

Browse files
committed
Fix integer-overflow problem in intarray's g_int_decompress().
An array element equal to INT_MAX gave this code indigestion,causing an infinite loop that surely ended in SIGSEGV. We fixedsome nearby problems awhile ago (cf757c518) but missed this.Report and diagnosis by Alexander Lakhin (bug #18273); patch by meDiscussion:https://postgr.es/m/18273-9a832d1da122600c@postgresql.org
1 parent60de25c commit9e7432f

File tree

4 files changed

+27
-22
lines changed

4 files changed

+27
-22
lines changed

‎contrib/intarray/_int_gist.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
290290
ArrayType*in;
291291
intlenin;
292292
int*din;
293-
inti,
294-
j;
293+
inti;
295294

296295
in=DatumGetArrayTypeP(entry->key);
297296

@@ -335,9 +334,12 @@ g_int_decompress(PG_FUNCTION_ARGS)
335334
dr=ARRPTR(r);
336335

337336
for (i=0;i<lenin;i+=2)
338-
for (j=din[i];j <=din[i+1];j++)
337+
{
338+
/* use int64 for j in case din[i + 1] is INT_MAX */
339+
for (int64j=din[i];j <=din[i+1];j++)
339340
if ((!i)||*(dr-1)!=j)
340-
*dr++=j;
341+
*dr++= (int)j;
342+
}
341343

342344
if (in!= (ArrayType*)DatumGetPointer(entry->key))
343345
pfree(in);

‎contrib/intarray/data/test__int.data

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6998,3 +6998,4 @@
69986998
{173,208,229}
69996999
{6,22,142,267,299}
70007000
{22,122,173,245,293}
7001+
{1,2,101,102,201,202,2147483647}

‎contrib/intarray/expected/_int.out

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -464,13 +464,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
464464
SELECT count(*) from test__int WHERE a @@ '20 | !21';
465465
count
466466
-------
467-
6566
467+
6567
468468
(1 row)
469469

470470
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
471471
count
472472
-------
473-
6343
473+
6344
474474
(1 row)
475475

476476
SET enable_seqscan = off; -- not all of these would use index by default
@@ -538,13 +538,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
538538
SELECT count(*) from test__int WHERE a @@ '20 | !21';
539539
count
540540
-------
541-
6566
541+
6567
542542
(1 row)
543543

544544
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
545545
count
546546
-------
547-
6343
547+
6344
548548
(1 row)
549549

550550
INSERT INTO test__int SELECT array(SELECT x FROM generate_series(1, 1001) x); -- should fail
@@ -620,13 +620,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
620620
SELECT count(*) from test__int WHERE a @@ '20 | !21';
621621
count
622622
-------
623-
6566
623+
6567
624624
(1 row)
625625

626626
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
627627
count
628628
-------
629-
6343
629+
6344
630630
(1 row)
631631

632632
DROP INDEX text_idx;
@@ -700,13 +700,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
700700
SELECT count(*) from test__int WHERE a @@ '20 | !21';
701701
count
702702
-------
703-
6566
703+
6567
704704
(1 row)
705705

706706
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
707707
count
708708
-------
709-
6343
709+
6344
710710
(1 row)
711711

712712
DROP INDEX text_idx;
@@ -774,13 +774,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
774774
SELECT count(*) from test__int WHERE a @@ '20 | !21';
775775
count
776776
-------
777-
6566
777+
6567
778778
(1 row)
779779

780780
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
781781
count
782782
-------
783-
6343
783+
6344
784784
(1 row)
785785

786786
DROP INDEX text_idx;
@@ -848,13 +848,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
848848
SELECT count(*) from test__int WHERE a @@ '20 | !21';
849849
count
850850
-------
851-
6566
851+
6567
852852
(1 row)
853853

854854
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
855855
count
856856
-------
857-
6343
857+
6344
858858
(1 row)
859859

860860
DROP INDEX text_idx;
@@ -870,9 +870,10 @@ DROP INDEX text_idx;
870870
-- core that would reach the same codepaths.
871871
CREATE TABLE more__int AS SELECT
872872
-- Leave alone NULLs, empty arrays and the one row that we use to test
873-
-- equality
873+
-- equality; also skip INT_MAX
874874
CASE WHEN a IS NULL OR a = '{}' OR a = '{73,23,20}' THEN a ELSE
875-
(select array_agg(u) || array_agg(u + 1000) || array_agg(u + 2000) from (select unnest(a) u) x)
875+
(select array_agg(u) || array_agg(u + 1000) || array_agg(u + 2000)
876+
from unnest(a) u where u < 2000000000)
876877
END AS a, a as b
877878
FROM test__int;
878879
CREATE INDEX ON more__int using gist (a gist__int_ops(numranges = 252));
@@ -939,13 +940,13 @@ SELECT count(*) from more__int WHERE a @@ '(20&23)|(50&68)';
939940
SELECT count(*) from more__int WHERE a @@ '20 | !21';
940941
count
941942
-------
942-
6566
943+
6567
943944
(1 row)
944945

945946
SELECT count(*) from more__int WHERE a @@ '!20 & !21';
946947
count
947948
-------
948-
6343
949+
6344
949950
(1 row)
950951

951952
RESET enable_seqscan;

‎contrib/intarray/sql/_int.sql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,10 @@ DROP INDEX text_idx;
194194
-- core that would reach the same codepaths.
195195
CREATETABLEmore__intASSELECT
196196
-- Leave alone NULLs, empty arrays and the one row that we use to test
197-
-- equality
197+
-- equality; also skip INT_MAX
198198
CASE WHEN a ISNULLOR a='{}'OR a='{73,23,20}' THEN a ELSE
199-
(select array_agg(u)|| array_agg(u+1000)|| array_agg(u+2000)from (select unnest(a) u) x)
199+
(select array_agg(u)|| array_agg(u+1000)|| array_agg(u+2000)
200+
from unnest(a) uwhere u<2000000000)
200201
ENDAS a, aas b
201202
FROM test__int;
202203
CREATEINDEXON more__int using gist (a gist__int_ops(numranges=252));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp