diff options
| author | sebres <sebres@users.sourceforge.net> | 2018-07-26 19:10:41 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2018-07-26 19:10:41 (GMT) |
| commit | e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42 (patch) | |
| tree | fda39d88c678de3ee6fbaa5f9c1c7bc6b3682b67 | |
| parent | 5c0692322db2cf56b327751edf8bcbc9e50809b3 (diff) | |
| parent | ad757b50dce2f04dd5e6d034a96f4ddd90621a0e (diff) | |
| download | tcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.zip tcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.tar.gz tcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.tar.bz2 | |
merge 8.7
| -rw-r--r-- | generic/tclStringObj.c | 23 | ||||
| -rw-r--r-- | tests/format.test | 14 | ||||
| -rw-r--r-- | tests/string.test | 6 |
3 files changed, 40 insertions, 3 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index f1c7350..7d8e736 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1848,6 +1848,11 @@ Tcl_AppendFormatToObj( width = 0; if (isdigit(UCHAR(ch))) { width = strtoul(format, &end, 10); + if (width < 0) { + msg = overflow; + errCode = "OVERFLOW"; + goto errorMsg; + } format = end; step = TclUtfToUniChar(format, &ch); } else if (ch == '*') { @@ -3001,15 +3006,21 @@ TclStringCat( * Result will be pure byte array. Pre-size it */ + int numBytes; ov = objv; oc = objc; do { Tcl_Obj *objPtr = *ov++; - if (objPtr->bytes == NULL) { - int numBytes; + /* + * Every argument is either a bytearray with a ("pure") + * value we know we can safely use, or it is an empty string. + * We don't need to count bytes for the empty strings. + */ + if (TclIsPureByteArray(objPtr)) { Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */ + if (numBytes) { last = objc - oc; if (length == 0) { @@ -3161,7 +3172,13 @@ TclStringCat( while (objc--) { Tcl_Obj *objPtr = *objv++; - if (objPtr->bytes == NULL) { + /* + * Every argument is either a bytearray with a ("pure") + * value we know we can safely use, or it is an empty string. + * We don't need to copy bytes from the empty strings. + */ + + if (TclIsPureByteArray(objPtr)) { int more; unsigned char *src = Tcl_GetByteArrayFromObj(objPtr, &more); memcpy(dst, src, (size_t) more); diff --git a/tests/format.test b/tests/format.test index d380b05..0f24e8f 100644 --- a/tests/format.test +++ b/tests/format.test @@ -597,6 +597,20 @@ test format-19.3 {Bug 2830354} { string length [format %340f 0] } 340 +test format-19.4.1 {Bug d498578df4: width overflow should cause limit exceeded} \ +-constraints {longIs32bit} -body { + # in case of overflow into negative, it produces width -2 (and limit exceeded), + # in case of width will be unsigned, it will be outside limit (2GB for 32bit)... + # and it don't throw an error in case the bug is not fixed (and probably no segfault). + format %[expr {0xffffffff - 1}]g 0 +} -returnCodes error -result "max size for a Tcl value exceeded" + +test format-19.4.2 {Bug d498578df4: width overflow should cause limit exceeded} -body { + # limit should exceeds in any case, + # and it don't throw an error in case the bug is not fixed (and probably no segfault). + format %[expr {0xffffffffffffffff - 1}]g 0 +} -returnCodes error -result "max size for a Tcl value exceeded" + # Note that this test may fail in future versions test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body { set x [dict create a b c d] diff --git a/tests/string.test b/tests/string.test index 283c745..e0b7ec4 100644 --- a/tests/string.test +++ b/tests/string.test @@ -2306,6 +2306,12 @@ test string-29.15.$noComp {string cat, efficiency} -setup { tcl::unsupported::representation [run {string cat $e $f $e $f [list x]}] } -match glob -result {*no string representation} } +test string-30.1.1.$noComp {[Bug ba921a8d98]: string cat} { + run {string cat [set data [binary format a* hello]] [encoding convertto $data] [unset data]} +} hellohello +test string-30.1.2.$noComp {[Bug ba921a8d98]: inplace cat by subst (compiled to "strcat" instruction)} { + run {set x "[set data [binary format a* hello]][encoding convertto $data][unset data]"} +} hellohello } |
