summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2023-04-27 20:42:04 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2023-04-27 20:42:04 (GMT)
commit5eb2064b6323a354be793a900518f1136a3399da (patch)
tree2e63b650b9c897b74bf50eebb1ef40d18c543289
parent2e9301202d1bc6b6a8cb45f75585c911e64d5063 (diff)
parent7f433932f67e088cdf21d42138a2fd4c96620ef0 (diff)
downloadtcl-5eb2064b6323a354be793a900518f1136a3399da.zip
tcl-5eb2064b6323a354be793a900518f1136a3399da.tar.gz
tcl-5eb2064b6323a354be793a900518f1136a3399da.tar.bz2
Fix for [f5eadcbf9a6b1b4c], passing pointer to uninitialized memory leads
Tcl_UniCharToUtf() to corrupt data.
-rw-r--r--generic/tclEncoding.c43
-rw-r--r--generic/tclStringObj.c6
-rw-r--r--generic/tclUtf.c16
3 files changed, 65 insertions, 0 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index 2b8e8c0..abce00b 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -2532,6 +2532,14 @@ UtfToUtfProc(
flags |= PTR2INT(clientData);
dstEnd = dst + dstLen - ((flags & ENCODING_UTF) ? TCL_UTF_MAX : 6);
+
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
profile = CHANNEL_PROFILE_GET(flags);
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
@@ -2746,6 +2754,13 @@ Utf32ToUtfProc(
}
result = TCL_OK;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
/*
* Check alignment with utf-32 (4 == sizeof(UTF-32))
*/
@@ -3015,6 +3030,13 @@ Utf16ToUtfProc(
}
result = TCL_OK;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
/*
* Check alignment with utf-16 (2 == sizeof(UTF-16))
*/
@@ -3428,6 +3450,13 @@ TableToUtfProc(
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
toUnicode = (const unsigned short *const *) dataPtr->toUnicode;
prefixBytes = dataPtr->prefixBytes;
pageZero = toUnicode[0];
@@ -3669,6 +3698,13 @@ Iso88591ToUtfProc(
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
result = TCL_OK;
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
Tcl_UniChar ch = 0;
@@ -3908,6 +3944,13 @@ EscapeToUtfProc(
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, dstLen);
+
state = PTR2INT(*statePtr);
if (flags & TCL_ENCODING_START) {
state = 0;
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 22a686f..4202873 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -4497,6 +4497,12 @@ ExtendStringRepWithUnicode(
copyBytes:
dst = objPtr->bytes + origLength;
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(dst, 0xff, stringPtr->allocated - origLength);
for (i = 0; i < numChars; i++) {
dst += Tcl_UniCharToUtf(unicode[i], dst);
}
diff --git a/generic/tclUtf.c b/generic/tclUtf.c
index cc5769f..54cef2f 100644
--- a/generic/tclUtf.c
+++ b/generic/tclUtf.c
@@ -348,6 +348,14 @@ Tcl_UniCharToUtfDString(
p = string;
wEnd = uniStr + uniLength;
+
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Once TCL_UTF_MAX == 3 is removed and Tcl_UniCharToUtf restored to its
+ * prior non-stateful nature, this call to memset can also be removed.
+ */
+ memset(p, 0xff, Tcl_DStringLength(dsPtr) - oldLength);
+
for (w = uniStr; w < wEnd; ) {
p += Tcl_UniCharToUtf(*w, p);
w++;
@@ -391,6 +399,14 @@ Tcl_Char16ToUtfDString(
p = string;
wEnd = uniStr + uniLength;
+
+ /* Initialize the buffer so that some random data doesn't trick
+ * Tcl_UniCharToUtf() into thinking it should combine surrogate pairs.
+ * Because TCL_COMBINE is used here, memset() is required even when
+ * TCL_UTF_MAX == 4.
+ */
+ memset(p, 0xff, Tcl_DStringLength(dsPtr) - oldLength);
+
for (w = uniStr; w < wEnd; ) {
if (!len && ((*w & 0xFC00) != 0xDC00)) {
/* Special case for handling high surrogates. */