From 45eb47230d93a652873e9b0f94e2f1b04181a8cc Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Sat, 14 Feb 2026 12:16:16 -0800 Subject: [PATCH] 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) non-local exit discards the pointer in question. pg_mblen_cstr() ordered the checks correctly, but these other two did not. Back-patch to v14, like commit 1e7fe06c10c0a8da9dd6261a6be8d405dc17c728. Reviewed-by: Thomas Munro Discussion: https://postgr.es/m/20260214053821.fa.noahmisch@microsoft.com Backpatch-through: 14 --- src/backend/utils/mb/mbutils.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 345a9d456d4..36bcd9e25a5 100644 --- a/src/backend/utils/mb/mbutils.c +++ b/src/backend/utils/mb/mbutils.c @@ -1085,15 +1085,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; } @@ -1108,15 +1109,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; }