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/tclWinFile.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/tclWinFile.c')
| -rw-r--r-- | win/tclWinFile.c | 24 |
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 { |
