tclvfs-20080503-zipvfs.diff at [75999463a7]

File tclvfs/patches/all/tclvfs-20080503-zipvfs.diff artifact f1ca9abb3e part of check-in 75999463a7


diff -uNr tclvfs-20080503.orig/library/zipvfs.tcl tclvfs-20080503-1rsk/library/zipvfs.tcl
--- tclvfs-20080503.orig/library/zipvfs.tcl	2008-04-15 16:11:53.000000000 -0500
+++ tclvfs-20080503-1rsk/library/zipvfs.tcl	2010-10-01 21:48:38.000000000 -0500
@@ -107,6 +107,10 @@
 	    
 	    ::zip::stat $zipfd $name sb
 
+            if {$sb(ino) == -1} {
+                vfs::filesystem posixerror $::vfs::posix(EISDIR)
+            }
+
 	    set nfd [vfs::memchan]
 	    fconfigure $nfd -translation binary
 
@@ -255,21 +259,21 @@
     set year [expr { (($date >> 9) & 0xFF) + 1980 }]
 
     # Fix up bad date/time data, no need to fail
-    while {$sec  > 59} {incr sec  -60}
-    while {$min  > 59} {incr sec  -60}
-    while {$hour > 23} {incr hour -24}
-    if {$mday < 1}  {incr mday}
-    if {$mon  < 1}  {incr mon}
-    while {$mon > 12} {incr hour -12}
+    if {$sec  > 59} {set sec  59}
+    if {$min  > 59} {set min  59}
+    if {$hour > 23} {set hour 23}
+    if {$mday < 1}  {set mday 1}
+    if {$mday > 31} {set mday 31}
+    if {$mon  < 1}  {set mon  1}
+    if {$mon > 12}  {set mon  12}
 
-    while {[catch {
+    set res 0
+    catch {
 	set dt [format {%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d} \
 		    $year $mon $mday $hour $min $sec]
 	set res [clock scan $dt -gmt 1]
-    }]} {
-	# Only mday can be wrong, at end of month
-	incr mday -1
     }
+
     return $res
 }
 
@@ -360,6 +364,11 @@
     # after the whole file has been searched.
 
     set sz  [tell $fd]
+    if {[info exists ::zip::max_header_seek]} {
+        if {$::zip::max_header_seek < $sz} {
+            set sz $::zip::max_header_seek
+        }
+    }
     set len 512
     set at  512
     while {1} {
@@ -381,7 +390,12 @@
     }
 
     set hdr [string range $hdr [expr $pos + 4] [expr $pos + 21]]
-    set pos [expr [tell $fd] + $pos - 512]
+
+    set seekstart [expr {[tell $fd] - 512}]
+    if {$seekstart < 0} {
+        set seekstart 0
+    }
+    set pos [expr {$seekstart + $pos}]
 
     binary scan $hdr ssssiis \
 	cb(ndisk) cb(cdisk) \
@@ -396,10 +410,15 @@
 
     # Compute base for situations where ZIP file
     # has been appended to another media (e.g. EXE)
-    set cb(base)	[expr { $pos - $cb(csize) - $cb(coff) }]
+    set base            [expr { $pos - $cb(csize) - $cb(coff) }]
+    if {$base < 0} {
+        set base 0
+    }
+    set cb(base)	$base
 }
 
 proc zip::TOC {fd arr} {
+    upvar #0 zip::$fd cb
     upvar 1 $arr sb
 
     set buf [read $fd 46]
@@ -410,6 +429,8 @@
       flen elen clen sb(disk) sb(attr) \
       sb(atx) sb(ino)
 
+    set sb(ino) [expr {$cb(base) + $sb(ino)}]
+
     if { ![string equal "PK\01\02" $hdr] } {
 	binary scan $hdr H* x
 	error "bad central header: $x"
@@ -442,7 +463,7 @@
 	
 	zip::EndOfArchive $fd cb
 
-	seek $fd $cb(coff) start
+	seek $fd [expr {$cb(base) + $cb(coff)}] start
 
 	set toc(_) 0; unset toc(_); #MakeArray