summaryrefslogtreecommitdiffstats
path: root/win/tclWinFile.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/tclWinFile.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/tclWinFile.c')
-rw-r--r--win/tclWinFile.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index 9087361..eeb48b7 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -943,12 +943,15 @@ TclpMatchInDirectory(
int len;
DWORD attr;
WIN32_FILE_ATTRIBUTE_DATA data;
- const char *str = Tcl_GetStringFromObj(norm,&len);
+ const char *str;
+ if (norm != pathPtr) { Tcl_IncrRefCount(norm); }
+ str = TclGetStringFromObj(norm, &len);
native = (WCHAR *)Tcl_FSGetNativePath(pathPtr);
if (GetFileAttributesExW(native,
GetFileExInfoStandard, &data) != TRUE) {
+ if (norm != pathPtr) { Tcl_DecrRefCount(norm); }
return TCL_OK;
}
attr = data.dwFileAttributes;
@@ -956,6 +959,7 @@ TclpMatchInDirectory(
if (NativeMatchType(WinIsDrive(str,len), attr, native, types)) {
Tcl_ListObjAppendElement(interp, resultPtr, pathPtr);
}
+ if (norm != pathPtr) { Tcl_DecrRefCount(norm); }
}
return TCL_OK;
} else {
@@ -981,7 +985,8 @@ TclpMatchInDirectory(
if (fileNamePtr == NULL) {
return TCL_ERROR;
}
- Tcl_IncrRefCount(fileNamePtr); /* ensure it'd be alive, while used. */
+ /* Ensure it'd be alive, while used. */
+ if (fileNamePtr != pathPtr) { Tcl_IncrRefCount(fileNamePtr); }
/*
* Verify that the specified path exists and is actually a directory.
@@ -989,14 +994,14 @@ TclpMatchInDirectory(
native = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
if (native == NULL) {
- Tcl_DecrRefCount(fileNamePtr);
+ if (fileNamePtr != pathPtr) { Tcl_DecrRefCount(fileNamePtr); }
return TCL_OK;
}
attr = GetFileAttributesW(native);
if ((attr == INVALID_FILE_ATTRIBUTES)
|| ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
- Tcl_DecrRefCount(fileNamePtr);
+ if (fileNamePtr != pathPtr) { Tcl_DecrRefCount(fileNamePtr); }
return TCL_OK;
}
@@ -1014,7 +1019,7 @@ TclpMatchInDirectory(
TclDStringAppendLiteral(&dsOrig, "/");
dirLength++;
}
- Tcl_DecrRefCount(fileNamePtr);
+ if (fileNamePtr != pathPtr) { Tcl_DecrRefCount(fileNamePtr); }
dirName = Tcl_DStringValue(&dsOrig);
/*
@@ -2412,18 +2417,21 @@ TclpObjLink(
int res;
const WCHAR *LinkTarget;
const WCHAR *LinkSource = (const WCHAR *)Tcl_FSGetNativePath(pathPtr);
- Tcl_Obj *normalizedToPtr = Tcl_FSGetNormalizedPath(NULL, toPtr);
+ Tcl_Obj *normToPtr = Tcl_FSGetNormalizedPath(NULL, toPtr);
- if (normalizedToPtr == NULL) {
+ if (normToPtr == NULL) {
return NULL;
}
+ if (normToPtr != toPtr) { Tcl_IncrRefCount(normToPtr); }
- LinkTarget = (const WCHAR *)Tcl_FSGetNativePath(normalizedToPtr);
+ LinkTarget = (const WCHAR *)Tcl_FSGetNativePath(normToPtr);
if (LinkSource == NULL || LinkTarget == NULL) {
+ if (normToPtr != toPtr) { Tcl_DecrRefCount(normToPtr); }
return NULL;
}
res = WinLink(LinkSource, LinkTarget, linkAction);
+ if (normToPtr != toPtr) { Tcl_DecrRefCount(normToPtr); }
if (res == 0) {
return toPtr;
} else {