From 74a6deea150b6a807892deaef25264195952b565 Mon Sep 17 00:00:00 2001 From: apnadkarni Date: Wed, 27 Sep 2023 03:29:39 +0000 Subject: Finish up [23dd83ce7c] tests and fixes. --- generic/tclZipfs.c | 37 ++++++++++++++++++++++++++----------- tests/zipfs.test | 10 ++++++---- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 333c278..cb8792f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4588,16 +4588,26 @@ ZipChannelOpen( } if (!trunc) { flags |= TCL_READABLE; - if (z->isEncrypted && (z->zipFilePtr->passBuf[0] == 0)) { - ZIPFS_ERROR(interp, "decryption failed"); - ZIPFS_ERROR_CODE(interp, "DECRYPT"); - goto error; - } else if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) { - ZIPFS_ERROR(interp, "file too large"); - ZIPFS_ERROR_CODE(interp, "FILE_SIZE"); + if (z->isEncrypted) { + if (z->numCompressedBytes < 12) { + ZIPFS_ERROR(interp, "decryption failed: truncated decryption header"); + ZIPFS_ERROR_CODE(interp, "DECRYPT"); + goto error; + + } + if (z->zipFilePtr->passBuf[0] == 0) { + ZIPFS_ERROR(interp, "decryption failed - no password provided"); + ZIPFS_ERROR_CODE(interp, "DECRYPT"); + 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; } @@ -4711,7 +4721,8 @@ InitWritableChannel( info->isWriting = 1; info->maxWrite = ZipFS.wrmax; - info->ubufToFree = (unsigned char *) attemptckalloc(info->maxWrite); + info->ubufToFree = + (unsigned char *)attemptckalloc(info->maxWrite ? info->maxWrite : 1); info->ubuf = info->ubufToFree; if (!info->ubuf) { goto memoryError; @@ -4772,8 +4783,11 @@ InitWritableChannel( if (z->isEncrypted) { unsigned int j; + /* Min length 12 for keys should already been checked. */ + assert(stream.avail_in >= 12); + stream.avail_in -= 12; - cbuf = (unsigned char *) attemptckalloc(stream.avail_in); + cbuf = (unsigned char *) attemptckalloc(stream.avail_in ? stream.avail_in : 1); if (!cbuf) { goto memoryError; } @@ -4929,8 +4943,9 @@ InitReadableChannel( stream.opaque = Z_NULL; stream.avail_in = z->numCompressedBytes; if (info->isEncrypted) { + assert(stream.avail_in >= 12); stream.avail_in -= 12; - ubuf = (unsigned char *) attemptckalloc(stream.avail_in); + ubuf = (unsigned char *) attemptckalloc(stream.avail_in ? stream.avail_in : 1); if (!ubuf) { goto memoryError; } @@ -4944,7 +4959,7 @@ InitReadableChannel( stream.next_in = info->ubuf; } info->ubufToFree = (unsigned char *) - attemptckalloc(info->numBytes); + attemptckalloc(info->numBytes ? info->numBytes : 1); info->ubuf = info->ubufToFree; stream.next_out = info->ubuf; if (!info->ubuf) { diff --git a/tests/zipfs.test b/tests/zipfs.test index efbd233..b9d44f9 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -567,7 +567,7 @@ namespace eval test_ns_zipfs { lappend result [string equal $chans [lsort [chan names]]] } -cleanup { cleanup - } -result {1 {decryption failed} 1} + } -result {1 {decryption failed - no password provided} 1} test zipfs-mount-password-3 "mount - verify compressed cipher unreadable without password" -body { zipfs mount [zippath test-password.zip] $defaultMountPoint @@ -578,7 +578,7 @@ namespace eval test_ns_zipfs { lappend result [string equal $chans [lsort [chan names]]] } -cleanup { cleanup - } -result {1 {decryption failed} 1} + } -result {1 {decryption failed - no password provided} 1} test zipfs-mount-nested-1 "mount - nested mount on non-existing path" -setup { mount [zippath test.zip] @@ -966,6 +966,7 @@ namespace eval test_ns_zipfs { testzipfsread stored test.zip test test testzipfsread stored teststored.zip aaaaaaaaaaaaaa testzipfsread deflate testdeflated2.zip aaaaaaaaaaaaaa + testzipfsread bug-23dd83ce7c empty.zip {} empty.txt # Test open modes - see bug [4645658689] testzipfsread stored-rw teststored.zip aaaaaaaaaaaaaa abac-repeat.txt r+ testzipfsread deflate-rw testdeflated2.zip aaaaaaaaaaaaaa abac-repeat.txt r+ @@ -1042,6 +1043,7 @@ namespace eval test_ns_zipfs { testzipfswrite deflate-a testdeflated2.zip "append mode not supported: permission denied" abac-repeat.txt a -returnCodes error testzipfswrite store-ar teststored.zip "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nxyz" abac-repeat.txt a+ testzipfswrite deflate-ar testdeflated2.zip "aaaaaaaaaaaaaa\nbbbbbbbbbbbbbb\naaaaaaaaaaaaaa\ncccccccccccccc\nxyz" abac-repeat.txt a+ + testzipfswrite bug-23dd83ce7c-w empty.zip "xyz" empty.txt w test zipfs-write-unreadable "Reads not allowed on file opened for write" -setup { mount [zippath test.zip] @@ -1199,10 +1201,10 @@ namespace eval test_ns_zipfs { testpassword plain-nopassword plain.txt "" plaintext testpassword plain-badpassword plain.txt xxx plaintext testpassword cipher cipher.bin password ciphertext -constraints bug-bbe7c6ff9e - testpassword cipher-nopassword cipher.bin {} "decryption failed" -returnCodes error + testpassword cipher-nopassword cipher.bin {} "decryption failed - no password provided" -returnCodes error testpassword cipher-badpassword cipher.bin xxx "invalid CRC" -returnCodes error testpassword cipher-deflate cipher-deflate.bin password [lseq 100] -constraints bug-bbe7c6ff9e - testpassword cipher-deflate-nopassword cipher-deflate.bin {} "decryption failed" -returnCodes error + testpassword cipher-deflate-nopassword cipher-deflate.bin {} "decryption failed - no password provided" -returnCodes error testpassword cipher-deflate-badpassword cipher-deflate.bin xxx "decompression error" -returnCodes error # -- cgit v0.12