diff options
author | dgp <dgp@users.sourceforge.net> | 2018-11-09 16:03:22 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2018-11-09 16:03:22 (GMT) |
commit | 5deb25bc9b71c984e1e0577b53b7664c1fab0315 (patch) | |
tree | a06be82e0f814165c21ee6cae49f3d72ed9855ef /generic | |
parent | 008a36f3e4b5daef7eadc65c63a98e40d62bd1e2 (diff) | |
parent | 0f4e877214d36d6ecbf31ae9fb60ea5ebb3dac0a (diff) | |
download | tcl-5deb25bc9b71c984e1e0577b53b7664c1fab0315.zip tcl-5deb25bc9b71c984e1e0577b53b7664c1fab0315.tar.gz tcl-5deb25bc9b71c984e1e0577b53b7664c1fab0315.tar.bz2 |
merge 8.5
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclListObj.c | 19 | ||||
-rw-r--r-- | generic/tclUtil.c | 17 |
2 files changed, 35 insertions, 1 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 786e1ce..e42567e 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -1990,7 +1990,21 @@ UpdateStringOfList( * Pass 2: copy into string rep buffer. */ + /* + * We used to set the string length here, relying on a presumed + * guarantee that the number of bytes TclScanElement() calls reported + * to be needed was a precise count and not an over-estimate, so long + * as the same flag values were passed to TclConvertElement(). + * + * Then we saw [35a8f1c04a], where a bug in TclScanElement() caused + * that guarantee to fail. Rather than trust there are no more bugs, + * we set the length after the loop based on what was actually written, + * an not on what was predicted. + * listPtr->length = bytesNeeded - 1; + * + */ + listPtr->bytes = ckalloc(bytesNeeded); dst = listPtr->bytes; for (i = 0; i < numElems; i++) { @@ -1999,7 +2013,10 @@ UpdateStringOfList( dst += TclConvertElement(elem, length, dst, flagPtr[i]); *dst++ = ' '; } - listPtr->bytes[listPtr->length] = '\0'; + dst[-1] = '\0'; + + /* Here is the safe setting of the string length. */ + listPtr->length = dst - 1 - listPtr->bytes; if (flagPtr != localFlags) { ckfree(flagPtr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 6eab7b8..d5cc7c2 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -1046,6 +1046,23 @@ TclScanElement( return 2; } +#if COMPAT + /* + * We have an established history in TclConvertElement() when quoting + * because of a leading hash character to force what would be the + * CONVERT_MASK mode into the CONVERT_BRACE mode. That is, we format + * the element #{a"b} like this: + * {#{a"b}} + * and not like this: + * \#{a\"b} + * This is inconsistent with [list x{a"b}], but we will not change that now. + * Set that preference here so that we compute a tight size requirement. + */ + if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) { + preferBrace = 1; + } +#endif + if ((*p == '{') || (*p == '"')) { /* * Must escape or protect so leading character of value is not |