diff options
author | dgp <dgp@users.sourceforge.net> | 2012-01-26 16:53:56 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2012-01-26 16:53:56 (GMT) |
commit | ebc5194e2d1e363c46561ea1303dfb409f58862f (patch) | |
tree | 3d91f7e33f4131d7b72d37cffc46247620e30cac /generic | |
parent | 68fbac8d0f24ffb16077c6c3ecd6c1a61ab16bb1 (diff) | |
parent | c476140458013d8216208a4ea6f6c8537525fa98 (diff) | |
download | tcl-ebc5194e2d1e363c46561ea1303dfb409f58862f.zip tcl-ebc5194e2d1e363c46561ea1303dfb409f58862f.tar.gz tcl-ebc5194e2d1e363c46561ea1303dfb409f58862f.tar.bz2 |
3475569 Add checks for unshared values before calls demanding them.
3479689 Stop memory corruption when shimmering 0-refCount value to "path" type.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclPathObj.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index dd68004..30f2081 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -269,6 +269,14 @@ TclFSNormalizeAbsolutePath( } if (!first || (tclPlatform == TCL_PLATFORM_UNIX)) { linkObj = Tcl_FSLink(retVal, NULL, 0); + + /* Safety check in case driver caused sharing */ + if (Tcl_IsShared(retVal)) { + TclDecrRefCount(retVal); + retVal = Tcl_DuplicateObj(retVal); + Tcl_IncrRefCount(retVal); + } + if (linkObj != NULL) { /* * Got a link. Need to check if the link is relative @@ -293,11 +301,6 @@ TclFSNormalizeAbsolutePath( break; } } - if (Tcl_IsShared(retVal)) { - TclDecrRefCount(retVal); - retVal = Tcl_DuplicateObj(retVal); - Tcl_IncrRefCount(retVal); - } /* * We want the trailing slash. @@ -313,7 +316,12 @@ TclFSNormalizeAbsolutePath( */ TclDecrRefCount(retVal); - retVal = linkObj; + if (Tcl_IsShared(linkObj)) { + retVal = Tcl_DuplicateObj(linkObj); + TclDecrRefCount(linkObj); + } else { + retVal = linkObj; + } linkStr = Tcl_GetStringFromObj(retVal, &curLen); /* @@ -1075,6 +1083,12 @@ Tcl_FSJoinPath( if (sep != NULL) { separator = TclGetString(sep)[0]; } + /* Safety check in case the VFS driver caused sharing */ + if (Tcl_IsShared(res)) { + TclDecrRefCount(res); + res = Tcl_DuplicateObj(res); + Tcl_IncrRefCount(res); + } } if (length > 0 && ptr[length -1] != '/') { @@ -2485,7 +2499,10 @@ SetFsPathFromAny( } Tcl_DStringFree(&temp); } else { + /* Bug 3479689: protect 0-refcount pathPth from getting freed */ + pathPtr->refCount++; transPtr = Tcl_FSJoinToPath(pathPtr, 0, NULL); + pathPtr->refCount--; } #if defined(__CYGWIN__) && defined(__WIN32__) |