From a68beda425a0471230f39ef9852d5dffc38ee7c1 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 13 Aug 2026 11:20:27 -0400 Subject: [PATCH] Consistently enforce tsvector/tsquery maximum lengths. Some places rejected individual tokens longer than MAXSTRLEN, while others rejected ones longer than MAXSTRLEN-1. The data structure is perfectly capable of handling MAXSTRLEN, so there's nothing wrong with using the looser bound. Moreover, as things stand there is a dump/reload hazard: some code paths permit construction of a tsvector or tsquery that would later be rejected by tsvectorin or tsqueryin. So standardize on using MAXSTRLEN. Identical remarks apply to MAXSTRPOS (the total data length), so fix that too. Back-patch, in hopes of avoiding cases where a value acceptable to one supported release is not acceptable to another. Author: Tom Lane Reviewed-by: Zsolt Parragi Discussion: https://postgr.es/m/CAN4CZFNYQo4zfbRR435uD0vSfuy5y7dnFOXDfKr9zYoL1JnAxA@mail.gmail.com Backpatch-through: 14 --- src/backend/tsearch/ts_parse.c | 4 ++-- src/backend/utils/adt/tsquery.c | 6 +++--- src/backend/utils/adt/tsvector.c | 4 ++-- src/backend/utils/adt/tsvector_op.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c index 6f04d1d25a6..b6f3482bfff 100644 --- a/src/backend/tsearch/ts_parse.c +++ b/src/backend/tsearch/ts_parse.c @@ -379,7 +379,7 @@ parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen) PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); - if (type > 0 && lenlemm >= MAXSTRLEN) + if (type > 0 && lenlemm > MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, @@ -582,7 +582,7 @@ hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int bu PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); - if (type > 0 && lenlemm >= MAXSTRLEN) + if (type > 0 && lenlemm > MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index de899a600ae..546fc093d9e 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -548,12 +548,12 @@ pushValue_internal(TSQueryParserState state, pg_crc32 valcrc, int distance, int { QueryOperand *tmp; - if (distance >= MAXSTRPOS) + if (distance > MAXSTRPOS) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("value is too big in tsquery: \"%s\"", state->buffer))); - if (lenval >= MAXSTRLEN) + if (lenval > MAXSTRLEN) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("operand is too long in tsquery: \"%s\"", @@ -581,7 +581,7 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool { pg_crc32 valcrc; - if (lenval >= MAXSTRLEN) + if (lenval > MAXSTRLEN) ereturn(state->escontext,, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long in tsquery: \"%s\"", diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c index dae8b577cfa..e9c1e898c19 100644 --- a/src/backend/utils/adt/tsvector.c +++ b/src/backend/utils/adt/tsvector.c @@ -207,12 +207,12 @@ tsvectorin(PG_FUNCTION_ARGS) while (gettoken_tsvector(state, &token, &toklen, &pos, &poslen, NULL)) { - if (toklen >= MAXSTRLEN) + if (toklen > MAXSTRLEN) ereturn(escontext, (Datum) 0, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long (%ld bytes, max %ld bytes)", (long) toklen, - (long) (MAXSTRLEN - 1)))); + (long) MAXSTRLEN))); if (cur - tmpbuf > MAXSTRPOS) ereturn(escontext, (Datum) 0, diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 1c46cfde0ac..3eb4470294f 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -775,12 +775,12 @@ array_to_tsvector(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING), errmsg("lexeme array may not contain empty strings"))); - if (toklen >= MAXSTRLEN) + if (toklen > MAXSTRLEN) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long (%d bytes, max %d bytes)", toklen, - MAXSTRLEN - 1))); + MAXSTRLEN))); } /* Sort and de-dup, because this is required for a valid tsvector. */