diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-12-30 23:59:46 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-12-30 23:59:46 (GMT) |
commit | 0813e41bab07c15f4ddebfbf81eef669f4da6e37 (patch) | |
tree | 6d771c8e7cacd124fa9232a4ea0dfb0b7d999940 /generic/tclZipfs.c | |
parent | 899be54b87e35cb83ff377608dd7b802254e99cb (diff) | |
download | tcl-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.c | 36 |
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"); |