summaryrefslogtreecommitdiffstats
path: root/generic/tclZipfs.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-30 23:59:46 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2018-12-30 23:59:46 (GMT)
commit0813e41bab07c15f4ddebfbf81eef669f4da6e37 (patch)
tree6d771c8e7cacd124fa9232a4ea0dfb0b7d999940 /generic/tclZipfs.c
parent899be54b87e35cb83ff377608dd7b802254e99cb (diff)
downloadtcl-0813e41bab07c15f4ddebfbf81eef669f4da6e37.zip
tcl-0813e41bab07c15f4ddebfbf81eef669f4da6e37.tar.gz
tcl-0813e41bab07c15f4ddebfbf81eef669f4da6e37.tar.bz2
Fix [44d382c51a848e6fbe7c9ee15e9386f1237660ee|44d382c51a84]: ZIP filesystem time stamp conversion wrong etc.
Diffstat (limited to 'generic/tclZipfs.c')
-rw-r--r--generic/tclZipfs.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index 78eec7e..d02a2da 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -552,12 +552,13 @@ DosTimeDate(
struct tm tm;
time_t ret;
- memset(&tm, 0, sizeof(struct tm));
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_isdst = -1; /* let mktime() deal with DST */
tm.tm_year = ((dosDate & 0xfe00) >> 9) + 80;
tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1;
tm.tm_mday = dosDate & 0x1f;
tm.tm_hour = (dosTime & 0xf800) >> 11;
- tm.tm_min = (dosTime & 0x7e) >> 5;
+ tm.tm_min = (dosTime & 0x7e0) >> 5;
tm.tm_sec = (dosTime & 0x1f) << 1;
ret = mktime(&tm);
if (ret == (time_t) -1) {
@@ -3725,7 +3726,7 @@ ZipChannelOpen(
unsigned char *zbuf = z->zipFilePtr->data + z->offset;
if (z->isEncrypted) {
- int len = z->zipFilePtr->passBuf[0];
+ int len = z->zipFilePtr->passBuf[0] & 0xFF;
char passBuf[260];
for (i = 0; i < len; i++) {
@@ -3826,7 +3827,7 @@ ZipChannelOpen(
info->numBytes = z->numBytes;
info->maxWrite = 0;
if (info->isEncrypted) {
- int len = z->zipFilePtr->passBuf[0];
+ int len = z->zipFilePtr->passBuf[0] & 0xFF;
char passBuf[260];
for (i = 0; i < len; i++) {
@@ -3914,6 +3915,31 @@ ZipChannelOpen(
Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "CORRUPT", NULL);
}
goto error;
+ } else if (info->isEncrypted) {
+ unsigned char *ubuf = NULL;
+ unsigned int j, len;
+
+ /*
+ * Decode encrypted but uncompressed file, since we support
+ * Tcl_Seek() on it, and it can be randomly accessed later.
+ */
+
+ len = z->numCompressedBytes - 12;
+ ubuf = (unsigned char *) attemptckalloc(len);
+ if (ubuf == NULL) {
+ ckfree((char *) info);
+ if (interp != NULL) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("out of memory", -1));
+ }
+ goto error;
+ }
+ for (j = 0; j < len; j++) {
+ ch = info->ubuf[j];
+ ubuf[j] = zdecode(info->keys, crc32tab, ch);
+ }
+ info->ubuf = ubuf;
+ info->isEncrypted = 0;
}
}
@@ -4508,7 +4534,7 @@ ZipFSFileAttrsGetProc(
*objPtrRef = Tcl_NewStringObj(z->zipFilePtr->name, -1);
break;
case 5:
- *objPtrRef = Tcl_NewStringObj("0555", -1);
+ *objPtrRef = Tcl_NewStringObj("0o555", -1);
break;
default:
ZIPFS_ERROR(interp, "unknown attribute");