Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -91,11 +91,11 @@ @interface OFZIPArchive_FileWriteStream: OFStream { OFStream *_stream; uint32_t _CRC32; @public - uint64_t _bytesWritten; + int64_t _bytesWritten; OFMutableZIPArchiveEntry *_entry; } - initWithStream: (OFStream *)stream entry: (OFMutableZIPArchiveEntry *)entry; @@ -401,10 +401,13 @@ [_lastReturnedStream isKindOfClass: [OFZIPArchive_FileWriteStream class]]) { OFZIPArchive_FileWriteStream *stream = (OFZIPArchive_FileWriteStream *)_lastReturnedStream; + if (INT64_MAX - _offset < stream->_bytesWritten) + @throw [OFOutOfRangeException exception]; + _offset += stream->_bytesWritten; if (stream->_entry != nil) { [_entries addObject: stream->_entry]; [_pathToEntryMap setObject: stream->_entry @@ -468,10 +471,11 @@ void *pool; OFMutableZIPArchiveEntry *entry; OFString *fileName; OFData *extraField; uint16_t fileNameLength, extraFieldLength; + int64_t offsetAdd = 0; if (_mode != OF_ZIP_ARCHIVE_MODE_WRITE && _mode != OF_ZIP_ARCHIVE_MODE_APPEND) @throw [OFInvalidArgumentException exception]; @@ -511,25 +515,30 @@ [_stream writeLittleEndianInt16: [entry of_lastModifiedFileDate]]; /* We use the data descriptor */ [_stream writeLittleEndianInt32: 0]; [_stream writeLittleEndianInt32: 0]; [_stream writeLittleEndianInt32: 0]; - _offset += 4 + (5 * 2) + (3 * 4); + offsetAdd += 4 + (5 * 2) + (3 * 4); fileName = [entry fileName]; fileNameLength = [fileName UTF8StringLength]; extraField = [entry extraField]; extraFieldLength = [extraField count]; [_stream writeLittleEndianInt16: fileNameLength]; [_stream writeLittleEndianInt16: extraFieldLength]; - _offset += 2 * 2; + offsetAdd += 2 * 2; [_stream writeString: fileName]; if (extraField != nil) [_stream writeData: extraField]; - _offset += fileNameLength + extraFieldLength; + offsetAdd += fileNameLength + extraFieldLength; + + if (INT64_MAX - _offset < offsetAdd) + @throw [OFOutOfRangeException exception]; + + _offset += offsetAdd; _lastReturnedStream = [[OFZIPArchive_FileWriteStream alloc] initWithStream: _stream entry: entry]; @@ -815,17 +824,17 @@ } - (void)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { - if (length > INT64_MAX || INT64_MAX - _bytesWritten < length) + if (length > INT64_MAX || INT64_MAX - _bytesWritten < (int64_t)length) @throw [OFOutOfRangeException exception]; [_stream writeBuffer: buffer length: length]; - _bytesWritten += length; + _bytesWritten += (int64_t)length; _CRC32 = of_crc32(_CRC32, buffer, length); } - (void)close {