diff options
| -rw-r--r-- | generic/tclZipfs.c | 37 | ||||
| -rw-r--r-- | tests/zipfs.test | 12 |
2 files changed, 31 insertions, 18 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index a074db1..4e38b09 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -889,7 +889,7 @@ static char * DecodeZipEntryText( const unsigned char *inputBytes, unsigned int inputLength, - Tcl_DString *dstPtr) + Tcl_DString *dstPtr) /* Must have been initialized by caller! */ { Tcl_Encoding encoding; const char *src; @@ -897,7 +897,6 @@ DecodeZipEntryText( int dstLen, srcLen = inputLength, flags; Tcl_EncodingState state; - Tcl_DStringInit(dstPtr); if (inputLength < 1) { return Tcl_DStringValue(dstPtr); } @@ -996,7 +995,9 @@ DecodeZipEntryText( *------------------------------------------------------------------------ */ static int -NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPtr) +NormalizeMountPoint(Tcl_Interp *interp, + const char *mountPath, + Tcl_DString *dsPtr) /* Must be initialized by caller! */ { const char *joiner[2]; char *joinedPath; @@ -1004,8 +1005,7 @@ NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPt Tcl_Obj *normalizedObj; const char *normalizedPath; Tcl_Size normalizedLen; - - Tcl_DStringInit(dsPtr); + Tcl_DString dsJoin; /* * Several things need to happen here @@ -1020,12 +1020,13 @@ NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPt joiner[0] = ZIPFS_VOLUME; joiner[1] = mountPath; - joinedPath = Tcl_JoinPath(2, joiner, dsPtr); + Tcl_DStringInit(&dsJoin); + joinedPath = Tcl_JoinPath(2, joiner, &dsJoin); /* Now joinedPath has all \ -> / and // -> / (except UNC) converted. */ if (!strncmp(ZIPFS_VOLUME, joinedPath, ZIPFS_VOLUME_LEN)) { - unnormalizedObj = Tcl_DStringToObj(dsPtr); + unnormalizedObj = Tcl_DStringToObj(&dsJoin); } else { if (joinedPath[0] != '/' || joinedPath[1] == '/') { /* mount path was D:/x, D:x or //unc */ @@ -1044,7 +1045,7 @@ NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPt /* normalizedObj owned by Tcl!! Do NOT DecrRef without an IncrRef */ normalizedPath = Tcl_GetStringFromObj(normalizedObj, &normalizedLen); - Tcl_DStringFree(dsPtr); /* Reset */ + Tcl_DStringFree(&dsJoin); Tcl_DStringAppend(dsPtr, normalizedPath, normalizedLen); Tcl_DecrRefCount(normalizedObj); return TCL_OK; @@ -1057,7 +1058,7 @@ invalidMountPath: } errorReturn: - Tcl_DStringFree(dsPtr); + Tcl_DStringFree(&dsJoin); return TCL_ERROR; } @@ -1084,7 +1085,8 @@ static char * MapPathToZipfs(Tcl_Interp *interp, const char *mountPath, /* Must be fully normalized */ const char *path, /* Archive content path to map */ - Tcl_DString *dsPtr) /* Must be cleared on success return */ + Tcl_DString *dsPtr) /* Must be initialized and cleared + by caller */ { const char *joiner[2]; char *joinedPath; @@ -1092,9 +1094,9 @@ MapPathToZipfs(Tcl_Interp *interp, Tcl_Obj *normalizedObj; const char *normalizedPath; Tcl_Size normalizedLen; + Tcl_DString dsJoin; assert(TclIsZipfsPath(mountPath)); - Tcl_DStringInit(dsPtr); joiner[0] = mountPath; joiner[1] = path; @@ -1104,19 +1106,20 @@ MapPathToZipfs(Tcl_Interp *interp, joiner[1] += 2; } #endif - joinedPath = Tcl_JoinPath(2, joiner, dsPtr); + Tcl_DStringInit(&dsJoin); + joinedPath = Tcl_JoinPath(2, joiner, &dsJoin); if (strncmp(ZIPFS_VOLUME, joinedPath, ZIPFS_VOLUME_LEN)) { /* path was not relative. Strip off the volume (e.g. UNC) */ Tcl_Size numParts; const char **partsPtr; Tcl_SplitPath(path, &numParts, &partsPtr); - Tcl_DStringFree(dsPtr); + Tcl_DStringFree(&dsJoin); partsPtr[0] = mountPath; - (void)Tcl_JoinPath(numParts, partsPtr, dsPtr); + (void)Tcl_JoinPath(numParts, partsPtr, &dsJoin); ckfree(partsPtr); } - unnormalizedObj = Tcl_DStringToObj(dsPtr); /* Also resets dsPtr */ + unnormalizedObj = Tcl_DStringToObj(&dsJoin); /* Also resets dsJoin */ Tcl_IncrRefCount(unnormalizedObj); normalizedObj = Tcl_FSGetNormalizedPath(interp, unnormalizedObj); if (normalizedObj == NULL) { @@ -1127,7 +1130,6 @@ MapPathToZipfs(Tcl_Interp *interp, Tcl_DecrRefCount(unnormalizedObj); /* normalizedObj owned by Tcl!! Do NOT DecrRef without an IncrRef */ - Tcl_DStringFree(dsPtr); /* Reset */ normalizedPath = Tcl_GetStringFromObj(normalizedObj, &normalizedLen); Tcl_DStringAppend(dsPtr, normalizedPath, normalizedLen); Tcl_DecrRefCount(normalizedObj); @@ -1971,6 +1973,7 @@ ZipFSCatalogFilesystem( pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS); comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); extra = ZipReadShort(start, end, q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); path = DecodeZipEntryText(q + ZIP_CENTRAL_HEADER_LEN, pathlen, &ds); if ((pathlen > 0) && (path[pathlen - 1] == '/')) { Tcl_DStringSetLength(&ds, pathlen - 1); @@ -2336,6 +2339,7 @@ TclZipfs_Mount( } Tcl_DString ds; + Tcl_DStringInit(&ds); ret = NormalizeMountPoint(interp, mountPoint, &ds); if (ret != TCL_OK) { Unlock(); @@ -2448,6 +2452,7 @@ TclZipfs_MountBuffer( } Tcl_DString ds; + Tcl_DStringInit(&ds); ret = NormalizeMountPoint(interp, mountPoint, &ds); if (ret != TCL_OK) { Unlock(); diff --git a/tests/zipfs.test b/tests/zipfs.test index 025d4c1..a7a6a1d 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -694,8 +694,8 @@ namespace eval test_ns_zipfs { cleanup } -body { # Primarily verifies that drive letters are stripped and paths maintained - lsort [zipfs list] - } -result {//zipfs:/testmount //zipfs:/testmount/filename.txt //zipfs:/testmount/src //zipfs:/testmount/src/tcltk //zipfs:/testmount/src/tcltk/wip //zipfs:/testmount/src/tcltk/wip/tcl //zipfs:/testmount/src/tcltk/wip/tcl/tests //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/abspath.txt //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/fullpath.txt} + lsort [zipfs find $defMountPt] + } -result {//zipfs:/testmount/filename.txt //zipfs:/testmount/src //zipfs:/testmount/src/tcltk //zipfs:/testmount/src/tcltk/wip //zipfs:/testmount/src/tcltk/wip/tcl //zipfs:/testmount/src/tcltk/wip/tcl/tests //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/abspath.txt //zipfs:/testmount/src/tcltk/wip/tcl/tests/zipfiles/fullpath.txt} # # zipfs list @@ -1917,6 +1917,14 @@ namespace eval test_ns_zipfs { read $fd close $fd } -result "" + + # Following will only show a leak with valgrind + test bug-9525f4c8bc "Memory leak with long mount paths" -body { + set mt //zipfs:[string repeat /x 240] + zipfs mount [zippath test.zip] $mt + zipfs unmount $mt + } -result "" + } |
