summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2024-01-29 13:55:50 (GMT)
committersebres <sebres@users.sourceforge.net>2024-01-29 13:55:50 (GMT)
commite854c0b7ad76b97772afc934c45e763ecf17ff5c (patch)
treec39453206359fb16bf2aafe1c6c482a315bc2c07
parentcd529a89c5b995d312b41d0b7c9054d678ee8745 (diff)
downloadtcl-e854c0b7ad76b97772afc934c45e763ecf17ff5c.zip
tcl-e854c0b7ad76b97772afc934c45e763ecf17ff5c.tar.gz
tcl-e854c0b7ad76b97772afc934c45e763ecf17ff5c.tar.bz2
closes [db4f2843cd]: fixes SF by BO in ReadChars (and Tcl_ReadChars with append) caused by wrong buffer enlarge if objPtr shimmering to unicode for whatever reason, since Tcl_AppendToObj prefers unicode to bytes, whereas TclAppendUtfToUtf always extend bytes (that handled by ReadChars)
-rw-r--r--generic/tclIO.c3
-rw-r--r--generic/tclInt.h2
-rw-r--r--generic/tclStringObj.c37
3 files changed, 39 insertions, 3 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 0f79f1e..b8a79c2 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -6111,8 +6111,9 @@ ReadChars(
int factor = *factorPtr;
int dstLimit = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR;
+ if (dstLimit <= 0) dstLimit = INT_MAX; /* avoid overflow */
(void) TclGetStringFromObj(objPtr, &numBytes);
- Tcl_AppendToObj(objPtr, NULL, dstLimit);
+ TclAppendUtfToUtf(objPtr, NULL, dstLimit);
if (toRead == srcLen) {
unsigned int size;
diff --git a/generic/tclInt.h b/generic/tclInt.h
index a09d6cb..68c07f2 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2861,6 +2861,8 @@ struct Tcl_LoadHandle_ {
MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr,
const unsigned char *bytes, int len);
+MODULE_SCOPE void TclAppendUtfToUtf(Tcl_Obj *objPtr,
+ const char *bytes, int numBytes);
MODULE_SCOPE void TclAdvanceContinuations(int *line, int **next,
int loc);
MODULE_SCOPE void TclAdvanceLines(int *line, const char *start,
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 975b991..7f9f874 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -1671,7 +1671,7 @@ AppendUnicodeToUtfRep(
* None.
*
* Side effects:
- * objPtr's internal rep is reallocated.
+ * objPtr's internal rep is reallocated and string rep is cleaned.
*
*----------------------------------------------------------------------
*/
@@ -1707,7 +1707,7 @@ AppendUtfToUnicodeRep(
* None.
*
* Side effects:
- * objPtr's internal rep is reallocated.
+ * objPtr's string rep is reallocated (by TCL STRING GROWTH ALGORITHM).
*
*----------------------------------------------------------------------
*/
@@ -1787,6 +1787,39 @@ AppendUtfToUtfRep(
/*
*----------------------------------------------------------------------
*
+ * TclAppendUtfToUtf --
+ *
+ * This function appends "numBytes" bytes of "bytes" to the UTF string
+ * rep of "objPtr" (objPtr's internal rep converted to string on demand).
+ * numBytes must be non-negative.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * objPtr's string rep is reallocated (by TCL STRING GROWTH ALGORITHM).
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclAppendUtfToUtf(
+ Tcl_Obj *objPtr, /* Points to the object to append to. */
+ const char *bytes, /* String to append (or NULL to enlarge buffer). */
+ int numBytes) /* Number of bytes of "bytes" to append. */
+{
+ if (Tcl_IsShared(objPtr)) {
+ Tcl_Panic("%s called with shared object", "TclAppendUtfToUtf");
+ }
+
+ SetStringFromAny(NULL, objPtr);
+
+ AppendUtfToUtfRep(objPtr, bytes, numBytes);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_AppendStringsToObjVA --
*
* This function appends one or more null-terminated strings to an