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:

In the following script, the $src gains two new characters at the end each time a zlib transform is pushed and then popped:

#! /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

User Comments: dkf added on 2024-05-27 09:38:02:

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:

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)