pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: pgsql-hackers@lists.postgresql.org
Subject: Residual tsquery cleanups
Date: Sun, 16 Aug 2026 12:21:59 -0400
Message-ID: <455079.1786897319@sss.pgh.pa.us> (raw)

The two attached, pretty trivial patches clean up some loose ends
from the recent tsvector/tsquery security commits.  I'm thinking
of back-patching both, but perhaps there is an argument for not
back-patching the first one?

			regards, tom lane

Attachments:

  [text/x-diff] v1-0001-Tighten-up-tsqueryrecv.patch (1.8K, ../455079.1786897319@sss.pgh.pa.us/2-v1-0001-Tighten-up-tsqueryrecv.patch)
  download | inline diff:
From 5567ea2fb4ba82a5ebe4efaacef58715d95c9216 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 16 Aug 2026 12:08:22 -0400
Subject: [PATCH v1 1/2] Tighten up tsqueryrecv().

tsqueryrecv() accepted zero-length lexemes, which tsqueryin() doesn't.
It also accepted phrase distance values larger than MAXENTRYPOS,
which tsqueryin() doesn't.  While neither of these omissions are
very harmful in themselves, they do allow accepting tsquery values
that will fail in a subsequent textual dump/reload.

Commit 23d9ad771 performed similar tightening of tsvectorrecv(),
but I left off these changes at the time because they didn't seem
to have security implications.

Reported-by: Claude Code (via Noah Misch)
Author: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 14
---
 src/backend/utils/adt/tsquery.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 3247d5db082..df26fc2a139 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -1272,6 +1272,9 @@ tsqueryrecv(PG_FUNCTION_ARGS)
 			if (weight > 0xF)
 				elog(ERROR, "invalid tsquery: invalid weight bitmap");
 
+			if (val_len == 0)
+				elog(ERROR, "invalid tsquery: empty operand");
+
 			if (val_len > MAXSTRLEN)
 				elog(ERROR, "invalid tsquery: operand too long");
 
@@ -1311,7 +1314,14 @@ tsqueryrecv(PG_FUNCTION_ARGS)
 
 			item->qoperator.oper = oper;
 			if (oper == OP_PHRASE)
-				item->qoperator.distance = (int16) pq_getmsgint(buf, sizeof(int16));
+			{
+				unsigned int dist = pq_getmsgint(buf, sizeof(int16));
+
+				if (dist > MAXENTRYPOS)
+					elog(ERROR, "invalid tsquery: invalid phrase distance %d",
+						 dist);
+				item->qoperator.distance = (int16) dist;
+			}
 		}
 		else
 			elog(ERROR, "unrecognized tsquery node type: %d", item->type);
-- 
2.52.0

  [text/x-diff] v1-0002-Clean-up-documentation-about-text-search-datatype.patch (2.5K, ../455079.1786897319@sss.pgh.pa.us/3-v1-0002-Clean-up-documentation-about-text-search-datatype.patch)
  download | inline diff:
From 40adfc381b50c29014d05ee497c424a8ee7ac533 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 16 Aug 2026 12:15:26 -0400
Subject: [PATCH v1 2/2] Clean up documentation about text search datatype
 limits.

textsearch.sgml neglected to mention that the MAXSTRPOS total-length
limit applies to tsquery as well as tsvector.  It also claims that
there is a 32K limit on the total number of nodes in a tsquery, which
is wrong.  (I suspect that QueryOperator.left may once have been
int16, which would give rise to such a limit.  But it's uint32 now,
so you'd hit the 1GB varlena limit well before overflowing that.)

While at it, re-order the bullet points into an order that makes
more sense, to me anyway.

Reported-by: Claude Code (via Noah Misch)
Author: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 14
---
 doc/src/sgml/textsearch.sgml | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml
index d6d2ddeaacc..2f3a76bef1e 100644
--- a/doc/src/sgml/textsearch.sgml
+++ b/doc/src/sgml/textsearch.sgml
@@ -4046,24 +4046,24 @@ Parser: "pg_catalog.default"
      <para>The length of each lexeme must be less than 2 kilobytes</para>
     </listitem>
     <listitem>
-     <para>The length of a <type>tsvector</type> (lexemes + positions) must be
-     less than 1 megabyte</para>
+     <para>No more than 256 positions per lexeme</para>
     </listitem>
     <listitem>
      <para>Position values in <type>tsvector</type> must be greater than 0 and
      no more than 16,383</para>
     </listitem>
     <listitem>
-     <para>The match distance in a <literal>&lt;<replaceable>N</replaceable>&gt;</literal>
-     (FOLLOWED BY) <type>tsquery</type> operator cannot be more than
-     16,384</para>
+     <para>The length of a <type>tsvector</type>'s data (lexemes + positions)
+     must be less than 1 megabyte</para>
     </listitem>
     <listitem>
-     <para>No more than 256 positions per lexeme</para>
+     <para>The length of a <type>tsquery</type>'s data (lexemes only)
+     must be less than 1 megabyte</para>
     </listitem>
     <listitem>
-     <para>The number of nodes (lexemes + operators) in a <type>tsquery</type>
-     must be less than 32,768</para>
+     <para>The match distance in a <literal>&lt;<replaceable>N</replaceable>&gt;</literal>
+     (FOLLOWED BY) <type>tsquery</type> operator cannot be more than
+     16,384</para>
     </listitem>
    </itemizedlist>
   </para>
-- 
2.52.0

view thread (3+ messages)  latest in thread

Message-ID: <455079.1786897319@sss.pgh.pa.us>
Permalink:  ../455079.1786897319@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/455079.1786897319@sss.pgh.pa.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: tgl@sss.pgh.pa.us, pgsql-hackers@lists.postgresql.org
  Subject: Re: Residual tsquery cleanups
  In-Reply-To: <455079.1786897319@sss.pgh.pa.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox