summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2012-01-26 16:53:56 (GMT)
committerdgp <dgp@users.sourceforge.net>2012-01-26 16:53:56 (GMT)
commitebc5194e2d1e363c46561ea1303dfb409f58862f (patch)
tree3d91f7e33f4131d7b72d37cffc46247620e30cac /generic
parent68fbac8d0f24ffb16077c6c3ecd6c1a61ab16bb1 (diff)
parentc476140458013d8216208a4ea6f6c8537525fa98 (diff)
downloadtcl-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.c29
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__)