From d5c5eb7b1795eecdae73dbb23df7c12bbddc3a36 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Tue, 7 Apr 2026 13:31:44 +0900 Subject: [PATCH] Guard against int64 overflow in RPR bounded frame end computation --- src/backend/executor/execRPR.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 60f0d8b2fa1..ee4c67c9597 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -22,6 +22,7 @@ */ #include "postgres.h" +#include "common/int.h" #include "executor/execRPR.h" #include "executor/executor.h" #include "miscadmin.h" @@ -1046,10 +1047,11 @@ * * When the frame is bounded (e.g., ROWS BETWEEN CURRENT ROW AND 5 * FOLLOWING), ExecRPRProcessRow receives hasLimitedFrame=true and - * frameOffset indicating the upper bound. After the advance phase, + * frameOffset indicating the upper bound. Before the match phase, * any context whose match has exceeded the frame boundary - * (currentPos - matchStartRow >= frameOffset + 1) is finalized early. - * This prevents matches from extending beyond the window frame. + * (currentPos >= matchStartRow + frameOffset + 1) is finalized early + * by forcing a mismatch. This prevents matches from extending beyond + * the window frame. The sum is clamped to PG_INT64_MAX on overflow. * * Note that bounded frames also disable context absorption at the * planner level (see VIII-3(b)), since the frame boundary breaks the @@ -3154,7 +3156,12 @@ ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, /* Check frame boundary - finalize if exceeded */ if (hasLimitedFrame) { - int64 ctxFrameEnd = ctx->matchStartRow + frameOffset + 1; + int64 ctxFrameEnd; + + /* Clamp to INT64_MAX on overflow */ + if (pg_add_s64_overflow(ctx->matchStartRow, frameOffset + 1, + &ctxFrameEnd)) + ctxFrameEnd = PG_INT64_MAX; if (currentPos >= ctxFrameEnd) { @@ -3204,6 +3211,7 @@ ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, * context here must be within its frame boundary. */ Assert(!hasLimitedFrame || + ctx->matchStartRow > PG_INT64_MAX - frameOffset - 1 || currentPos < ctx->matchStartRow + frameOffset + 1); nfa_advance(winstate, ctx, currentPos); -- 2.50.1 (Apple Git-155)