diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-12-31 00:04:59 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2018-12-31 00:04:59 (GMT) |
commit | c094536030e27841605612e51a67f46f1f0ff549 (patch) | |
tree | bdf29ea286b478a74b3a339ca09492d3133097a9 /generic/tclZipfs.c | |
parent | 72fb39bd82318b35f92d430df9bc5388b5c708ee (diff) | |
parent | 0813e41bab07c15f4ddebfbf81eef669f4da6e37 (diff) | |
download | tcl-c094536030e27841605612e51a67f46f1f0ff549.zip tcl-c094536030e27841605612e51a67f46f1f0ff549.tar.gz tcl-c094536030e27841605612e51a67f46f1f0ff549.tar.bz2 |
Merge 8.7
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 4a4faa7..c9a58df 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -546,12 +546,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) { @@ -3719,7 +3720,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++) { @@ -3820,7 +3821,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++) { @@ -3908,6 +3909,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 *) Tcl_AttemptAlloc(len); + if (ubuf == NULL) { + Tcl_Free((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; } } @@ -4502,7 +4528,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"); |