diff options
| author | sebres <sebres@users.sourceforge.net> | 2025-07-21 18:21:43 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2025-07-21 18:21:43 (GMT) |
| commit | e7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10 (patch) | |
| tree | fd8fdc0c2f22981d9fed6e2e98447134f1341112 /win/tclWinFCmd.c | |
| parent | 6f2c08cfba0904f3bbd9f983e04381b4e86fccee (diff) | |
| download | tcl-e7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10.zip tcl-e7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10.tar.gz tcl-e7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10.tar.bz2 | |
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 441337e..a9de366 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -910,10 +910,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); @@ -934,6 +940,9 @@ TclpObjCopyDirectory( Tcl_DStringFree(&ds); Tcl_IncrRefCount(*errorPtr); } + + if (normSrcPtr != srcPathPtr) { Tcl_DecrRefCount(normSrcPtr); } + if (normDestPtr != destPathPtr) { Tcl_DecrRefCount(normDestPtr); } return ret; } @@ -988,6 +997,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); @@ -1008,6 +1018,7 @@ TclpObjRemoveDirectory( } Tcl_DStringFree(&ds); } + if (normPtr && normPtr != pathPtr) { Tcl_DecrRefCount(normPtr); } return ret; } |
