summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2018-09-22 10:09:23 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2018-09-22 10:09:23 (GMT)
commitdf89a7f2110fcd0e00738488b7c9e54f7357feb3 (patch)
tree0960da87f0f1d56ed3bff73edc4a4630c2f7df30
parentbd42171094d5ada2e2e46978f2e842a66b6fa44e (diff)
downloadtcl-df89a7f2110fcd0e00738488b7c9e54f7357feb3.zip
tcl-df89a7f2110fcd0e00738488b7c9e54f7357feb3.tar.gz
tcl-df89a7f2110fcd0e00738488b7c9e54f7357feb3.tar.bz2
Prevent possible build order problem, due to missing dde/registry dll's.
Make sure that Tcl_WinTChar2Utf() never produces intermediate null-bytes.
-rw-r--r--generic/tclStubInit.c17
-rw-r--r--win/Makefile.in2
-rw-r--r--win/tclWin32Dll.c17
3 files changed, 27 insertions, 9 deletions
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 134b68f..cb33288 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -242,7 +242,7 @@ Tcl_WinUtfToTChar(
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[0] = '\0';
++p; --size;
}
++p;
@@ -258,7 +258,7 @@ Tcl_WinTCharToUtf(
int len,
Tcl_DString *dsPtr)
{
- char *p;
+ char *p, *r;
int size;
if (len > 0) {
@@ -266,10 +266,19 @@ Tcl_WinTCharToUtf(
}
size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL);
Tcl_DStringInit(dsPtr);
- Tcl_DStringSetLength(dsPtr, size+1);
- p = (char *)Tcl_DStringValue(dsPtr);
+ Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */
+ r = p = (char *)Tcl_DStringValue(dsPtr);
WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL);
if (len == -1) --size; /* account for 0-byte at string end */
+ while (r < p+size) {
+ if (!*r) {
+ /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */
+ memmove(r+2, r+1, p-r+size-1);
+ memcpy(r++, "\xC0\x80", 2);
+ Tcl_DStringSetLength(dsPtr, ++size + 1);
+ }
+ ++r;
+ }
Tcl_DStringSetLength(dsPtr, size);
p[size] = 0;
return p;
diff --git a/win/Makefile.in b/win/Makefile.in
index b5095e7..3e117d1 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -482,7 +482,7 @@ doc:
tclzipfile: ${TCL_ZIP_FILE}
-${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS}
+${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} ${DDE_DLL_FILE} ${REG_DLL_FILE}
rm -rf ${TCL_VFS_ROOT}
mkdir -p ${TCL_VFS_PATH}
$(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH}
diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c
index 26da566..2216a66 100644
--- a/win/tclWin32Dll.c
+++ b/win/tclWin32Dll.c
@@ -488,7 +488,7 @@ Tcl_WinUtfToTChar(
while (p < wp + size - 1) {
if (p[0] == 0xfffd && p[1] == 0xfffd) {
memmove(p+1, p+2, sizeof(TCHAR) * (p - wp + size - 2));
- p[0] = 0;
+ p[0] = '\0';
++p; --size;
}
++p;
@@ -506,7 +506,7 @@ Tcl_WinTCharToUtf(
Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
* converted string is stored. */
{
- char *p;
+ char *p, *r;
int size;
if (len > 0) {
@@ -514,10 +514,19 @@ Tcl_WinTCharToUtf(
}
size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL);
Tcl_DStringInit(dsPtr);
- Tcl_DStringSetLength(dsPtr, size+1);
- p = (char *)Tcl_DStringValue(dsPtr);
+ Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */
+ r = p = (char *)Tcl_DStringValue(dsPtr);
WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL);
if (len == -1) --size; /* account for 0-byte at string end */
+ while (r < p+size) {
+ if (!*r) {
+ /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */
+ memmove(r+2, r+1, p-r+size-1);
+ memcpy(r++, "\xC0\x80", 2);
+ Tcl_DStringSetLength(dsPtr, ++size + 1);
+ }
+ ++r;
+ }
Tcl_DStringSetLength(dsPtr, size);
p[size] = 0;
return p;