summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclZipfs.c77
-rw-r--r--tests/zipfs.test14
2 files changed, 41 insertions, 50 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index cb8792f..ad65e72 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -4535,14 +4535,27 @@ static Tcl_Channel
ZipChannelOpen(
Tcl_Interp *interp, /* Current interpreter. */
char *filename, /* What are we opening. */
- int wr, /* True if we're opening in write mode. */
- int trunc) /* True if we're opening in truncate mode. */
+ int mode) /* O_WRONLY O_RDWR O_TRUNC flags */
{
ZipEntry *z;
ZipChannel *info;
int flags = 0;
char cname[128];
+ int wr = (mode & (O_WRONLY | O_RDWR)) != 0;
+
+ /* Check for unsupported modes. */
+
+ if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && wr)) {
+ Tcl_SetErrno(EACCES);
+ if (interp) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%s not supported: %s",
+ mode & O_APPEND ? "append mode" : "write access",
+ Tcl_PosixError(interp)));
+ }
+ return NULL;
+ }
/*
* Is the file there?
*/
@@ -4586,8 +4599,20 @@ ZipChannelOpen(
ZIPFS_ERROR_CODE(interp, "COMP_METHOD");
goto error;
}
- if (!trunc) {
+ if (wr) {
+ if ((mode & O_TRUNC) == 0 && !z->data && (z->numBytes > ZipFS.wrmax)) {
+ Tcl_SetErrno(EFBIG);
+ ZIPFS_POSIX_ERROR(interp, "file size exceeds max writable");
+ goto error;
+ }
+ flags = TCL_WRITABLE;
+ if (mode & O_RDWR)
+ flags |= TCL_READABLE;
+ } else {
+ /* Read-only */
flags |= TCL_READABLE;
+ }
+ if (flags & TCL_READABLE) {
if (z->isEncrypted) {
if (z->numCompressedBytes < 12) {
ZIPFS_ERROR(interp, "decryption failed: truncated decryption header");
@@ -4601,14 +4626,6 @@ ZipChannelOpen(
goto error;
}
}
- if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) {
- Tcl_SetErrno(EFBIG);
- ZIPFS_POSIX_ERROR(interp, "file size exceeds max writable");
- goto error;
- }
- } else {
- /* If truncating anyways, we do not care about error checking */
- flags = TCL_WRITABLE;
}
info = AllocateZipChannel(interp);
@@ -4618,31 +4635,23 @@ ZipChannelOpen(
info->zipFilePtr = z->zipFilePtr;
info->zipEntryPtr = z;
if (wr) {
- /*
- * Set up a writable channel.
- */
+ /* Set up a writable channel. */
- flags |= TCL_WRITABLE;
- if (InitWritableChannel(interp, info, z, trunc) == TCL_ERROR) {
+ if (InitWritableChannel(interp, info, z, mode & O_TRUNC) == TCL_ERROR) {
ckfree(info);
goto error;
}
} else if (z->data) {
- /*
- * Set up a readable channel for direct data.
- */
+ /* Set up a readable channel for direct data. */
- flags |= TCL_READABLE;
info->numBytes = z->numBytes;
info->ubuf = z->data;
info->ubufToFree = NULL; /* Not dynamically allocated */
- }
- else {
+ } else {
/*
* Set up a readable channel.
*/
- flags |= TCL_READABLE;
if (InitReadableChannel(interp, info, z) == TCL_ERROR) {
ckfree(info);
goto error;
@@ -5155,27 +5164,9 @@ ZipFSOpenFileChannelProc(
return NULL;
}
- int trunc = (mode & O_TRUNC) != 0;
- int wr = (mode & (O_WRONLY | O_RDWR)) != 0;
-
- /*
- * Check for unsupported modes.
- */
-
- if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && wr)) {
- Tcl_SetErrno(EACCES);
- if (interp) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "%s not supported: %s",
- mode & O_APPEND ? "append mode" : "write access",
- Tcl_PosixError(interp)));
- }
- return NULL;
- }
-
- return ZipChannelOpen(interp, Tcl_GetString(pathPtr), wr, trunc);
+ return ZipChannelOpen(interp, Tcl_GetString(pathPtr), mode);
}
-
+
/*
*-------------------------------------------------------------------------
*
diff --git a/tests/zipfs.test b/tests/zipfs.test
index 333426e..705f26f 100644
--- a/tests/zipfs.test
+++ b/tests/zipfs.test
@@ -1137,7 +1137,7 @@ namespace eval test_ns_zipfs {
append result [gets $fd],
set pos [tell $fd]
append result $pos,
- puts -nonewline $fd "xyz"
+ puts -nonewline $fd "0123456789"
append result [gets $fd],
seek $fd $pos
append result [gets $fd],
@@ -1172,12 +1172,12 @@ namespace eval test_ns_zipfs {
} -body $body -result $expected {*}$args
}
- testzipfsrw store-r+ teststored.zip "aaaaaaaaaaaaaa,15,bbbbbbbbbbb,xyzbbbbbbbbbbb,ccccc\n|aaaaaaaaaaaaaa\nxyzbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
- testzipfsrw store-w+ teststored.zip ",0,,xyz,yz|" abac-repeat.txt w+ -constraints bug-00018ec7a0
- testzipfsrw store-a+ teststored.zip ",60,,xyz,cc\nxyz|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nxyz" abac-repeat.txt a+
- testzipfsrw deflate-r+ testdeflated2.zip "aaaaaaaaaaaaaa,15,bbbbbbbbbbb,xyzbbbbbbbbbbb,ccccc\n|aaaaaaaaaaaaaa\nxyzbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
- testzipfsrw deflate-w+ testdeflated2.zip ",0,,xyz,yz|" abac-repeat.txt w+ -constraints bug-00018ec7a0
- testzipfsrw deflate-a+ testdeflated2.zip ",60,,xyz,cc\nxyz|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nxyz" abac-repeat.txt a+
+ testzipfsrw store-r+ teststored.zip "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
+ testzipfsrw store-w+ teststored.zip ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
+ testzipfsrw store-a+ teststored.zip ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
+ testzipfsrw deflate-r+ testdeflated2.zip "aaaaaaaaaaaaaa,15,bbbb,0123456789bbbb,ccccc\n|aaaaaaaaaaaaaa\n0123456789bbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n" abac-repeat.txt r+
+ testzipfsrw deflate-w+ testdeflated2.zip ",0,,0123456789,456789|0123456789" abac-repeat.txt w+
+ testzipfsrw deflate-a+ testdeflated2.zip ",60,,0123456789,456789|aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\n0123456789" abac-repeat.txt a+
test zipfs-rw-bug-f91ee30d33 "Bug f91ee30d33 - truncates at last read" -setup {
mount [zippath test.zip]
} -cleanup {