summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2019-04-24 14:29:41 (GMT)
committerdgp <dgp@users.sourceforge.net>2019-04-24 14:29:41 (GMT)
commitb21bc1e84f40c6e09c7d3fc3766a4106eab719d8 (patch)
treec02b1a384de12d05bf60795ff7da2dcbf39c53d0
parent35396a7f5c0759d9cf20079bdf1700d0e55dba78 (diff)
downloadtcl-b21bc1e84f40c6e09c7d3fc3766a4106eab719d8.zip
tcl-b21bc1e84f40c6e09c7d3fc3766a4106eab719d8.tar.gz
tcl-b21bc1e84f40c6e09c7d3fc3766a4106eab719d8.tar.bz2
Plug memleak in [lpop] due to mishandling the unconventional recounting
practices of TclLsetFlat().
-rw-r--r--generic/tclCmdIL.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index dd7136c..ef7a42c 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -2584,7 +2584,7 @@ Tcl_LpopObjCmd(
/* Argument objects. */
{
int listLen, result;
- Tcl_Obj *elemPtr;
+ Tcl_Obj *elemPtr, *stored;
Tcl_Obj *listPtr, **elemPtrs;
if (objc < 2) {
@@ -2622,6 +2622,7 @@ Tcl_LpopObjCmd(
/*
* Second, remove the element.
+ * TclLsetFlat adds a ref count which is handled.
*/
if (objc == 2) {
@@ -2632,6 +2633,7 @@ Tcl_LpopObjCmd(
if (result != TCL_OK) {
return result;
}
+ Tcl_IncrRefCount(listPtr);
} else {
listPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL);
@@ -2640,8 +2642,9 @@ Tcl_LpopObjCmd(
}
}
- listPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
- if (listPtr == NULL) {
+ stored = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
+ Tcl_DecrRefCount(listPtr);
+ if (stored == NULL) {
return TCL_ERROR;
}