summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclUtil.c8
-rw-r--r--tests/split.test15
2 files changed, 23 insertions, 0 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index d0cca71..55c7212 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -869,6 +869,14 @@ Tcl_SplitList(
size = TclMaxListLength(list, -1, &end) + 1;
length = end - list;
+ if (size >= (INT_MAX/sizeof(char *)) ||
+ length > (INT_MAX - 1 - (size * sizeof(char *)))) {
+ if (interp) {
+ Tcl_SetResult(
+ interp, "memory allocation limit exceeded", TCL_STATIC);
+ }
+ return TCL_ERROR;
+ }
argv = (const char **)ckalloc((size * sizeof(char *)) + length + 1);
for (i = 0, p = ((char *) argv) + size*sizeof(char *);
diff --git a/tests/split.test b/tests/split.test
index efd4323..2862291 100644
--- a/tests/split.test
+++ b/tests/split.test
@@ -80,6 +80,21 @@ test split-2.1 {split errors} {
test split-2.2 {split errors} {
list [catch {split a b c} msg] $msg $errorCode
} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+
+test bug-c9f0520f7e "Bug c9f0520f7e Tcl_SplitList memory overflow crash" -body {
+ # [dict for] compilation calls Tcl_SplitList, thus its use. Not
+ # a bug in dict.
+ proc p {} [list dict for $str {} {}]
+ p
+} -constraints slowTest -setup {
+ set limit 26
+ set str "0 1 2 3 4 5 6 7 8 9 "
+ for { set i 0 } { $i < $limit } { incr i } {
+ set str "$str $str"
+ }
+} -cleanup {
+ catch {rename p {}}
+} -result {max length of a Tcl list * exceeded} -match glob -returnCodes error
# cleanup
catch {rename foo {}}