mblen-valgrind-after-report-v1.patch

text/plain

Filename: mblen-valgrind-after-report-v1.patch
Type: text/plain
Part: 1
Message: Re: BUG #19406: substring(text) fails on valid UTF-8 toasted value in PostgreSQL 15.16

Patch

Format: unified
Series: patch v1
File+
src/backend/utils/mb/mbutils.c 8 6
From: Noah Misch <noah@leadboat.com>

pg_mblen_range, pg_mblen_with_len: Valgrind after encoding ereport.

The prior order caused spurious Valgrind errors.  They're spurious
because the ereport(ERROR) stops subsequent code from accessing the
memory in question.  pg_mblen_cstr() ordered the checks correctly, but
these other two did not.  Back-patch to v14, like commit
1e7fe06c10c0a8da9dd6261a6be8d405dc17c728.

Reviewed-by: FIXME
Discussion: https://postgr.es/m/FIXME
Backpatch-through: 14

diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index a5a7348..f3f94d4 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -1086,15 +1086,16 @@ pg_mblen_range(const char *mbstr, const char *end)
 	int			length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr);
 
 	Assert(end > mbstr);
+
+	if (unlikely(mbstr + length > end))
+		report_invalid_encoding_db(mbstr, length, end - mbstr);
+
 #ifdef VALGRIND_EXPENSIVE
 	VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, end - mbstr);
 #else
 	VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, length);
 #endif
 
-	if (unlikely(mbstr + length > end))
-		report_invalid_encoding_db(mbstr, length, end - mbstr);
-
 	return length;
 }
 
@@ -1109,15 +1110,16 @@ pg_mblen_with_len(const char *mbstr, int limit)
 	int			length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr);
 
 	Assert(limit >= 1);
+
+	if (unlikely(length > limit))
+		report_invalid_encoding_db(mbstr, length, limit);
+
 #ifdef VALGRIND_EXPENSIVE
 	VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, limit);
 #else
 	VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, length);
 #endif
 
-	if (unlikely(length > limit))
-		report_invalid_encoding_db(mbstr, length, limit);
-
 	return length;
 }