@@ -486,18 +486,41 @@ ginHeapTupleFastCollect(GinState *ginstate,
486
486
entries = ginExtractEntries (ginstate , attnum , value , isNull ,
487
487
& nentries , & categories );
488
488
489
+ /*
490
+ * Protect against integer overflow in allocation calculations
491
+ */
492
+ if (nentries < 0 ||
493
+ collector -> ntuples + nentries > MaxAllocSize / sizeof (IndexTuple ))
494
+ elog (ERROR , "too many entries for GIN index" );
495
+
489
496
/*
490
497
* Allocate/reallocate memory for storing collected tuples
491
498
*/
492
499
if (collector -> tuples == NULL )
493
500
{
494
- collector -> lentuples = nentries * ginstate -> origTupdesc -> natts ;
501
+ /*
502
+ * Determine the number of elements to allocate in the tuples array
503
+ * initially. Make it a power of 2 to avoid wasting memory when
504
+ * resizing (since palloc likes powers of 2).
505
+ */
506
+ collector -> lentuples = 16 ;
507
+ while (collector -> lentuples < nentries )
508
+ collector -> lentuples *= 2 ;
509
+
495
510
collector -> tuples = (IndexTuple * ) palloc (sizeof (IndexTuple ) * collector -> lentuples );
496
511
}
497
-
498
- while (collector -> ntuples + nentries > collector -> lentuples )
512
+ else if (collector -> lentuples < collector -> ntuples + nentries )
499
513
{
500
- collector -> lentuples *= 2 ;
514
+ /*
515
+ * Advance lentuples to the next suitable power of 2. This won't
516
+ * overflow, though we could get to a value that exceeds
517
+ * MaxAllocSize/sizeof(IndexTuple), causing an error in repalloc.
518
+ */
519
+ do
520
+ {
521
+ collector -> lentuples *= 2 ;
522
+ } while (collector -> lentuples < collector -> ntuples + nentries );
523
+
501
524
collector -> tuples = (IndexTuple * ) repalloc (collector -> tuples ,
502
525
sizeof (IndexTuple ) * collector -> lentuples );
503
526
}
0 commit comments