If case_sensitive is false and str_tolower() changes the byte length of
the string, then outlen will be incorrect.
Fortunately, pnstrdup() also stops at a NUL terminator, so it will
never overrun; but if outlen is calculated to be too small, then it
could cause truncation. In any case, the input comes from a trusted
source (dictionary configuration), so it's not very serious.
The correct value of outlen is strlen(d->syn[cur].out). But it's only
ever used in one place, which is a call to pnstrdup(). Given that the
string is NUL-terminated anyway, it's easier to fix it by just changing
that to a pstrdup(). Patch attached, backpatch all the way.
Regards,
Jeff Davis
From cc395fca68100d8bd354edab2ee93251285c943a Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Wed, 15 Apr 2026 12:56:31 -0700
Subject: [PATCH v1] dict_synonym.c: remove incorrect outlen.
Previously, outlen was miscalculated if case_sensitive was false and
str_tolower() changed the byte length of the string. If outlen was too
large, pnstrdup() would stop at the NUL terminator, preventing
overrun. But if outlen was too small, it would cause truncation,
possibly in the middle of a multibyte sequence.
Fix by just removing outlen. Both strings are NUL-terminated anyway.
Backpatch-through: 14
---
src/backend/tsearch/dict_synonym.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/backend/tsearch/dict_synonym.c b/src/backend/tsearch/dict_synonym.c
index 3937f25bcc6..24345767658 100644
--- a/src/backend/tsearch/dict_synonym.c
+++ b/src/backend/tsearch/dict_synonym.c
@@ -24,7 +24,6 @@ typedef struct
{
char *in;
char *out;
- int outlen;
uint16 flags;
} Syn;
@@ -189,7 +188,6 @@ dsynonym_init(PG_FUNCTION_ARGS)
d->syn[cur].out = str_tolower(starto, strlen(starto), DEFAULT_COLLATION_OID);
}
- d->syn[cur].outlen = strlen(starto);
d->syn[cur].flags = flags;
cur++;
@@ -237,7 +235,7 @@ dsynonym_lexize(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(NULL);
res = palloc0_array(TSLexeme, 2);
- res[0].lexeme = pnstrdup(found->out, found->outlen);
+ res[0].lexeme = pstrdup(found->out);
res[0].flags = found->flags;
PG_RETURN_POINTER(res);
--
2.43.0