summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2013-07-24 16:56:59 (GMT)
committerdgp <dgp@users.sourceforge.net>2013-07-24 16:56:59 (GMT)
commit0eb24b976438cfedbe287ccb3e41155a62785c1d (patch)
treea603d8e7dde86e04737b1a2353218ef36188adf4
parentf9e25fe5e7e67249f73b8f5926b3b5549c0e212e (diff)
parent7682f9c4cd7dfb3439a27d03b4531358798ff443 (diff)
downloadtcl-0eb24b976438cfedbe287ccb3e41155a62785c1d.zip
tcl-0eb24b976438cfedbe287ccb3e41155a62785c1d.tar.gz
tcl-0eb24b976438cfedbe287ccb3e41155a62785c1d.tar.bz2
Demonstrate and fix memory leak in Tcl_ParseVar().
-rw-r--r--generic/tclParse.c1
-rw-r--r--tests/parse.test21
2 files changed, 22 insertions, 0 deletions
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 08615a7..6723d39 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -1567,6 +1567,7 @@ Tcl_ParseVar(
code = TclSubstTokens(interp, parsePtr->tokenPtr, parsePtr->numTokens,
NULL, 1, NULL, NULL);
+ Tcl_FreeParse(parsePtr);
TclStackFree(interp, parsePtr);
if (code != TCL_OK) {
return NULL;
diff --git a/tests/parse.test b/tests/parse.test
index b9cfe80..9f2d50b 100644
--- a/tests/parse.test
+++ b/tests/parse.test
@@ -27,6 +27,7 @@ testConstraint testparsevar [llength [info commands testparsevar]]
testConstraint testasync [llength [info commands testasync]]
testConstraint testcmdtrace [llength [info commands testcmdtrace]]
testConstraint testevent [llength [info commands testevent]]
+testConstraint memory [llength [info commands memory]]
test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser {
testparser [bytestring "foo\0 bar"] -1
@@ -678,6 +679,26 @@ test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar
unset -nocomplain abc
list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
} {1 {invalid command name "bogus"}}
+test parse-13.6 {Tcl_ParseVar memory leak} -constraints memory -setup {
+ proc getbytes {} {
+ return [lindex [split [memory info] \n] 3 3]
+ }
+} -body {
+ set a() foo
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set vn {}
+ set res [testparsevar [append vn $ a([string repeat {[]} 19]) bar]]
+ if {$res ne {foo bar}} {error "Unexpected result: $res"}
+
+ set tmp $end
+ set end [getbytes]
+ }
+ expr {$end - $tmp}
+} -cleanup {
+ unset -nocomplain a end i vn res tmp
+ rename getbytes {}
+} -result 0
test parse-14.1 {Tcl_ParseBraces procedure, computing string length} testparser {
testparser [bytestring "foo\0 bar"] -1