summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-09-26 06:03:16 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-09-26 06:03:16 (GMT)
commitafc5ad1a567d39ead1f64e744057a5b3000245b2 (patch)
tree7eb1d5a72cd7190e16b91762848632c3bf8eee04
parentdf59028204b80f900fdda62c0f45142b742fc5fb (diff)
parentb730c0e5a483d8a0a348f211aadf08ec8e19be70 (diff)
downloadtcl-afc5ad1a567d39ead1f64e744057a5b3000245b2.zip
tcl-afc5ad1a567d39ead1f64e744057a5b3000245b2.tar.gz
tcl-afc5ad1a567d39ead1f64e744057a5b3000245b2.tar.bz2
Merge 8.7 - Bug [d5d03207ca] - Tcl hang on zipfs writes greater than buffer size
-rw-r--r--generic/tclZipfs.c15
-rw-r--r--tests/zipfs.test33
2 files changed, 36 insertions, 12 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index f65d27a..6c4356d 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -4324,18 +4324,17 @@ ZipChannelWrite(
ZipChannel *info = (ZipChannel *) instanceData;
unsigned long nextpos;
- if (!info->isWriting) {
+ if (toWrite == 0 || !info->isWriting) {
*errloc = EINVAL;
return -1;
}
- nextpos = info->numRead + toWrite;
- if (nextpos > info->maxWrite) {
- toWrite = info->maxWrite - info->numRead;
- nextpos = info->maxWrite;
- }
- if (toWrite == 0) {
- return 0;
+ assert(info->maxWrite >= info->numRead);
+ if (toWrite > (int) (info->maxWrite - info->numRead)) {
+ /* Don't do partial writes in error case. Or should we? */
+ *errloc = EFBIG;
+ return -1;
}
+ nextpos = info->numRead + toWrite;
memcpy(info->ubuf + info->numRead, buf, toWrite);
info->numRead = nextpos;
if (info->numRead > info->numBytes) {
diff --git a/tests/zipfs.test b/tests/zipfs.test
index 52dbcf1..5012c5b 100644
--- a/tests/zipfs.test
+++ b/tests/zipfs.test
@@ -1073,7 +1073,7 @@ namespace eval test_ns_zipfs {
set result
} -result [list newtext test\n]
- test zipfs-write-size-limit-0 "Writes have a size limit" -setup {
+ test zipfs-write-size-limit-0 "Writes more than size limit with flush" -setup {
set origlimit $::tcl::zipfs::wrmax
mount [zippath test.zip]
} -cleanup {
@@ -1083,10 +1083,35 @@ namespace eval test_ns_zipfs {
} -body {
set ::tcl::zipfs::wrmax 10
set fd [open [file join $defaultMountPoint test] w]
- puts -nonewline $fd [string repeat x 11]
- } -result {} -returnCodes error -constraints bug-d5d03207ca
+ puts $fd [string repeat x 11]
+ flush $fd
+ } -result {error flushing *: file too large} -match glob -returnCodes error
- test zipfs-write-size-limit-1 "Writes disallowed" -setup {
+ test zipfs-write-size-limit-1 "Writes size limit on close" -setup {
+ set origlimit $::tcl::zipfs::wrmax
+ mount [zippath test.zip]
+ } -cleanup {
+ set ::tcl::zipfs::wrmax $origlimit
+ cleanup
+ } -body {
+ set ::tcl::zipfs::wrmax 10
+ set fd [open [file join $defaultMountPoint test] w]
+ puts $fd [string repeat x 11]
+ close $fd
+ } -result {file too large} -match glob -returnCodes error
+
+ test zipfs-write-size-limit-2 "Writes max size" -setup {
+ mount [zippath test.zip]
+ } -cleanup {
+ cleanup
+ } -body {
+ set fd [open [file join $defaultMountPoint test] w]
+ puts -nonewline $fd [string repeat x $::tcl::zipfs::wrmax]
+ close $fd
+ file size [file join $defaultMountPoint test]
+ } -result $::tcl::zipfs::wrmax
+
+ test zipfs-write-size-limit-3 "Writes disallowed" -setup {
set origlimit $::tcl::zipfs::wrmax
mount [zippath test.zip]
} -cleanup {