summaryrefslogtreecommitdiffstats
path: root/generic/tclZipfs.c
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-10-15 06:32:31 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-10-15 06:32:31 (GMT)
commit8c2f47321dea1fe813bb8ca865d2cff1a9b08236 (patch)
treeccf68170e33e95191a421451c329f4fd465a96a5 /generic/tclZipfs.c
parent8c3b029c0757d433637c1911a74cd55c2766e3e9 (diff)
downloadtcl-8c2f47321dea1fe813bb8ca865d2cff1a9b08236.zip
tcl-8c2f47321dea1fe813bb8ca865d2cff1a9b08236.tar.gz
tcl-8c2f47321dea1fe813bb8ca865d2cff1a9b08236.tar.bz2
More fixes, update docs
Diffstat (limited to 'generic/tclZipfs.c')
-rw-r--r--generic/tclZipfs.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index d840224..a074db1 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -1011,7 +1011,6 @@ NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPt
* Several things need to happen here
* - Absolute paths containing volumes (drive letter or UNC) raise error
* except of course if the volume is zipfs root
- * - \ need to be converted to /
* - \ -> / and // -> / conversions (except if UNC which is error)
* - . and .. have to be dealt with
* The first is explicitly checked, the others are dealt with a
@@ -1029,7 +1028,7 @@ NormalizeMountPoint(Tcl_Interp *interp, const char *mountPath, Tcl_DString *dsPt
unnormalizedObj = Tcl_DStringToObj(dsPtr);
} else {
if (joinedPath[0] != '/' || joinedPath[1] == '/') {
- /* D:/x, D:x or //unc */
+ /* mount path was D:/x, D:x or //unc */
goto invalidMountPath;
}
unnormalizedObj = Tcl_ObjPrintf(ZIPFS_VOLUME "%s", joinedPath + 1);
@@ -1099,10 +1098,16 @@ MapPathToZipfs(Tcl_Interp *interp,
joiner[0] = mountPath;
joiner[1] = path;
+#ifndef _WIN32
+ /* On Unix C:/foo/bat is not treated as absolute by JoinPath so check ourself */
+ if (path[0] && path[1] == ':') {
+ joiner[1] += 2;
+ }
+#endif
joinedPath = Tcl_JoinPath(2, joiner, dsPtr);
if (strncmp(ZIPFS_VOLUME, joinedPath, ZIPFS_VOLUME_LEN)) {
- /* path was not relative. Strip off the volume */
+ /* path was not relative. Strip off the volume (e.g. UNC) */
Tcl_Size numParts;
const char **partsPtr;
Tcl_SplitPath(path, &numParts, &partsPtr);
@@ -2347,26 +2352,52 @@ TclZipfs_Mount(
ret = DescribeMounted(interp, mountPoint);
Unlock();
} else {
+ /* Have both a mount point and a file (name) to mount there. */
+
+ Tcl_Obj *zipPathObj;
+ Tcl_Obj *normZipPathObj;
+
Unlock();
- /* Have both a mount point and a file (name) to mount there. */
- if (passwd == NULL ||
- (ret = IsPasswordValid(interp, passwd, strlen(passwd))) == TCL_OK) {
- zf = AllocateZipFile(interp, strlen(mountPoint));
- if (zf == NULL) {
- ret = TCL_ERROR;
- } else {
- ret = ZipFSOpenArchive(interp, zipname, 1, zf);
- if (ret != TCL_OK) {
- ckfree(zf);
- } else {
- ret = ZipFSCatalogFilesystem(
- interp, zf, mountPoint, passwd, zipname);
- /* Note zf is already freed on error! */
+ zipPathObj = Tcl_NewStringObj(zipname, -1);
+ Tcl_IncrRefCount(zipPathObj);
+ normZipPathObj = Tcl_FSGetNormalizedPath(interp, zipPathObj);
+ if (normZipPathObj == NULL) {
+ Tcl_SetObjResult(
+ interp,
+ Tcl_ObjPrintf("could not normalize zip filename \"%s\"", zipname));
+ Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NORMALIZE", NULL);
+ ret = TCL_ERROR;
+ } else {
+ Tcl_IncrRefCount(normZipPathObj);
+ const char *normPath = Tcl_GetString(normZipPathObj);
+ if (passwd == NULL ||
+ (ret = IsPasswordValid(interp, passwd, strlen(passwd))) ==
+ TCL_OK) {
+ zf = AllocateZipFile(interp, strlen(mountPoint));
+ if (zf == NULL) {
+ ret = TCL_ERROR;
+ }
+ else {
+ ret = ZipFSOpenArchive(interp, normPath, 1, zf);
+ if (ret != TCL_OK) {
+ ckfree(zf);
+ }
+ else {
+ ret = ZipFSCatalogFilesystem(
+ interp, zf, mountPoint, passwd, normPath);
+ /* Note zf is already freed on error! */
+ }
}
}
+ Tcl_DecrRefCount(normZipPathObj);
+ if (ret == TCL_OK && interp) {
+ Tcl_DStringResult(interp, &ds);
+ }
}
+ Tcl_DecrRefCount(zipPathObj);
}
+
Tcl_DStringFree(&ds);
return ret;
}
@@ -2377,7 +2408,7 @@ TclZipfs_Mount(
* TclZipfs_MountBuffer --
*
* This procedure is invoked to mount a given ZIP archive file on a given
- * mountpoint with optional ZIP password.
+ * mountpoint.
*
* Results:
* A standard Tcl result.
@@ -2472,6 +2503,9 @@ TclZipfs_MountBuffer(
ret = ZipFSCatalogFilesystem(
interp, zf, mountPoint, NULL, "Memory Buffer");
}
+ if (ret == TCL_OK && interp) {
+ Tcl_DStringResult(interp, &ds);
+ }
}
done:
@@ -2581,7 +2615,6 @@ ZipFSMountObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
const char *mountPoint = NULL, *zipFile = NULL, *password = NULL;
- Tcl_Obj *zipFileObj = NULL;
int result;
if (objc > 4) {
@@ -2598,16 +2631,7 @@ ZipFSMountObjCmd(
mountPoint = Tcl_GetString(objv[1]);
} else {
/* 2 < objc < 4 */
- zipFileObj = Tcl_FSGetNormalizedPath(interp, objv[1]);
- if (!zipFileObj) {
- Tcl_SetObjResult(
- interp,
- Tcl_NewStringObj("could not normalize zip filename", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NORMALIZE", NULL);
- return TCL_ERROR;
- }
- Tcl_IncrRefCount(zipFileObj);
- zipFile = Tcl_GetString(zipFileObj);
+ zipFile = Tcl_GetString(objv[1]);
mountPoint = Tcl_GetString(objv[2]);
if (objc > 3) {
password = Tcl_GetString(objv[3]);
@@ -2616,9 +2640,6 @@ ZipFSMountObjCmd(
}
result = TclZipfs_Mount(interp, zipFile, mountPoint, password);
- if (zipFileObj != NULL) {
- Tcl_DecrRefCount(zipFileObj);
- }
return result;
}
@@ -3964,7 +3985,7 @@ ZipFSCanonicalObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- char *mntPoint = NULL;
+ const char *mntPoint = NULL;
Tcl_DString dsPath, dsMount;
if (objc < 2 || objc > 3) {