ensure that zip file name is valid before save (check // \\ and spaces)
authorab
Mon, 16 Jun 2008 14:33:43 +0200
changeset 2014 929753038c13
parent 2013 f6307da45659
child 2015 4e007cdea6be
ensure that zip file name is valid before save (check // \\ and spaces)
ZipArchive.st
--- a/ZipArchive.st	Fri Jun 13 10:52:49 2008 +0200
+++ b/ZipArchive.st	Mon Jun 16 14:33:43 2008 +0200
@@ -3139,7 +3139,8 @@
 !ZipArchive methodsFor:'private'!
 
 addContentsToArchiveFrom: realFileName to: zipFileName compress: aCompressFlag
-    |fromStream zipEntry data archiveData curTime curDate theCompressMethod positionSize|
+    |fromStream zipEntry data archiveData curTime curDate theCompressMethod positionSize
+     theZipFileName |
     aCompressFlag ifTrue: [
         fromStream := realFileName readStream.
         theCompressMethod := 8.
@@ -3166,8 +3167,10 @@
 
     lastEntry := zipEntry.
 
-    zipEntry fileName: zipFileName.
-    zipEntry fileNameLength: zipFileName size.
+    theZipFileName := self validZipFileNameFrom:zipFileName. 
+
+    zipEntry fileName: theZipFileName.
+    zipEntry fileNameLength: theZipFileName size.
     zipEntry uncompressedSize: 0.
 
     zipEntry compressionMethod: theCompressMethod.
@@ -3304,6 +3307,48 @@
         file setToEnd.
         endOfArchive   := file position.
     ].
+!
+
+validZipFileNameFrom:zipFileName
+    |fileNameParts partCol partOfPartCol validZipFileName theElement|
+    fileNameParts := OrderedCollection new.
+
+    partCol := zipFileName asCollectionOfSubstringsSeparatedBy:$\.
+    partCol do:[:aSegm|
+        partOfPartCol := aSegm asCollectionOfSubstringsSeparatedBy:$/.
+        partOfPartCol do:[:nextSegm|
+            fileNameParts add: nextSegm.
+        ].
+    ].
+
+    fileNameParts do:[:anElement|
+        anElement notEmptyOrNil ifTrue:[
+            (anElement includes: $ ) ifTrue:[
+                theElement := (anElement replString:' ' withString:'').
+            ] ifFalse:[
+                theElement := anElement.
+            ].
+            validZipFileName isNil ifTrue:[
+                validZipFileName := theElement.
+            ] ifFalse:[
+                validZipFileName := ((validZipFileName asFilename) construct:theElement) name.
+            ].
+        ].
+    ].
+
+    validZipFileName isEmptyOrNil ifTrue:[
+        ^ ZipFileFormatErrorSignal raiseRequestErrorString: (' - invalid zip file name ', zipFileName).
+    ].
+
+    ^ validZipFileName
+
+"
+    ZipArchive new validZipFileNameFrom:'hello//world'
+    ZipArchive new validZipFileNameFrom:'hello\\world'
+    ZipArchive new validZipFileNameFrom:'hello\/world'
+    ZipArchive new validZipFileNameFrom:'hello/\world'
+    ZipArchive new validZipFileNameFrom:'hello/\world/aaa bbb/ccc'
+"
 ! !
 
 !ZipArchive methodsFor:'private-decompression'!
@@ -3979,7 +4024,7 @@
 addFile: aFileName fromStream: aStream compressMethod: theCompressMethod
     |zipEntry curTime curDate crc32Pos crc32 unCompressedDataSize
       compressedDataSize buffer rdSize nextBlockSize streamBufferSize 
-      myZipStream startDataPosition|
+      myZipStream startDataPosition theZipFileName|
 
     (file isNil or: [mode ~~ #write]) ifTrue: [
         ^ self error: 'Archiv not open for writing ...'.
@@ -3994,8 +4039,10 @@
 
     lastEntry := zipEntry.
 
-    zipEntry fileName: aFileName.
-    zipEntry fileNameLength: aFileName size.
+    theZipFileName := self validZipFileNameFrom:aFileName. 
+
+    zipEntry fileName: theZipFileName.
+    zipEntry fileNameLength: theZipFileName size.
     zipEntry uncompressedSize: 0.
 
     zipEntry compressionMethod: theCompressMethod.
@@ -4086,7 +4133,7 @@
 !
 
 addFile: aFileName withContents: data compressMethod: theCompressMethod asDirectory: isDirectory
-    |zipEntry theCompressedData curTime curDate|
+    |zipEntry theCompressedData curTime curDate theZipFileName|
 
     (file isNil or: [mode ~~ #write]) ifTrue: [
         ^ self error: 'Archiv not open for writing ...'.
@@ -4101,8 +4148,10 @@
 
     lastEntry := zipEntry.
 
-    zipEntry fileName: aFileName.
-    zipEntry fileNameLength: aFileName size.
+    theZipFileName := self validZipFileNameFrom:aFileName. 
+
+    zipEntry fileName: theZipFileName.
+    zipEntry fileNameLength: theZipFileName size.
     zipEntry uncompressedSize: data size.
 
     isDirectory ifTrue: [
@@ -4545,7 +4594,7 @@
 !ZipArchive class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.68 2008-06-09 21:27:57 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.69 2008-06-16 12:33:43 ab Exp $'
 ! !
 
 ZipArchive initialize!