From: Noah Misch 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; }