summaryrefslogtreecommitdiffstats
path: root/generic/tclStubInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclStubInit.c')
-rw-r--r--generic/tclStubInit.c20
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 *