You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudberry.apache.org by dj...@apache.org on 2026/05/30 02:03:50 UTC

(cloudberry) 02/27: Fix overflows with ts_headline()

This is an automated email from the ASF dual-hosted git repository.

tuhaihe pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 1a5426fbcc2965d27e944b388fd28c7109954d4c
Author: Michael Paquier <mi...@paquier.xyz>
AuthorDate: Mon May 11 05:13:49 2026 -0700

    Fix overflows with ts_headline()
    
    The options "StartSel", "StopSel" and "FragmentDelimiter" given by a
    caller of the SQL function ts_headline() have their lengths stored as
    int16.  When providing values larger than PG_INT16_MAX, it was possible
    to overflow the length values stored, leading to incorrect behaviors in
    generateHeadline(), in most cases translating to a crash.
    
    Attempting to use values for these options larger than PG_INT16_MAX is
    now blocked.  Some test cases are added to cover our tracks.
    
    Reported-by: Xint Code
    Author: Michael Paquier <mi...@paquier.xyz>
    Backpatch-through: 14
    Security: CVE-2026-6473
---
 src/backend/tsearch/wparser_def.c     | 24 +++++++++++++++++++++---
 src/test/regress/expected/tsearch.out | 10 ++++++++++
 src/test/regress/sql/tsearch.sql      |  8 ++++++++
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c
index fb80fdd63f2..9130b148366 100644
--- a/src/backend/tsearch/wparser_def.c
+++ b/src/backend/tsearch/wparser_def.c
@@ -2626,6 +2626,9 @@ prsd_headline(PG_FUNCTION_ARGS)
 	int			max_fragments = 0;
 	bool		highlightall = false;
 	ListCell   *l;
+	size_t		startsellen;
+	size_t		stopsellen;
+	size_t		fragdelimlen;
 
 	/* Extract configuration option values */
 	prs->startsel = NULL;
@@ -2715,9 +2718,24 @@ prsd_headline(PG_FUNCTION_ARGS)
 		prs->fragdelim = pstrdup(" ... ");
 
 	/* Caller will need these lengths, too */
-	prs->startsellen = strlen(prs->startsel);
-	prs->stopsellen = strlen(prs->stopsel);
-	prs->fragdelimlen = strlen(prs->fragdelim);
+	startsellen = strlen(prs->startsel);
+	stopsellen = strlen(prs->stopsel);
+	fragdelimlen = strlen(prs->fragdelim);
+	if (startsellen > PG_INT16_MAX)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("value for \"%s\" is too long", "StartSel")));
+	if (stopsellen > PG_INT16_MAX)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("value for \"%s\" is too long", "StopSel")));
+	if (fragdelimlen > PG_INT16_MAX)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("value for \"%s\" is too long", "FragmentDelimiter")));
+	prs->startsellen = startsellen;
+	prs->stopsellen = stopsellen;
+	prs->fragdelimlen = fragdelimlen;
 
 	PG_RETURN_POINTER(prs);
 }
diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out
index aa44021e4e4..2331c18ad26 100644
--- a/src/test/regress/expected/tsearch.out
+++ b/src/test/regress/expected/tsearch.out
@@ -2167,6 +2167,16 @@ NOTICE:  text-search query doesn't contain lexemes: ""
  foo bar
 (1 row)
 
+-- Test for large values of StartSel, StopSel and FragmentDelimiter
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'StartSel=' || repeat('x', 32768));
+ERROR:  value for "StartSel" is too long
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'StopSel=' || repeat('x', 32768));
+ERROR:  value for "StopSel" is too long
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'FragmentDelimiter=' || repeat('x', 32768));
+ERROR:  value for "FragmentDelimiter" is too long
 --Rewrite sub system
 CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT);
 \set ECHO none
diff --git a/src/test/regress/sql/tsearch.sql b/src/test/regress/sql/tsearch.sql
index 226a78c996f..7ec5d86e93c 100644
--- a/src/test/regress/sql/tsearch.sql
+++ b/src/test/regress/sql/tsearch.sql
@@ -649,6 +649,14 @@ SELECT ts_headline('english',
 SELECT ts_headline('english',
 'foo bar', to_tsquery('english', ''));
 
+-- Test for large values of StartSel, StopSel and FragmentDelimiter
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'StartSel=' || repeat('x', 32768));
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'StopSel=' || repeat('x', 32768));
+SELECT ts_headline('english', 'foo barbar', to_tsquery('english', 'foo'),
+  'FragmentDelimiter=' || repeat('x', 32768));
+
 --Rewrite sub system
 
 CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org