public inbox for [email protected]  
help / color / mirror / Atom feed
From: =?gb18030?B?emVuZ21hbg==?= <[email protected]>
To: =?gb18030?B?1PjC+g==?= <[email protected]>
To: =?gb18030?B?cGdzcWwtYnVncw==?= <[email protected]>
Subject: Re:BUG #19492: intarray: fix variable stats leak in _int_matchsel
Date: Sun, 24 May 2026 13:15:43 +0800
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>

Patch attached. Also added a test case that exercises this code path
by creating a text operator with _int_matchsel as the restriction
estimator.

Regards,
Man Zeng

Attachments:

  [application/octet-stream] 0001-Fix-variable-stats-leak-in-_int_matchsel-early-retur.patch (2.7K, 2-0001-Fix-variable-stats-leak-in-_int_matchsel-early-retur.patch)
  download | inline diff:
From 8e5606371df544f8be48937419fe54c96a358048 Mon Sep 17 00:00:00 2001
From: Man Zeng <[email protected]>
Date: Sun, 24 May 2026 12:36:36 +0800
Subject: [PATCH] Fix variable stats leak in _int_matchsel early return path

When vardata.vartype != INT4ARRAYOID, _int_matchsel returns
DEFAULT_EQ_SEL without releasing the variable stats previously
acquired via examine_variable(), causing a memory leak. Add the
missing ReleaseVariableStats() call.
---
 contrib/intarray/_int_selfuncs.c   |  3 +++
 contrib/intarray/expected/_int.out | 21 +++++++++++++++++++++
 contrib/intarray/sql/_int.sql      | 20 ++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/contrib/intarray/_int_selfuncs.c b/contrib/intarray/_int_selfuncs.c
index 7fce743632f..c0161928074 100644
--- a/contrib/intarray/_int_selfuncs.c
+++ b/contrib/intarray/_int_selfuncs.c
@@ -151,7 +151,10 @@ _int_matchsel(PG_FUNCTION_ARGS)
 	 * query_int.
 	 */
 	if (vardata.vartype != INT4ARRAYOID)
+	{
+		ReleaseVariableStats(vardata);
 		PG_RETURN_FLOAT8(DEFAULT_EQ_SEL);
+	}
 
 	/*
 	 * Can't do anything useful if the something is not a constant, either.
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index fb4086a95ca..8ae730a535d 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -1026,3 +1026,24 @@ SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
 (1 row)
 
 RESET enable_seqscan;
+CREATE OR REPLACE FUNCTION my_text_eq(a text, b text) RETURNS boolean AS $$
+BEGIN
+    RETURN a = b;
+END;
+$$ LANGUAGE plpgsql;
+CREATE OPERATOR %% (
+    LEFTARG = text,
+    RIGHTARG = text,
+    FUNCTION = my_text_eq,
+    RESTRICT = _int_matchsel
+);
+CREATE TEMP TABLE test_vuln (t text);
+INSERT INTO test_vuln SELECT md5(i::text) FROM generate_series(1, 1000) i;
+ANALYZE test_vuln;
+SELECT * FROM test_vuln WHERE t %% 'test'::text;
+ t 
+---
+(0 rows)
+
+DROP FUNCTION my_text_eq CASCADE;
+NOTICE:  drop cascades to operator %%(text,text)
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 0d30914725e..765b1138772 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -252,3 +252,23 @@ SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
 
 
 RESET enable_seqscan;
+
+CREATE OR REPLACE FUNCTION my_text_eq(a text, b text) RETURNS boolean AS $$
+BEGIN
+    RETURN a = b;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OPERATOR %% (
+    LEFTARG = text,
+    RIGHTARG = text,
+    FUNCTION = my_text_eq,
+    RESTRICT = _int_matchsel
+);
+
+CREATE TEMP TABLE test_vuln (t text);
+INSERT INTO test_vuln SELECT md5(i::text) FROM generate_series(1, 1000) i;
+ANALYZE test_vuln;
+
+SELECT * FROM test_vuln WHERE t %% 'test'::text;
+DROP FUNCTION my_text_eq CASCADE;
-- 
2.45.2



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: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re:BUG #19492: intarray: fix variable stats leak in _int_matchsel
  In-Reply-To: <[email protected]>

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

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