fixed writing of files with spaces in the name;
authorsr
Wed, 14 Jan 2009 12:37:52 +0100
changeset 2088 d7197949c371
parent 2087 6a7385a63ce0
child 2089 4f57bd937ccc
fixed writing of files with spaces in the name; fixed reading of empty files; error when trying to read unsupported compression types; code cleanup
ZipArchive.st
--- a/ZipArchive.st	Wed Jan 14 11:38:16 2009 +0100
+++ b/ZipArchive.st	Wed Jan 14 12:37:52 2009 +0100
@@ -19,9 +19,11 @@
 		C_COMPRESSED_SIZE C_RELATIVE_OFFSET_LOCAL_HEADER
 		C_FILENAME_LENGTH C_UNCOMPRESSED_SIZE C_CENTRALHEADERSIGNATURE
 		C_LOCALHEADERSIGNATURE C_CENTRALENDSIGNATURE
-		ZipFileFormatErrorSignal COMPR_STORED COMPR_SHRUNK COMPR_REDUCED1
-		COMPR_REDUCED2 COMPR_REDUCED3 COMPR_REDUCED4 COMPR_IMPLODED
-		COMPR_TOKENIZED COMPR_DEFLATED'
+		ZipFileFormatErrorSignal UnsupportedZipFileFormatErrorSignal
+		COMPR_STORED COMPR_SHRUNK COMPR_REDUCED1 COMPR_REDUCED2
+		COMPR_REDUCED3 COMPR_REDUCED4 COMPR_IMPLODED COMPR_TOKENIZED
+		COMPR_DEFLATED EXTERNALFILEATTRIBUTES_ISFILE
+		EXTERNALFILEATTRIBUTES_ISDIRECTORY'
 	poolDictionaries:''
 	category:'System-Support-FileFormats'
 !
@@ -2918,6 +2920,10 @@
 
 !ZipArchive class methodsFor:'Signal constants'!
 
+unsupportedZipFileFormatErrorSignal
+    ^ UnsupportedZipFileFormatErrorSignal
+!
+
 zipFileFormatErrorSignal
     ^ ZipFileFormatErrorSignal
 ! !
@@ -2941,6 +2947,9 @@
     C_CENTRALHEADERSIGNATURE := 16r02014b50.
     C_CENTRALENDSIGNATURE := 16r06054b50.
 
+    EXTERNALFILEATTRIBUTES_ISFILE := 32.
+    EXTERNALFILEATTRIBUTES_ISDIRECTORY := 16.
+
     "/ compression methods
     COMPR_STORED          :=  0.
     COMPR_SHRUNK          :=  1.
@@ -2956,11 +2965,16 @@
         ZipFileFormatErrorSignal := Error newSignalMayProceed:true.
         ZipFileFormatErrorSignal nameClass:self message:#zipFileFormatErrorSignal.
         ZipFileFormatErrorSignal notifierString:'unrecognized/bad zip file format'.
+
+        UnsupportedZipFileFormatErrorSignal := Error newSignalMayProceed:true.
+        UnsupportedZipFileFormatErrorSignal nameClass:self message:#unsupportedZipFileFormatErrorSignal.
+        UnsupportedZipFileFormatErrorSignal notifierString:'unsupported zip file format'.
     ].
 
     Lobby isNil ifTrue:[
         Lobby := Registry new.
     ].
+
     "
      self initialize
     "
@@ -3139,14 +3153,23 @@
 !ZipArchive methodsFor:'private'!
 
 addContentsToArchiveFrom: realFileName to: zipFileName compress: aCompressFlag
+    <resource: #obsolete>
     |fromStream zipEntry data archiveData curTime curDate theCompressMethod positionSize
      theZipFileName |
