diff options
Diffstat (limited to 'generic/tclStubInit.c')
| -rw-r--r-- | generic/tclStubInit.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 843e029..d9f1159 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -110,17 +110,31 @@ Tcl_WinUtfToTChar( size_t len, Tcl_DString *dsPtr) { - WCHAR *wp; + WCHAR *wp, *p; int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); Tcl_DStringInit(dsPtr); Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (WCHAR *)Tcl_DStringValue(dsPtr); + p = wp = (WCHAR *)Tcl_DStringValue(dsPtr); MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); if (len == (size_t)-1) --size; /* account for 0-byte at string end */ + + /* It turns out that MultiByteToWideChar() cannot handle the 'modified' + * UTF-8 as used by Tcl. Every sequence of 0xC0 followed by 0x80 will + * be translated to two 0xfffd characters. This results in a test-failure + * of the registry-6.20 test-case. The simplest solution is to search for + * those two 0xfffd characters and replace them by a \u0000 character. */ + while (p < wp + size - 1) { + if (p[0] == 0xfffd && p[1] == 0xfffd) { + memmove(p+1, p+2, sizeof(WCHAR) * (p - wp + size - 2)); + p[0] = 0; + ++p; --size; + } + ++p; + } Tcl_DStringSetLength(dsPtr, 2*size); wp[size] = 0; - return (char *)wp; + return (char *) wp; } char * |
