diff options
| author | sebres <sebres@users.sourceforge.net> | 2025-07-21 18:32:50 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2025-07-21 18:32:50 (GMT) |
| commit | 899a818f2341e6eb0a03d92f3cbfcbfea136064c (patch) | |
| tree | 08d23b4cc7cd8c08626fd084766dba3e47110fcd /win/tclWinFCmd.c | |
| parent | 9ff2ef9fe1182691137f06690891b27b24890dd3 (diff) | |
| parent | e7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10 (diff) | |
| download | tcl-899a818f2341e6eb0a03d92f3cbfcbfea136064c.zip tcl-899a818f2341e6eb0a03d92f3cbfcbfea136064c.tar.gz tcl-899a818f2341e6eb0a03d92f3cbfcbfea136064c.tar.bz2 | |
merge 8.5 to 8.6: amend to [61c01e0edb08a9ed], more cases for increment ref-count with use-after-free prevention for interim normalized path object; provide fixes minimally invasive (if API used with fresh created path object, so decrement would not destroy it if normalized path equal original given path)
Diffstat (limited to 'win/tclWinFCmd.c')
| -rw-r--r-- | win/tclWinFCmd.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index 0bf21dd..ba76b5e 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -906,10 +906,16 @@ TclpObjCopyDirectory( int ret; normSrcPtr = Tcl_FSGetNormalizedPath(NULL,srcPathPtr); + if (normSrcPtr == NULL) { + return TCL_ERROR; + } + if (normSrcPtr != srcPathPtr) { Tcl_IncrRefCount(normSrcPtr); } normDestPtr = Tcl_FSGetNormalizedPath(NULL,destPathPtr); - if ((normSrcPtr == NULL) || (normDestPtr == NULL)) { + if (normDestPtr == NULL) { + if (normSrcPtr != srcPathPtr) { Tcl_DecrRefCount(normSrcPtr); } return TCL_ERROR; } + if (normDestPtr != destPathPtr) { Tcl_IncrRefCount(normDestPtr); } Tcl_WinUtfToTChar(Tcl_GetString(normSrcPtr), -1, &srcString); Tcl_WinUtfToTChar(Tcl_GetString(normDestPtr), -1, &dstString); @@ -930,6 +936,9 @@ TclpObjCopyDirectory( Tcl_DStringFree(&ds); Tcl_IncrRefCount(*errorPtr); } + + if (normSrcPtr != srcPathPtr) { Tcl_DecrRefCount(normSrcPtr); } + if (normDestPtr != destPathPtr) { Tcl_DecrRefCount(normDestPtr); } return ret; } @@ -984,6 +993,7 @@ TclpObjRemoveDirectory( if (normPtr == NULL) { return TCL_ERROR; } + if (normPtr != pathPtr) { Tcl_IncrRefCount(normPtr); } Tcl_WinUtfToTChar(Tcl_GetString(normPtr), -1, &native); ret = DoRemoveDirectory(&native, recursive, &ds); Tcl_DStringFree(&native); @@ -1003,6 +1013,7 @@ TclpObjRemoveDirectory( } Tcl_DStringFree(&ds); } + if (normPtr && normPtr != pathPtr) { Tcl_DecrRefCount(normPtr); } return ret; } |
