2010-12-29 Steve Huntley <stephen.huntley@alum.mit.edu>
authorSteve Huntley <stephen.huntley@alum.mit.edu>
Wed, 29 Dec 2010 09:57:43 +0000 (09:57 +0000)
committerSteve Huntley <stephen.huntley@alum.mit.edu>
Wed, 29 Dec 2010 09:57:43 +0000 (09:57 +0000)
* generic/vfs.c: include sys/stat.h so build under MinGW64 will succeed.
See bug #3107382.
* library/zipvfs.tcl: Fixed issues with clock handling, dealing with
trying to [open] a directory, reading a zip file that has been appended
to another file.  See bugs 31036873107380

ChangeLog
generic/vfs.c
library/zipvfs.tcl

index b261d85f4c7f7e51f2223dc4e74ee110657cfc7e..bfbe27cd7d0b775c3c1be475fd63ec3cd632b7ca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-12-29  Steve Huntley  <stephen.huntley@alum.mit.edu>
+
+       * generic/vfs.c: include sys/stat.h so build under MinGW64 will succeed.
+       See bug #3107382.
+       * library/zipvfs.tcl: Fixed issues with clock handling, dealing with 
+       trying to [open] a directory, reading a zip file that has been appended
+       to another file.  See bugs 3103687, 3107380
+
 2010-05-16  Steve Huntley  <stephen.huntley@alum.mit.edu>
 
        * library/vfslib.tcl: Changed memchan condition from Tcl version 8.6 or
index effcfdce1e014598f244f2d8a84c6bc29903fa6b..5ff2459153062dbcfa0f0d78a59892f426a0c602 100644 (file)
@@ -20,6 +20,9 @@
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  */
 
+#ifdef HAVE_SYS_STAT_H
+#  include <sys/stat.h>
+#endif
 #include <tcl.h>
 /* Required to access the 'stat' structure fields, and TclInExit() */
 #include "tclInt.h"
index 45cfbed993e8784d3ecaf33a4d62ba41b724a02c..741380c9ecf10d8757306f4bcf6784c1a46a2838 100644 (file)
@@ -107,6 +107,10 @@ proc vfs::zip::open {zipfd name mode permissions} {
            
            ::zip::stat $zipfd $name sb
 
+            if {$sb(ino) == -1} {
+                vfs::filesystem posixerror $::vfs::posix(EISDIR)
+            }
+
            set nfd [vfs::memchan]
            fconfigure $nfd -translation binary
 
@@ -263,21 +267,21 @@ proc zip::DosTime {date time} {
     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}
-
-    while {[catch {
+    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}
+
+    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
 }
 
@@ -377,6 +381,11 @@ proc zip::EndOfArchive {fd arr} {
     # 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} {
@@ -403,8 +412,13 @@ proc zip::EndOfArchive {fd arr} {
        }
     }
 
-    set hdr [string range $hdr [expr {$pos + 4}] [expr {$pos + 21}]]
-    set pos [expr {[tell $fd] + $pos - 512}]
+    set hdr [string range $hdr [expr $pos + 4] [expr $pos + 21]]
+     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) \
@@ -419,10 +433,15 @@ proc zip::EndOfArchive {fd arr} {
 
     # 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]
@@ -433,6 +452,8 @@ proc zip::TOC {fd arr} {
       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
        return -code error "bad central header: $x"
@@ -473,7 +494,7 @@ proc zip::open {path} {
        
        zip::EndOfArchive $fd cb
 
-       seek $fd $cb(coff) start
+       seek $fd [expr {$cb(base) + $cb(coff)}] start
 
        set toc(_) 0; unset toc(_); #MakeArray