diff options
author | ashok <ashok> | 2014-11-14 04:15:10 (GMT) |
---|---|---|
committer | ashok <ashok> | 2014-11-14 04:15:10 (GMT) |
commit | 47855ace43a7f946266bfc62a9cb919d478c9580 (patch) | |
tree | e0d4b0fc55e53cfd96ed8cdacde8b0ea1693af49 /win | |
parent | 1529354d816acf50736e152a156118c7335c6b17 (diff) | |
download | tk-47855ace43a7f946266bfc62a9cb919d478c9580.zip tk-47855ace43a7f946266bfc62a9cb919d478c9580.tar.gz tk-47855ace43a7f946266bfc62a9cb919d478c9580.tar.bz2 |
Fix [d43a10ce2fed950e00890049f3c273f2cdd12583|d43a10ce2f]: tk_getOpenFile crashes when passed a bad -typevariable.
Crash was caused by access to a list element after the Tcl_Obj was shimmered
to a variable intrep.
Diffstat (limited to 'win')
-rw-r--r-- | win/tkWinDialog.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index c90d05a..37e4dfb 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -1739,9 +1739,24 @@ static int GetFileNameXP(Tcl_Interp *interp, OFNOpts *optsPtr, enum OFNOper oper listObjv[ofn.nFilterIndex - 1], &count, &typeInfo) != TCL_OK) { result = TCL_ERROR; - } else if (Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, - typeInfo[0], TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { - result = TCL_ERROR; + } else { + /* + * BUGFIX for d43a10ce2fed950e00890049f3c273f2cdd12583 + * The original code was broken because it passed typeinfo[0] + * directly into Tcl_ObjSetVar2. In the case of typeInfo[0] + * pointing into a list which is also referenced by + * typeVariableObj, TOSV2 shimmers the object into + * variable intrep which loses the list representation. + * This invalidates typeInfo[0] which is freed but + * nevertheless stored as the value of the variable. + */ + Tcl_Obj *selFilterObj = typeInfo[0]; + Tcl_IncrRefCount(selFilterObj); + if (Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, + selFilterObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + result = TCL_ERROR; + } + Tcl_DecrRefCount(selFilterObj); } } } else if (cdlgerr == FNERR_INVALIDFILENAME) { |