Tcl Source Code

View Ticket
Login
Ticket UUID: 9ee9f4d7be4615e04f62fe22885dadce13ca4d01
Title: zlib push/pop corrupts underlying channel
Type: Bug Version: various
Submitter: pooryorick Created on: 2020-06-16 15:10:37
Subsystem: 57. zlib Assigned To: dkf
Priority: 7 High Severity: Important
Status: Open Last Modified: 2024-05-27 09:38:02
Resolution: None Closed By: nobody
    Closed on:
Description: (text/x-fossil-wiki)
In the following script, the $src gains two new characters at the end each
time a zlib transform is pushed and then popped:

<code><pre>
#! /usr/bin/env tclsh

set data hello
set src [file tempfile]
puts -nonewline $src $data
flush $src
chan configure $src -translation binary

set dst [file tempfile]
chan configure $dst -translation binary

for {set i 0} {$i < 10} {incr i} {
    # Determine size of src channel
    seek $src 0 end
    set size [chan tell $src]
    seek $src 0 start
    # Determine size of content in src channel
    set data [read $src]
    set size2 [string length $data]
    seek $src 0 start
    # Copy src over to dst, keep dst empty
    zlib push deflate $src -level 6
    chan truncate $dst 0
    chan copy $src $dst
    chan pop $src
    # Show sizes
    puts [list $size $size2]
}
close $src
close $dst

</pre></code>
User Comments: dkf added on 2024-05-27 09:38:02: (text/x-markdown)
OK, the "problem" is that you're applying a compressor to a channel being read (a case we don't handle) yet the channel is really read-write so the flush on close (or pop) writes the header to it. **Doing `zlib push deflate` creates a channel filter that activates on output.**

I'm not quite sure what to do about this yet.

dkf added on 2024-05-25 13:54:01: (text/x-markdown)
This appears to be due to the compression header. For `deflate` that's two bytes. It's rather more for `compress` and `gzip`.

It's quite odd that you're compressing on reading data into Tcl. I wonder if that's related?

(This is now test `zlib-14.1`)