From ffbe37115ad1016e78e59de14c7f86ed8aaefc3e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 5 Oct 2026 15:45:40 -0400 Subject: [PATCH] Handle operator-stack-overflow errors softly in tsquery and ltxtquery. When we converted these types' input functions to report errors through the soft-error mechanism, we missed that stack-overflow errors can be triggered through bad user input. Convert those to be reported softly, too. Bug: #19745 Reported-by: Ke Author: Tom Lane Discussion: https://postgr.es/m/19745-39cd7b93a505f9a9@postgresql.org Backpatch-through: 16 --- contrib/ltree/ltxtquery_io.c | 8 ++++---- src/backend/utils/adt/tsquery.c | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c index 0f2954f31ba..bd5e0096847 100644 --- a/contrib/ltree/ltxtquery_io.c +++ b/contrib/ltree/ltxtquery_io.c @@ -247,9 +247,10 @@ makepol(QPRS_STATE *state) } else { - if (lenstack == STACKDEPTH) - /* internal error */ - elog(ERROR, "stack too short"); + if (lenstack >= STACKDEPTH) + ereturn(state->escontext, ERR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("ltxtquery is too complex"))); stack[lenstack] = val; lenstack++; } @@ -282,7 +283,6 @@ makepol(QPRS_STATE *state) ereturn(state->escontext, ERR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); - } } while (lenstack) diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index 19d9e40ffeb..416cf19f2ca 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -633,10 +633,14 @@ typedef struct OperatorElement } OperatorElement; static void -pushOpStack(OperatorElement *stack, int *lenstack, int8 op, int16 distance) +pushOpStack(TSQueryParserState state, + OperatorElement *stack, int *lenstack, + int8 op, int16 distance) { - if (*lenstack == STACKDEPTH) /* internal error */ - elog(ERROR, "tsquery stack too small"); + if (*lenstack >= STACKDEPTH) + ereturn(state->escontext,, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("tsquery is too complex"))); stack[*lenstack].op = op; stack[*lenstack].distance = distance; @@ -696,7 +700,7 @@ makepol(TSQueryParserState state, break; case PT_OPR: cleanOpStack(state, opstack, &lenstack, operator); - pushOpStack(opstack, &lenstack, operator, weight); + pushOpStack(state, opstack, &lenstack, operator, weight); break; case PT_OPEN: makepol(state, pushval, opaque); @@ -714,7 +718,7 @@ makepol(TSQueryParserState state, state->buffer))); return; } - /* detect soft error in pushval or recursion */ + /* detect soft error in pushval, pushOpStack, or recursion */ if (SOFT_ERROR_OCCURRED(state->escontext)) return; }