+
+    "/ sr & cg:
+    "/ is this obsolete ?
+    "/
+    "/ if not, please refactor by calling
+    "/    self addFile: aFileName fromStream: aStream compressMethod: (aCompressFlag ifTrue:COMPR_DEFLATED ifFalse:COMPR_STORED) asDirectory:false
+    "/ as this is no longer sent, is it still needed ????
+
     aCompressFlag ifTrue: [
         fromStream := realFileName readStream.
-        theCompressMethod := 8.
+        theCompressMethod := COMPR_DEFLATED.
     ] ifFalse: [
         fromStream := realFileName readStream.
-        theCompressMethod := 0.
+        theCompressMethod := COMPR_STORED.
     ].
 
     fromStream isNil ifTrue: [
@@ -3175,7 +3198,7 @@
 
     zipEntry compressionMethod: theCompressMethod.
     zipEntry internalFileAttributes: 1.
-    zipEntry externalFileAttributes: 32.
+    zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISFILE.
 
     curTime := Time now.
     curDate := Date today.
@@ -3188,8 +3211,9 @@
         zipEntry crc32: (ZipStream crc32BytesIn: data).
     ].
 
-    (theCompressMethod == 8) ifTrue: [
+    (theCompressMethod == COMPR_DEFLATED) ifTrue: [
         |tmpCompressedData tmpCompressedDataSize|
+
         tmpCompressedData := ByteArray new:(data size + 16). "/ if the compression is less then the additional overhead we need more space in buffer
         tmpCompressedDataSize := ZipStream compress:data into:tmpCompressedData.
 
@@ -3241,10 +3265,15 @@
 !
 
 addFile: aFileName withContents: data compressed: doCompressFlag
-    doCompressFlag ifFalse: [
-        ^ self addFile: aFileName withContents: data compressMethod: 0 asDirectory: false.
-    ].
-    ^ self addFile: aFileName withContents: data compressMethod: 8 asDirectory: false.
+    <resource: #obsolete>
+    "/ sr & cg:
+    "/ is this obsolete ?
+
+    ^ self 
+        addFile: aFileName 
+        withContents: data 
+        compressMethod:(doCompressFlag ifTrue:COMPR_DEFLATED ifFalse:COMPR_STORED)
+        asDirectory: false.
 !
 
 checkZipArchive:archiveFileName
@@ -3322,12 +3351,13 @@
     ].
 
     fileNameParts do:[:anElement|
-        anElement notEmptyOrNil ifTrue:[
-            (anElement includes: $ ) ifTrue:[
-                theElement := (anElement replString:' ' withString:'').
-            ] ifFalse:[
-                theElement := anElement.
-            ].
+        anElement notEmptyOrNil ifTrue:[    
+            theElement := anElement.
+"/ disabled by sr - no reason to not allow spaces in a fileName
+"/            (anElement includes:$ ) ifTrue:[ 
+"/                theElement := (anElement replString:' ' withString:'').
+"/            ].
+
             validZipFileName isNil ifTrue:[
                 validZipFileName := theElement.
             ] ifFalse:[
@@ -3863,14 +3893,18 @@
             ].
 
             nextBlockSize > 0 ifTrue: [
-                zmemb compressionMethod == 8 ifTrue:[
+                zmemb compressionMethod == COMPR_DEFLATED ifTrue:[
                     myZipStream isNil ifTrue: [
                         file binary.
                         myZipStream := ZipStream readOpenAsZipStreamOn: file.
                     ].
                     buffer := myZipStream next:nextBlockSize.
                 ] ifFalse:[
-                    file nextBytes:nextBlockSize into:buffer startingAt:1.
+                    zmemb compressionMethod == COMPR_STORED ifTrue:[
+                        file nextBytes:nextBlockSize into:buffer startingAt:1.
+                    ] ifFalse:[
+                        UnsupportedZipFileFormatErrorSignal raiseErrorString:'unsupported compressMethod'
+                    ].
                 ].
 
                 aWriteStream nextPutBytes:buffer size from:buffer startingAt:1.
@@ -3887,8 +3921,10 @@
 !
 
 extractArchive:fileName
+    <resource: #obsolete>
     "extract a filename entry as a byteArray;
      nil on errors"
+
     |zmemb|
 
     (file isNil or: [mode ~~ #read]) ifTrue: [
@@ -3936,13 +3972,22 @@
                 ]
             ].
             baseName := aMember fileName copyFrom: (archiveDirectoryName size+1).
+            baseName size > 0 ifTrue:[
+                baseName first == $/ ifTrue:[
+                    baseName := (baseName from:2) asString.
+                ].
+            ].
 
             fileNameOrDirectoryEntry := osDirectory construct:baseName.
             "/ cg - hugh ??? will never be false, because Filename does not implement isEmpty/notEmpty !!!!!!!!
             fileNameOrDirectoryEntry notEmptyOrNil ifTrue: [
-                aMember compressedSize == 0 ifTrue: [
+                "/ sr&cg:
+                "/ size==0 is not aq valid indicator of the entry  being a directory.
+                "/ use the externalFileAttributes instead
+                "/ aMember compressedSize == 0 ifTrue: [
+                (aMember externalFileAttributes bitTest:EXTERNALFILEATTRIBUTES_ISDIRECTORY) ifTrue:[
                     fileNameOrDirectoryEntry recursiveMakeDirectory.
-                ] ifFalse: [
+                ] ifFalse: [                
                     fileNameOrDirectoryEntry writingFileDo:[:aStream|
                         self 
                             extract: aMember fileName 
@@ -3989,6 +4034,7 @@
 
 addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName compressMethod: theCompressMethod
     |osDirectory fileNameOrDirectoryEntry|
+
     osDirectory := osDirectoryName asFilename.
     (osDirectory exists not or:[osDirectory exists not]) ifTrue:[
         ^ self
@@ -3996,11 +4042,11 @@
 
     self addDirectory: archiveDirectoryName.
     osDirectory recursiveDirectoryContentsDo: [:entry|
-        fileNameOrDirectoryEntry := osDirectory construct: entry.
+        fileNameOrDirectoryEntry := osDirectory construct: entry. self halt.
         fileNameOrDirectoryEntry isDirectory ifTrue: [
             self addDirectory: (archiveDirectoryName, '/', entry).
         ] ifFalse: [
-            fileNameOrDirectoryEntry readingFileDo: [:aStream|
+            fileNameOrDirectoryEntry readingFileDo: [:aStream|    self halt.
                 self addFile: (archiveDirectoryName, '/', entry) 
                      fromStream: aStream 
                      compressMethod: theCompressMethod.
@@ -4010,7 +4056,7 @@
 !
 
 addArchiveDirectoryCompressed: archiveDirectoryName fromOsDirectory: osDirectoryName
-    ^ self addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName compressMethod: 8
+    ^ self addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName compressMethod: COMPR_DEFLATED 
 !
 
 addDirectory: aDirectoryName
@@ -4021,14 +4067,28 @@
     ^ self addFile: aFileName fromStream: aStream compressMethod: 0
 !
 
-addFile: aFileName fromStream: aStream compressMethod: theCompressMethod
+addFile: aFileName fromStream: aStream compressMethod: theCompressMethodArg
     |zipEntry curTime curDate crc32Pos crc32 unCompressedDataSize
       compressedDataSize buffer rdSize nextBlockSize streamBufferSize 
-      myZipStream startDataPosition theZipFileName|
+      myZipStream startDataPosition theZipFileName theCompressMethod|
+
+    "/ sr & cg:
+    "/ please refactor by calling
+    "/    self addFile: aFileName fromStream: aStream compressMethod: theCompressMethod asDirectory:false
 
     (file isNil or: [mode ~~ #write]) ifTrue: [
         ^ self error: 'Archiv not open for writing ...'.
     ].
+
+    theCompressMethod := theCompressMethodArg.
+
+    ((theCompressMethod == COMPR_DEFLATED) 
+    or:[ theCompressMethod == COMPR_STORED ]) ifFalse:[
+        UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
+        "/ if proceeded, write as uncompressed
+        theCompressMethod := COMPR_STORED
+    ].
+
     zipEntry := ZipMember new default.
 
     firstEntry isNil ifTrue: [
@@ -4047,7 +4107,7 @@
 
     zipEntry compressionMethod: theCompressMethod.
     zipEntry internalFileAttributes: 1.
-    zipEntry externalFileAttributes: 32.
+    zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISFILE.
 
     curTime := Time now.
     curDate := Date today.
@@ -4097,13 +4157,17 @@
             nextBlockSize > 0 ifTrue: [
                 aStream nextBytes:nextBlockSize into:buffer startingAt:1.
                 crc32 := (ZipStream crc32BytesIn: buffer crc: crc32).
-                (theCompressMethod == 8) ifTrue: [
+                (theCompressMethod == COMPR_DEFLATED) ifTrue: [
                     myZipStream isNil ifTrue: [
                         myZipStream := ZipStream writeOpenAsZipStreamOn: file.
                     ].
                     myZipStream nextPutBytes:nextBlockSize from:buffer startingAt:1.
                 ] ifFalse: [
-                    file nextPutBytes:nextBlockSize from:buffer startingAt:1.
+                    (theCompressMethod == COMPR_STORED) ifTrue: [
+                        file nextPutBytes:nextBlockSize from:buffer startingAt:1.
+                    ] ifFalse:[
+                        self halt "/ cannot happen
+                    ]
                 ].
             ].
             rdSize := rdSize - nextBlockSize.
@@ -4132,12 +4196,21 @@
     ^ self addFile: aFileName withContents: data compressMethod: 0 asDirectory: false.
 !
 
-addFile: aFileName withContents: data compressMethod: theCompressMethod asDirectory: isDirectory
-    |zipEntry theCompressedData curTime curDate theZipFileName|
+addFile: aFileName withContents: data compressMethod: theCompressMethodArg asDirectory: isDirectory
+    |zipEntry theCompressedData curTime curDate theZipFileName theCompressMethod|
 
     (file isNil or: [mode ~~ #write]) ifTrue: [
         ^ self error: 'Archiv not open for writing ...'.
     ].
+
+    theCompressMethod := theCompressMethodArg.
+    ((theCompressMethod == COMPR_DEFLATED) 
+    or:[ theCompressMethod == COMPR_STORED ]) ifFalse:[
+        UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
+        "/ if proceeded, write as uncompressed
+        theCompressMethod := COMPR_STORED
+    ].
+
     zipEntry := ZipMember new default.
 
     firstEntry isNil ifTrue: [
@@ -4155,11 +4228,11 @@
     zipEntry uncompressedSize: data size.
 
     isDirectory ifTrue: [
-        zipEntry externalFileAttributes: 16.
+        zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISDIRECTORY.
     ] ifFalse: [
         zipEntry compressionMethod: theCompressMethod.
         zipEntry internalFileAttributes: 1.
-        zipEntry externalFileAttributes: 32.
+        zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISFILE.
     ].
 
     curTime := Time now.
@@ -4173,7 +4246,7 @@
         zipEntry crc32: (ZipStream crc32BytesIn: data).
     ].
 
-    (isDirectory not and: [theCompressMethod == 8]) ifTrue: [
+    (isDirectory not and: [theCompressMethod == COMPR_DEFLATED]) ifTrue: [
         |tmpCompressedData tmpCompressedDataSize|
         tmpCompressedData := ByteArray new:(data size + 16). "/ if the compression is less then the additional overhead we need more space in buffer
         tmpCompressedDataSize := ZipStream compress:data into:tmpCompressedData.
@@ -4181,8 +4254,12 @@
         zipEntry compressedSize: (tmpCompressedDataSize - 6). "/6 = the zlib specific data 2 bytes in front and 4 bytes behind the real data
         theCompressedData := tmpCompressedData copyFrom: 3. "/ 2 bytes before the real data
     ] ifFalse: [
-        zipEntry compressedSize: zipEntry uncompressedSize.
-        theCompressedData := data.
+        theCompressMethod == COMPR_STORED ifTrue:[ 
+            zipEntry compressedSize: zipEntry uncompressedSize.
+            theCompressedData := data.
+        ] ifFalse:[
+            self halt "/ cannot happen
+        ].
     ].
 
     "/ ensure that the file position is at the end
@@ -4211,11 +4288,11 @@
 !
 
 addFileCompressed: aFileName fromStream: aStream
-    ^ self addFile: aFileName fromStream: aStream compressMethod: 8
+    ^ self addFile: aFileName fromStream: aStream compressMethod: COMPR_DEFLATED
 !
 
 addFileCompressed: aFileName withContents: data
-    ^ self addFile: aFileName withContents: data compressMethod: 8 asDirectory: false.
+    ^ self addFile: aFileName withContents: data compressMethod: COMPR_DEFLATED asDirectory: false.
 ! !
 
 !ZipArchive methodsFor:'writing - stream'!
@@ -4594,7 +4671,7 @@
 !ZipArchive class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.70 2008-06-16 13:01:12 ab Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.71 2009-01-14 11:37:52 sr Exp $'
 ! !
 
 ZipArchive initialize!