From e19e3679f984fe416f2ab9d93859315008d58fe9 Mon Sep 17 00:00:00 2001 From: Wojciech Kocjan Date: Wed, 4 Jul 2012 12:40:29 +0000 Subject: [PATCH] * zipvfs.tcl: Fix for streaming not working properly in certain zip files; refactoring of zip::Data to reuse header parsing code for streams --- ChangeLog | 5 +++++ library/zipvfs.tcl | 39 ++++++++++++++++----------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 11d4321..1075db4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-07-04 Wojciech Kocjan + + * zipvfs.tcl: Fix for streaming not working properly in certain zip + files; refactoring of zip::Data to reuse header parsing code for streams + 2012-03-15 Wojciech Kocjan * zipvfs.tcl: Fix for zip symlinks not supported anymore, bug 3505283 diff --git a/library/zipvfs.tcl b/library/zipvfs.tcl index b40803a..0c5cc6e 100644 --- a/library/zipvfs.tcl +++ b/library/zipvfs.tcl @@ -128,26 +128,7 @@ proc vfs::zip::open {zipfd name mode permissions} { # return [list $nfd] # use streaming for files larger than 1MB if {$::zip::useStreaming && $sb(size) >= 1048576} { - set buf [read $zipfd 30] - set n [binary scan $buf A4sssssiiiss \ - hdr sb(ver) sb(flags) sb(method) \ - time date \ - sb(crc) sb(csize) sb(size) flen elen] - - if { ![string equal "PK\03\04" $hdr] } { - binary scan $hdr H* x - error "bad header: $x" - } - - set sb(name) [read $zipfd [::zip::u_short $flen]] - set sb(extra) [read $zipfd [::zip::u_short $elen]] - - if { $sb(flags) & 0x4 } { - # Data Descriptor used - set buf [read $zipfd 12] - binary scan $buf iii sb(crc) sb(csize) sb(size) - } - + seek $zipfd [zip::ParseDataHeader $zipfd sb] start if { $sb(method) != 0} { set nfd [::zip::zstream $zipfd $sb(csize) $sb(size)] } else { @@ -331,8 +312,9 @@ proc zip::DosTime {date time} { return $res } +proc zip::ParseDataHeader {fd arr {dataVar ""}} { + upvar 1 $arr sb -proc zip::Data {fd arr verify} { upvar 1 $arr sb # APPNOTE A: Local file header @@ -364,7 +346,13 @@ proc zip::Data {fd arr verify} { # APPNOTE B: File data # if bit 3 of flags is set the csize comes from the central directory - set data [read $fd $sb(csize)] + set offset [tell $fd] + if {$dataVar != ""} { + upvar 1 $dataVar data + set data [read $fd $sb(csize)] + } else { + seek $fd $sb(csize) current + } # APPNOTE C: Data descriptor if { $sb(flags) & (1<<3) } { @@ -379,7 +367,12 @@ proc zip::Data {fd arr verify} { set sb(csize) [expr {$sb(csize) & 0xffffffff}] set sb(size) [expr {$sb(size) & 0xffffffff}] } - + return $offset +} + +proc zip::Data {fd arr verify} { + upvar 1 $arr sb + ParseDataHeader $fd $arr data switch -exact -- $sb(method) { 0 { # stored; no compression -- 2.23.0