From: Heikki Linnakangas Date: Mon, 1 Feb 2021 17:30:19 +0200 Subject: [PATCH v3 4/5] Fix bugs in the commit to change conversion function signature. Per John Naylor's report, and some bugs I found while testing. TODO: to be squashed. --- src/backend/utils/mb/conv.c | 16 ++++++---------- .../utf8_and_iso8859_1/utf8_and_iso8859_1.c | 8 ++++++++ src/backend/utils/mb/mbutils.c | 5 +++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/mb/conv.c b/src/backend/utils/mb/conv.c index b83358bc7a5..f3bda5753d0 100644 --- a/src/backend/utils/mb/conv.c +++ b/src/backend/utils/mb/conv.c @@ -497,7 +497,6 @@ UtfToLocal(const unsigned char *utf, int len, int l; const pg_utf_to_local_combined *cp; const unsigned char *start = utf; - const unsigned char *cur = utf; if (!PG_VALID_ENCODING(encoding)) ereport(ERROR, @@ -511,8 +510,6 @@ UtfToLocal(const unsigned char *utf, int len, unsigned char b3 = 0; unsigned char b4 = 0; - cur = iso; - /* "break" cases all represent errors */ if (*utf == '\0') break; @@ -648,10 +645,11 @@ UtfToLocal(const unsigned char *utf, int len, } /* failed to translate this character */ + utf -= l; if (noError) break; report_untranslatable_char(PG_UTF8, encoding, - (const char *) (utf - l), len); + (const char *) utf, len); } /* if we broke out of loop early, must be invalid input */ @@ -660,7 +658,7 @@ UtfToLocal(const unsigned char *utf, int len, *iso = '\0'; - return cur - start; + return utf - start; } /* @@ -701,7 +699,6 @@ LocalToUtf(const unsigned char *iso, int len, int l; const pg_local_to_utf_combined *cp; const unsigned char *start = iso; - const unsigned char *cur = iso; if (!PG_VALID_ENCODING(encoding)) ereport(ERROR, @@ -715,8 +712,6 @@ LocalToUtf(const unsigned char *iso, int len, unsigned char b3 = 0; unsigned char b4 = 0; - cur = iso; - /* "break" cases all represent errors */ if (*iso == '\0') break; @@ -799,10 +794,11 @@ LocalToUtf(const unsigned char *iso, int len, } /* failed to translate this character */ + iso -= l; if (noError) break; report_untranslatable_char(encoding, PG_UTF8, - (const char *) (iso - l), len); + (const char *) iso, len); } /* if we broke out of loop early, must be invalid input */ @@ -811,5 +807,5 @@ LocalToUtf(const unsigned char *iso, int len, *utf = '\0'; - return cur - start; + return iso - start; } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c index 8ac93604a1b..d0dc4cca378 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c @@ -104,10 +104,18 @@ utf8_to_iso8859_1(PG_FUNCTION_ARGS) int l = pg_utf_mblen(src); if (l > len || !pg_utf8_islegal(src, l)) + { + if (noError) + break; report_invalid_encoding(PG_UTF8, (const char *) src, len); + } if (l != 2) + { + if (noError) + break; report_untranslatable_char(PG_UTF8, PG_LATIN1, (const char *) src, len); + } c1 = src[1] & 0x3f; c = ((c & 0x1f) << 6) | c1; if (c >= 0x80 && c <= 0xff) diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 3e106027d75..af1cafe523a 100644 --- a/src/backend/utils/mb/mbutils.c +++ b/src/backend/utils/mb/mbutils.c @@ -818,12 +818,13 @@ perform_default_encoding_conversion(const char *src, int len, MemoryContextAllocHuge(CurrentMemoryContext, (Size) len * MAX_CONVERSION_GROWTH + 1); - FunctionCall5(flinfo, + FunctionCall6(flinfo, Int32GetDatum(src_encoding), Int32GetDatum(dest_encoding), CStringGetDatum(src), CStringGetDatum(result), - Int32GetDatum(len)); + Int32GetDatum(len), + BoolGetDatum(false)); /* * Release extra space if there might be a lot --- see comments in -- 2.29.2 --------------39E46EF15EBFAA37D53332E5 Content-Type: text/x-patch; charset=UTF-8; name="v3-0005-Do-COPY-FROM-encoding-conversion-verification-in-.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="v3-0005-Do-COPY-FROM-encoding-conversion-verification-in-.pa"; filename*1="tch"