From: Wojciech Kocjan <zoro2@users.sourceforge.net>
Date: Wed, 4 Jul 2012 12:40:29 +0000 (+0000)
Subject: 	* zipvfs.tcl: Fix for streaming not working properly in certain zip
X-Git-Url: http://test.brassandglass.co.uk/gitweb?a=commitdiff_plain;h=e19e3679f984fe416f2ab9d93859315008d58fe9;p=tclvfs

	* zipvfs.tcl: Fix for streaming not working properly in certain zip
	files; refactoring of zip::Data to reuse header parsing code for streams
---

diff --git a/ChangeLog b/ChangeLog
index 11d4321..1075db4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-04  Wojciech Kocjan <zoro2@users.sourceforge.net>
+
+	* 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 <zoro2@users.sourceforge.net>
 
 	* 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