v2-0001-Fix-signed-integer-overflow-in-nodeWindowAgg.c.patch
application/octet-stream
Filename: v2-0001-Fix-signed-integer-overflow-in-nodeWindowAgg.c.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Fix signed integer overflow in nodeWindowAgg.c
| File | + | − |
|---|---|---|
| src/backend/executor/nodeWindowAgg.c | 49 | 5 |
From 9589510f4e284ef4ee9f0a95fac572aced43cbe7 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Sat, 14 Feb 2026 18:16:27 +0900
Subject: [PATCH v2] Fix signed integer overflow in nodeWindowAgg.c
---
src/backend/executor/nodeWindowAgg.c | 54 +++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index d9b64b0f465..dab057df0bd 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -37,6 +37,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
+#include "common/int.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
#include "miscadmin.h"
@@ -1532,12 +1533,17 @@ row_is_in_frame(WindowObject winobj, int64 pos, TupleTableSlot *slot,
if (frameOptions & FRAMEOPTION_ROWS)
{
int64 offset = DatumGetInt64(winstate->endOffsetValue);
+ int64 target_pos;
/* rows after current row + offset are out of frame */
if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)
offset = -offset;
- if (pos > winstate->currentpos + offset)
+ if (pg_add_s64_overflow(winstate->currentpos, offset, &target_pos))
+ {
+ /* overflow: frame extends to end of partition */
+ }
+ else if (pos > target_pos)
return -1;
}
else if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS))
@@ -1672,7 +1678,16 @@ update_frameheadpos(WindowAggState *winstate)
if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING)
offset = -offset;
- winstate->frameheadpos = winstate->currentpos + offset;
+ /*
+ * If we have an overflow, it means the frame head is beyond the
+ * range of int64. Since currentpos >= 0, this can only be a
+ * positive overflow. We treat this as being beyond end of
+ * partition.
+ */
+ if (pg_add_s64_overflow(winstate->currentpos, offset,
+ &winstate->frameheadpos))
+ winstate->frameheadpos = PG_INT64_MAX;
+
/* frame head can't go before first row */
if (winstate->frameheadpos < 0)
winstate->frameheadpos = 0;
@@ -1789,7 +1804,16 @@ update_frameheadpos(WindowAggState *winstate)
if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING)
minheadgroup = winstate->currentgroup - offset;
else
- minheadgroup = winstate->currentgroup + offset;
+ {
+ /*
+ * If we have an overflow, it means the target group is beyond
+ * the range of int64. We treat this as "infinity", which
+ * ensures the loop below advances to end of partition.
+ */
+ if (pg_add_s64_overflow(winstate->currentgroup, offset,
+ &minheadgroup))
+ minheadgroup = PG_INT64_MAX;
+ }
tuplestore_select_read_pointer(winstate->buffer,
winstate->framehead_ptr);
@@ -1926,7 +1950,18 @@ update_frametailpos(WindowAggState *winstate)
if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)
offset = -offset;
- winstate->frametailpos = winstate->currentpos + offset + 1;
+ /*
+ * If we have an overflow, it means the frame tail is beyond the
+ * range of int64. Since currentpos >= 0, this can only be a
+ * positive overflow. We treat this as being beyond end of
+ * partition.
+ */
+ if (pg_add_s64_overflow(winstate->currentpos, offset,
+ &winstate->frametailpos) ||
+ pg_add_s64_overflow(winstate->frametailpos, 1,
+ &winstate->frametailpos))
+ winstate->frametailpos = PG_INT64_MAX;
+
/* smallest allowable value of frametailpos is 0 */
if (winstate->frametailpos < 0)
winstate->frametailpos = 0;
@@ -2043,7 +2078,16 @@ update_frametailpos(WindowAggState *winstate)
if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)
maxtailgroup = winstate->currentgroup - offset;
else
- maxtailgroup = winstate->currentgroup + offset;
+ {
+ /*
+ * If we have an overflow, it means the target group is beyond
+ * the range of int64. We treat this as "infinity", which
+ * ensures the loop below advances to end of partition.
+ */
+ if (pg_add_s64_overflow(winstate->currentgroup, offset,
+ &maxtailgroup))
+ maxtailgroup = PG_INT64_MAX;
+ }
tuplestore_select_read_pointer(winstate->buffer,
winstate->frametail_ptr);
--
2.39.5 (Apple Git-154)