summaryrefslogtreecommitdiffstats
path: root/win/tclWinFCmd.c
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2025-07-21 18:32:50 (GMT)
committersebres <sebres@users.sourceforge.net>2025-07-21 18:32:50 (GMT)
commit899a818f2341e6eb0a03d92f3cbfcbfea136064c (patch)
tree08d23b4cc7cd8c08626fd084766dba3e47110fcd /win/tclWinFCmd.c
parent9ff2ef9fe1182691137f06690891b27b24890dd3 (diff)
parente7e759c639a63a5b4ef2bcce0a9aaab4cb1ffe10 (diff)
downloadtcl-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.c13
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;
}