mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Avoid integer overflow while sifting-up a heap in tuplesort.c.
If the number of tuples in the heap exceeds approximately INT_MAX/2, this loop's calculation "2*i+1" could overflow, resulting in a crash. Fix it by using unsigned int rather than int for the relevant local variables; that shouldn't cost anything extra on any popular hardware. Per bug #14722 from Sergey Koposov. Original patch by Sergey Koposov, modified by me per a suggestion from Heikki Linnakangas to use unsigned int not int64. Back-patch to 9.4, where tuplesort.c grew the ability to sort as many as INT_MAX tuples in-memory (commit 263865a48). Discussion: https://postgr.es/m/20170629161637.1478.93109@wrigleys.postgresql.org
This commit is contained in:
parent
ca906f68f2
commit
512f67c8d0
@ -3490,7 +3490,7 @@ tuplesort_heap_replace_top(Tuplesortstate *state, SortTuple *tuple,
|
||||
bool checkIndex)
|
||||
{
|
||||
SortTuple *memtuples = state->memtuples;
|
||||
int i,
|
||||
unsigned int i,
|
||||
n;
|
||||
|
||||
Assert(!checkIndex || state->currentRun == RUN_FIRST);
|
||||
@ -3498,11 +3498,16 @@ tuplesort_heap_replace_top(Tuplesortstate *state, SortTuple *tuple,
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
/*
|
||||
* state->memtupcount is "int", but we use "unsigned int" for i, j, n.
|
||||
* This prevents overflow in the "2 * i + 1" calculation, since at the top
|
||||
* of the loop we must have i < n <= INT_MAX <= UINT_MAX/2.
|
||||
*/
|
||||
n = state->memtupcount;
|
||||
i = 0; /* i is where the "hole" is */
|
||||
for (;;)
|
||||
{
|
||||
int j = 2 * i + 1;
|
||||
unsigned int j = 2 * i + 1;
|
||||
|
||||
if (j >= n)
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user