diff options
author | sebres <sebres@users.sourceforge.net> | 2024-01-29 13:55:50 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2024-01-29 13:55:50 (GMT) |
commit | e854c0b7ad76b97772afc934c45e763ecf17ff5c (patch) | |
tree | c39453206359fb16bf2aafe1c6c482a315bc2c07 | |
parent | cd529a89c5b995d312b41d0b7c9054d678ee8745 (diff) | |
download | tcl-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.c | 3 | ||||
-rw-r--r-- | generic/tclInt.h | 2 | ||||
-rw-r--r-- | generic/tclStringObj.c | 37 |
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 |