Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -117,11 +117,11 @@ return field; } static uint32_t -crc32(uint32_t crc, uint8_t *bytes, size_t length) +calculateCRC32(uint32_t crc, uint8_t *bytes, size_t length) { size_t i; for (i = 0; i < length; i++) { uint_fast8_t j; @@ -132,10 +132,25 @@ crc = (crc >> 1) ^ (CRC32_MAGIC & (~(crc & 1) + 1)); } return crc; } + +static void +seekOrThrowInvalidFormat(OFSeekableStream *stream, + of_offset_t offset, int whence) +{ + @try { + [stream seekToOffset: offset + whence: whence]; + } @catch (OFSeekFailedException *e) { + if ([e errNo] == EINVAL) + @throw [OFInvalidFormatException exception]; + + @throw e; + } +} @implementation OFZIPArchive + (instancetype)archiveWithSeekableStream: (OFSeekableStream*)stream { return [[[self alloc] initWithSeekableStream: stream] autorelease]; @@ -203,19 +218,11 @@ uint16_t commentLength; of_offset_t offset = -22; bool valid = false; do { - @try { - [_stream seekToOffset: offset - whence: SEEK_END]; - } @catch (OFSeekFailedException *e) { - if ([e errNo] == EINVAL) - @throw [OFInvalidFormatException exception]; - - @throw e; - } + seekOrThrowInvalidFormat(_stream, offset, SEEK_END); if ([_stream readLittleEndianInt32] == 0x06054B50) { valid = true; break; } @@ -242,12 +249,11 @@ _centralDirectoryEntries == 0xFFFF || _centralDirectorySize == 0xFFFFFFFF || _centralDirectoryOffset == 0xFFFFFFFF) { uint64_t offset64, size; - [_stream seekToOffset: offset - 20 - whence: SEEK_END]; + seekOrThrowInvalidFormat(_stream, offset - 20, SEEK_END); if ([_stream readLittleEndianInt32] != 0x07064B50) { objc_autoreleasePoolPop(pool); return; } @@ -260,12 +266,12 @@ offset64 = [_stream readLittleEndianInt64]; if ((of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; - [_stream seekToOffset: (of_offset_t)offset64 - whence: SEEK_SET]; + seekOrThrowInvalidFormat(_stream, + (of_offset_t)offset64, SEEK_SET); if ([_stream readLittleEndianInt32] != 0x06064B50) @throw [OFInvalidFormatException exception]; size = [_stream readLittleEndianInt64]; @@ -299,12 +305,12 @@ size_t i; if ((of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; - [_stream seekToOffset: (of_offset_t)_centralDirectoryOffset - whence: SEEK_SET]; + seekOrThrowInvalidFormat(_stream, + (of_offset_t)_centralDirectoryOffset, SEEK_SET); _entries = [[OFMutableArray alloc] init]; _pathToEntryMap = [[OFMutableDictionary alloc] init]; for (i = 0; i < _centralDirectoryEntries; i++) { @@ -353,12 +359,11 @@ offset64 = [entry OF_localFileHeaderOffset]; if ((of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; - [_stream seekToOffset: (of_offset_t)offset64 - whence: SEEK_SET]; + seekOrThrowInvalidFormat(_stream, (of_offset_t)offset64, SEEK_SET); localFileHeader = [[[OFZIPArchive_LocalFileHeader alloc] initWithStream: _stream] autorelease]; if (![localFileHeader matchesEntry: entry]) @throw [OFInvalidFormatException exception]; @@ -566,15 +571,15 @@ ret = [_decompressedStream readIntoBuffer: buffer length: min]; _size -= ret; } - _CRC32 = crc32(_CRC32, buffer, ret); + _CRC32 = calculateCRC32(_CRC32, buffer, ret); return ret; } - (void)close { _closed = true; } @end