Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1c74435

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 fixed some nearby problems awhile ago (cf 757c518) but missed this. Report and diagnosis by Alexander Lakhin (bug #18273); patch by me Discussion: https://postgr.es/m/18273-9a832d1da122600c@postgresql.org
1 parent 72d5b27 commit 1c74435

File tree

3 files changed

+15
-12
lines changed

3 files changed

+15
-12
lines changed

contrib/intarray/_int_gist.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
287287
ArrayType *in;
288288
int lenin;
289289
int *din;
290-
int i,
291-
j;
290+
int i;
292291

293292
in = DatumGetArrayTypeP(entry->key);
294293

@@ -332,9 +331,12 @@ g_int_decompress(PG_FUNCTION_ARGS)
332331
dr = ARRPTR(r);
333332

334333
for (i = 0; i < lenin; i += 2)
335-
for (j = din[i]; j <= din[i + 1]; j++)
334+
{
335+
/* use int64 for j in case din[i + 1] is INT_MAX */
336+
for (int64 j = din[i]; j <= din[i + 1]; j++)
336337
if ((!i) || *(dr - 1) != j)
337-
*dr++ = j;
338+
*dr++ = (int) j;
339+
}
338340

339341
if (in != (ArrayType *) DatumGetPointer(entry->key))
340342
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: 8 additions & 8 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
@@ -614,13 +614,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
614614
SELECT count(*) from test__int WHERE a @@ '20 | !21';
615615
count
616616
-------
617-
6566
617+
6567
618618
(1 row)
619619

620620
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
621621
count
622622
-------
623-
6343
623+
6344
624624
(1 row)
625625

626626
DROP INDEX text_idx;
@@ -688,13 +688,13 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
688688
SELECT count(*) from test__int WHERE a @@ '20 | !21';
689689
count
690690
-------
691-
6566
691+
6567
692692
(1 row)
693693

694694
SELECT count(*) from test__int WHERE a @@ '!20 & !21';
695695
count
696696
-------
697-
6343
697+
6344
698698
(1 row)
699699

700700
RESET enable_seqscan;

0 commit comments

Comments
 (0)