summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2018-07-26 19:10:41 (GMT)
committersebres <sebres@users.sourceforge.net>2018-07-26 19:10:41 (GMT)
commite68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42 (patch)
treefda39d88c678de3ee6fbaa5f9c1c7bc6b3682b67
parent5c0692322db2cf56b327751edf8bcbc9e50809b3 (diff)
parentad757b50dce2f04dd5e6d034a96f4ddd90621a0e (diff)
downloadtcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.zip
tcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.tar.gz
tcl-e68dfbc8afaac6c1288fdf0d3b43f5fc9480fe42.tar.bz2
merge 8.7
-rw-r--r--generic/tclStringObj.c23
-rw-r--r--tests/format.test14
-rw-r--r--tests/string.test6
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
}