Restore old pgwin32_message_to_UTF16() behavior outside transactions.
authorNoah Misch <noah@leadboat.com>
Sat, 15 Aug 2015 00:23:09 +0000 (20:23 -0400)
committerNoah Misch <noah@leadboat.com>
Sat, 15 Aug 2015 00:23:09 +0000 (20:23 -0400)
Commit 49c817eab78c6f0ce8c3bf46766b73d6cf3190b7 replaced with a hard
error the dubious pg_do_encoding_conversion() behavior when outside a
transaction.  Reintroduce the historic soft failure locally within
pgwin32_message_to_UTF16().  This fixes errors when writing messages in
less-common encodings to the Windows event log or console.  Back-patch
to 9.4, where the aforementioned commit first appeared.

Per bug #13427 from Dmitri Bourlatchkov.

src/backend/utils/mb/mbutils.c

index 1e9a004b0d73e21b4fc0f70789e9ad36bd29bdc5..2a8271ab0725042f163b3907c278dfff9c32f327 100644 (file)
@@ -1063,7 +1063,8 @@ pgwin32_message_to_UTF16(const char *str, int len, int *utf16len)
 
        /*
         * Use MultiByteToWideChar directly if there is a corresponding codepage,
-        * or double conversion through UTF8 if not.
+        * or double conversion through UTF8 if not.  Double conversion is needed,
+        * for example, in an ENCODING=LATIN8, LC_CTYPE=C database.
         */
        if (codepage != 0)
        {
@@ -1075,12 +1076,21 @@ pgwin32_message_to_UTF16(const char *str, int len, int *utf16len)
        {
                char       *utf8;
 
-               utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
-                                                                                                 len,
-                                                                                                 GetMessageEncoding(),
-                                                                                                 PG_UTF8);
-               if (utf8 != str)
-                       len = strlen(utf8);
+               /*
+                * XXX pg_do_encoding_conversion() requires a transaction.  In the
+                * absence of one, hope for the input to be valid UTF8.
+                */
+               if (IsTransactionState())
+               {
+                       utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
+                                                                                                         len,
+                                                                                                         GetMessageEncoding(),
+                                                                                                         PG_UTF8);
+                       if (utf8 != str)
+                               len = strlen(utf8);
+               }
+               else
+                       utf8 = (char *) str;
 
                utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
                dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len);