ZipZap
ZipZap copied to clipboard
ZZDeflateOutputStream write:maxLength erroneously returning zero
When supplying a streamBlock to ZZArchiveEntry archiveEntryWithFileName:compress:streamBlock:
the given output stream is of type ZZDeflateOutputStream
which sometimes returns a zero when it doesn't mean it, causing problems.
The docs for NSOutputStream write:maxLength:
say:
Return Value A number indicating the outcome of the operation:
- A positive number indicates the number of bytes written.
- 0 indicates that a fixed-length stream and has reached its capacity.
- -1 means that the operation failed; more information about the error can be obtained with streamError.
so when ZZDeflateOutputStream write:maxLength:
returns zero the calling code believes the stream has reached capacity and attempts no more writes. This causes a crash in ZZArchive loadCanMiss:error:
due to the contained ZZChannel
attempting to init an NSData
object with a nil
URL (from the _URL
ivar).
- (BOOL)loadCanMiss:(BOOL)canMiss error:(out NSError**)error
{
// memory-map the contents from the zip file
NSError* __autoreleasing readError;
NSData* contents = [_channel newInput:&readError];
In practice, if one ignores a return of zero from ZZDeflateOutputStream write:maxLength:
and continues to attempt writes the process completes without issue. This, however, is non-standard.
The return value from NSOutputStream write:maxLength:
is a contract with the caller and the value returned should accurately reflect those bytes which were consumed from the given buffer, not how many bytes the stream wrote out somewhere else.
+1