--- a/ZipArchive.st Sat Nov 09 19:42:20 2019 +0100
+++ b/ZipArchive.st Fri Nov 15 19:57:57 2019 +0100
@@ -3471,18 +3471,21 @@
"initialize the archive to write to aPositionableStream"
stream notNil ifTrue: [
- self close.
+ self close.
].
mode := #write.
aPositionableStream binary.
stream := aPositionableStream.
+ startOfArchive := aPositionableStream position.
aPositionableStream isFileStream ifTrue:[
- archiveName := aPositionableStream pathName.
+ archiveName := aPositionableStream pathName.
] ifFalse:[
- archiveName := 'internal stream'.
+ archiveName := 'internal stream'.
].
zipMembersByName := Dictionary new.
+
+ "Modified: / 15-11-2019 / 19:31:15 / Stefan Vogel"
! !
!ZipArchive methodsFor:'private'!
@@ -3752,7 +3755,7 @@
"/ ensure that the file position is at end
stream setToEnd.
- centralDirectory centralDirectoryStartOffset: stream position.
+ centralDirectory centralDirectoryStartOffset: stream position-startOfArchive.
self zipMembersDo:[:zipEntry |
noEntries := noEntries + 1.
@@ -3789,7 +3792,7 @@
centralDirectory centralDirectoryTotalNoOfEntries: noEntries.
centralDirectory centralDirectoryTotalNoOfEntriesOnThisDisk: noEntries.
- centralDirectory centralDirectorySize: (stream position) - (centralDirectory centralDirectoryStartOffset).
+ centralDirectory centralDirectorySize: (stream position-startOfArchive) - (centralDirectory centralDirectoryStartOffset).
stream nextPutByte:($P codePoint).
stream nextPutByte:($K codePoint).
@@ -3808,7 +3811,7 @@
].
"Modified: / 19-11-2010 / 16:23:36 / cg"
- "Modified: / 22-11-2018 / 15:36:07 / Stefan Vogel"
+ "Modified: / 15-11-2019 / 19:34:40 / Stefan Vogel"
!
addMember:zmemb
@@ -3928,15 +3931,15 @@
size := endOfArchive - startOfArchive.
(size == 0) ifTrue:[
- ^ self
+ ^ self
].
(size < (ECREC_SIZE+4)) ifTrue:[
- ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - zipfile too short'.
+ ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - zipfile too short'.
].
self searchForEndOfCentralDirectorySignature ifFalse: [
- ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - could not find end of directory signature'.
+ ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - could not find end of directory signature'.
].
"/ position before end of central directory signature
@@ -3945,52 +3948,52 @@
"/ Now we have found the end of central directory record
centralDirectory := ZipCentralDirectory new.
EndOfStreamNotification handle:[:ex|
- ZipFileFormatErrorSignal raiseRequestErrorString:' - file format error or short file: ' ,
- (stream isFileStream ifTrue:[stream pathName] ifFalse:['inStream']).
- ^ self.
+ ZipFileFormatErrorSignal raiseRequestErrorString:' - file format error or short file: ' ,
+ (stream isFileStream ifTrue:[stream pathName] ifFalse:['inStream']).
+ ^ self.
] do:[
- centralDirectory readFrom:stream.
-
- "/ set file position to start of central directory
- (pos0 - centralDirectory centralDirectoryStartOffset - centralDirectory centralDirectorySize) < startOfArchive ifTrue: [
- ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - central directory start is out of the archive bounds'.
- ].
-
- startOfArchive := pos0 - centralDirectory centralDirectoryStartOffset - centralDirectory centralDirectorySize.
- stream position:(pos0 - (centralDirectory centralDirectorySize)).
-
- zipMembersByName := Dictionary new:centralDirectory centralDirectoryTotalNoOfEntries.
-
- "/ read central directory entries
- 1 to:(centralDirectory centralDirectoryTotalNoOfEntries) do:[:i |
- |zipd centralFileHeaderSignature|
-
- (stream position + (self class centralDirectoryMinimumSize)) > endOfArchive ifTrue: [
- ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - central directory entry out of archive bounds'.
- ].
- centralFileHeaderSignature := stream nextInt32MSB:false.
- centralFileHeaderSignature ~= C_CENTRAL_HEADER_SIGNATURE ifTrue:[
- ZipFileFormatErrorSignal raiseRequestErrorString:' - file format error - bad centralHeaderSignature in: ' ,
- (stream isFileStream ifTrue:[stream pathName] ifFalse:['inStream']).
- ^ self.
- ].
-
- zipd := ZipMember new readCentralDirectoryEntryFrom:stream.
- self addMember:zipd.
- ].
-
- (stream position + 6) > endOfArchive ifTrue: [
- "/ archive has no digital signature
- ^ self.
- ].
-
- "/ check for digital signature
- ((stream nextByte ~~ ($P codePoint))
- or:[stream nextByte ~~ ($K codePoint)
- or:[stream nextByte ~~ 8r005
- or:[stream nextByte ~~ 8r005]]]) ifTrue:[
- centralDirectory readDigitalSignatureFrom:stream.
- ].
+ centralDirectory readFrom:stream.
+
+ "/ set file position to start of central directory
+ (pos0 - centralDirectory centralDirectoryStartOffset - centralDirectory centralDirectorySize) < startOfArchive ifTrue: [
+ ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - central directory start is out of the archive bounds'.
+ ].
+
+ startOfArchive := pos0 - centralDirectory centralDirectoryStartOffset - centralDirectory centralDirectorySize.
+ stream position:(pos0 - (centralDirectory centralDirectorySize)).
+
+ zipMembersByName := Dictionary new:centralDirectory centralDirectoryTotalNoOfEntries.
+
+ "/ read central directory entries
+ 1 to:(centralDirectory centralDirectoryTotalNoOfEntries) do:[:i |
+ |zipd centralFileHeaderSignature|
+
+ (stream position + (self class centralDirectoryMinimumSize)) > endOfArchive ifTrue: [
+ ^ ZipFileFormatErrorSignal raiseRequestErrorString:' - central directory entry out of archive bounds'.
+ ].
+ centralFileHeaderSignature := stream nextInt32MSB:false.
+ centralFileHeaderSignature ~= C_CENTRAL_HEADER_SIGNATURE ifTrue:[
+ ZipFileFormatErrorSignal raiseRequestErrorString:' - file format error - bad centralHeaderSignature in: ' ,
+ (stream isFileStream ifTrue:[stream pathName] ifFalse:['inStream']).
+ ^ self.
+ ].
+
+ zipd := ZipMember new readCentralDirectoryEntryFrom:stream.
+ self addMember:zipd.
+ ].
+
+ (stream position + 6) > endOfArchive ifTrue: [
+ "/ archive has no digital signature
+ ^ self.
+ ].
+
+ "/ check for digital signature
+ ((stream nextByte ~~ ($P codePoint))
+ or:[stream nextByte ~~ ($K codePoint)
+ or:[stream nextByte ~~ 8r005
+ or:[stream nextByte ~~ 8r005]]]) ifTrue:[
+ centralDirectory readDigitalSignatureFrom:stream.
+ ].
]
"
@@ -4001,14 +4004,14 @@
"Modified: / 19-11-2010 / 15:43:24 / cg"
"Modified (format): / 17-02-2017 / 22:20:26 / stefan"
+ "Modified: / 15-11-2019 / 19:57:40 / Stefan Vogel"
!
searchForEndOfCentralDirectorySignature
"read the zip directory into a linked-list of zipMembers"
- |size foundPK pos0 searchEndPos|
-
- foundPK := false.
+ |size pos0 searchEndPos|
+
size := endOfArchive - startOfArchive.
stream position:(pos0 := endOfArchive - ECREC_SIZE - 4).
@@ -4017,38 +4020,40 @@
or:[stream nextByte ~~ ($K codePoint)
or:[stream nextByte ~~ 8r005
or:[stream nextByte ~~ 8r006]]]) ifTrue:[
- "/ search from end of archive backwards for "end of central directory signature",
- "/ this is necessary if the archive includes a .ZIP file comment or a digital signature
- "/ then the end of the directory signature may be on an other position
-
- "/ but the "end of central directory signature" must be located in the
- "/ last 64k of the archive
- size > 65536 ifTrue: [
- searchEndPos := (endOfArchive - 65536).
- ] ifFalse: [
- searchEndPos := startOfArchive.
- ].
-
- stream position: (pos0 := endOfArchive - 4).
-
- [foundPK] whileFalse: [
- (stream nextByte == ($P codePoint)
- and:[stream nextByte == ($K codePoint)
- and:[stream nextByte == 8r005
- and:[stream nextByte == 8r006]]]) ifTrue:[
- ^ true
- ].
- stream position <= searchEndPos ifTrue: [
- ^ false.
- ].
- pos0 == 0 ifTrue:[
- ^ false.
- ].
- stream position: (pos0 := pos0 - 1).
- ].
- ^ false
+ "/ search from end of archive backwards for "end of central directory signature",
+ "/ this is necessary if the archive includes a .ZIP file comment or a digital signature
+ "/ then the end of the directory signature may be on an other position
+
+ "/ but the "end of central directory signature" must be located in the
+ "/ last 64k of the archive
+ size > 65536 ifTrue: [
+ searchEndPos := (endOfArchive - 65536).
+ ] ifFalse: [
+ searchEndPos := startOfArchive.
+ ].
+
+ stream position: (pos0 := endOfArchive - 4).
+
+ [true] whileTrue:[
+ (stream nextByte == ($P codePoint)
+ and:[stream nextByte == ($K codePoint)
+ and:[stream nextByte == 5
+ and:[stream nextByte == 6]]]) ifTrue:[
+ ^ true
+ ].
+ stream position <= searchEndPos ifTrue: [
+ ^ false.
+ ].
+ pos0 == 0 ifTrue:[
+ ^ false.
+ ].
+ stream position: (pos0 := pos0 - 1).
+ ].
+ ^ false
].
^ true
+
+ "Modified: / 15-11-2019 / 19:02:40 / Stefan Vogel"
!
zipMembersDo:aBlock
@@ -4379,8 +4384,8 @@
theCompressMethod := theCompressMethodArg.
- ((theCompressMethod == COMPRESSION_DEFLATED)
- or:[ theCompressMethod == COMPRESSION_STORED ]) ifFalse:[
+ (theCompressMethod ~~ COMPRESSION_DEFLATED
+ and:[theCompressMethod ~~ COMPRESSION_STORED]) ifTrue:[
UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
"/ if proceeded, write as uncompressed
theCompressMethod := COMPRESSION_STORED
@@ -4389,7 +4394,7 @@
zipEntry := ZipMember new default.
theZipFileName := self validZipFileNameFrom:aFileName.
- zipEntry fileName: theZipFileName.
+ zipEntry fileName:theZipFileName.
zipEntry uncompressedSize: 0.
isDirectory ifTrue: [
@@ -4407,7 +4412,7 @@
"/ ensure that the file position is at the end
stream setToEnd.
- zipEntry writeTo:stream.
+ zipEntry writeTo:stream position:stream position - startOfArchive.
streamBufferSize := self class streamBufferSize.
buffer := ByteArray new:streamBufferSize.
@@ -4440,7 +4445,7 @@
].
].
- zipEntry compressedSize:(stream position) - startDataPosition.
+ zipEntry compressedSize:stream position - startDataPosition.
"/ crc32 is always required (not as written in docu to be zero in case of uncompressed mode)
zipEntry crc32:crc32.
@@ -4452,7 +4457,7 @@
stream setToEnd.
"Modified: / 19-11-2010 / 15:39:32 / cg"
- "Modified: / 22-11-2018 / 12:27:39 / Stefan Vogel"
+ "Modified: / 15-11-2019 / 19:44:42 / Stefan Vogel"
!
addFile: aFileName withContents: data
@@ -4495,9 +4500,9 @@
basicAddFile:aFileName withContents:data compressMethod:theCompressMethodArg asDirectory:isDirectory
"do not create directories (isDirectory = true) - they are not compatible between operating systems"
- |zipEntry theCompressedData theZipFileName theCompressMethod compressedDataOffset compressedDataSize|
-
- (stream isNil or:[ mode ~~ #write ]) ifTrue:[
+ |zipEntry theCompressedData theZipFileName theCompressMethod compressedDataOffset compressedDataSize|
+
+ (stream isNil or:[mode ~~ #write]) ifTrue:[
^ self error:'ZipArchive not open for writing ...'.
].
theCompressMethod := theCompressMethodArg.
@@ -4513,7 +4518,7 @@
theZipFileName := self validZipFileNameFrom:aFileName.
(isDirectory and:[self appendTrailingSlash and:[theZipFileName last ~~ $/]]) ifTrue:[
- zipEntry fileName:theZipFileName , $/.
+ zipEntry fileName:theZipFileName, $/.
] ifFalse:[
zipEntry fileName:theZipFileName.
].
@@ -4547,7 +4552,7 @@
"/ ensure that the file position is at the end
stream setToEnd.
- zipEntry writeTo:stream.
+ zipEntry writeTo:stream position:stream position - startOfArchive.
theCompressedData notNil ifTrue:[
stream
nextPutAll:theCompressedData
@@ -4559,7 +4564,7 @@
"Created: / 18-11-2010 / 19:31:10 / cg"
"Modified: / 19-11-2010 / 17:47:01 / cg"
"Modified: / 19-11-2012 / 12:04:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 22-11-2018 / 15:42:25 / Stefan Vogel"
+ "Modified (format): / 15-11-2019 / 19:50:43 / Stefan Vogel"
! !
!ZipArchive methodsFor:'writing - stream'!
@@ -4578,16 +4583,16 @@
|zipEntry theZipFileName theCompressMethod|
(stream isNil or:[mode ~~ #write]) ifTrue: [
- ^ self error: 'ZipArchive not open for writing ...'.
+ ^ self error: 'ZipArchive not open for writing ...'.
].
theCompressMethod := theCompressMethodArg.
((theCompressMethod == COMPRESSION_DEFLATED)
or:[theCompressMethod == COMPRESSION_STORED]) ifFalse:[
- UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
- "/ if proceeded, write as uncompressed
- theCompressMethod := COMPRESSION_STORED
+ UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
+ "/ if proceeded, write as uncompressed
+ theCompressMethod := COMPRESSION_STORED
].
zipEntry := ZipMember new default.
@@ -4606,12 +4611,13 @@
"/ ensure that the file position is at the end
stream setToEnd.
- zipEntry writeTo:stream.
+ zipEntry writeTo:stream position:stream position - startOfArchive.
self addMember:zipEntry.
^ (ZipWriteStream zipFileStream:stream zipEntry:zipEntry) zipArchive:self.
"Modified: / 19-11-2010 / 15:38:54 / cg"
+ "Modified: / 15-11-2019 / 19:45:48 / Stefan Vogel"
! !
!ZipArchive::AbstractZipStream class methodsFor:'instance creation'!
@@ -5163,10 +5169,10 @@
nextPutInt32:uncompressedSize MSB:false.
!
-writeTo:aStream
+writeTo:aStream position:position
"represent myself on aStream"
- relativeLocalHeaderOffset := aStream position.
+ relativeLocalHeaderOffset := position.
aStream
nextPutInt32:C_LOCAL_HEADER_SIGNATURE MSB:false;
@@ -5187,8 +5193,7 @@
aStream nextPutAll:extraField.
].
- "Modified: / 19-11-2010 / 15:45:38 / cg"
- "Modified: / 22-11-2018 / 15:37:03 / Stefan Vogel"
+ "Created: / 15-11-2019 / 19:44:10 / Stefan Vogel"
! !
!ZipArchive::ZipReadStream methodsFor:'accessing'!