diff options
author | dgp <dgp@users.sourceforge.net> | 2019-04-24 14:29:41 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2019-04-24 14:29:41 (GMT) |
commit | b21bc1e84f40c6e09c7d3fc3766a4106eab719d8 (patch) | |
tree | c02b1a384de12d05bf60795ff7da2dcbf39c53d0 | |
parent | 35396a7f5c0759d9cf20079bdf1700d0e55dba78 (diff) | |
download | tcl-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.c | 9 |
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; } |