Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -152,10 +152,12 @@ [OBJCFLAGS="$OBJCFLAGS -Wshorten-64-to-32"]) AX_CHECK_COMPILER_FLAGS(-Wsemicolon-before-method-body -Werror, [OBJCFLAGS="$OBJCFLAGS -Wsemicolon-before-method-body"]) AX_CHECK_COMPILER_FLAGS(-Wobjc-property-synthesis -Werror, [OBJCFLAGS="$OBJCFLAGS -Wobjc-property-synthesis"]) +AX_CHECK_COMPILER_FLAGS(-Wsign-compare -Werror, + [OBJCFLAGS="$OBJCFLAGS -Wsign-compare"]) AC_MSG_CHECKING(whether Objective C compiler supports properties) AC_TRY_COMPILE([ @interface Foo { Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -39,10 +39,11 @@ #ifdef OF_HAVE_SOCKETS # import "OFHTTPRequestFailedException.h" #endif #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" +#import "OFInvalidServerReplyException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" @@ -158,11 +159,12 @@ OFFile *file = [[OFFile alloc] initWithPath: path mode: @"rb"]; of_offset_t size = [[OFFileManager defaultManager] sizeOfFileAtPath: path]; - if (size > SIZE_MAX) + if (sizeof(of_offset_t) > sizeof(size_t) && + size > (of_offset_t)SIZE_MAX) @throw [OFOutOfRangeException exception]; self = [self initWithItemSize: 1 capacity: (size_t)size]; @@ -218,11 +220,11 @@ OFHTTPResponse *response = [client performRequest: request]; size_t pageSize; char *buffer; OFDictionary *headers; - OFString *contentLength; + OFString *contentLengthString; if ([response statusCode] != 200) @throw [OFHTTPRequestFailedException exceptionWithRequest: request response: response]; @@ -243,16 +245,24 @@ } @finally { [self freeMemory: buffer]; } headers = [response headers]; - if ((contentLength = - [headers objectForKey: @"Content-Length"]) != nil) - if ([self count] != - [contentLength decimalValue]) + if ((contentLengthString = + [headers objectForKey: @"Content-Length"]) != nil) { + intmax_t contentLength = + [contentLengthString decimalValue]; + + if (contentLength < 0) + @throw [OFInvalidServerReplyException + exception]; + + if ((uintmax_t)[self count] != + (uintmax_t)contentLength) @throw [OFTruncatedDataException exception]; + } } @catch (id e) { [self release]; @throw e; } } else Index: src/OFGZIPStream.m ================================================================== --- src/OFGZIPStream.m +++ src/OFGZIPStream.m @@ -228,11 +228,11 @@ length: 4 - _bytesRead]; if (_bytesRead < 4) return 0; - if (((_buffer[3] << 24) | (_buffer[2] << 16) | + if ((((uint32_t)_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]) != ~_CRC32) @throw [OFChecksumFailedException exception]; _bytesRead = 0; _CRC32 = ~0; @@ -240,11 +240,11 @@ break; case OF_GZIP_STREAM_UNCOMPRESSED_SIZE: _bytesRead += [_stream readIntoBuffer: _buffer length: 4 - _bytesRead]; - if (((_buffer[3] << 24) | (_buffer[2] << 16) | + if ((((uint32_t)_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]) != _uncompressedSize) @throw [OFChecksumFailedException exception]; _bytesRead = 0; Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -109,11 +109,16 @@ _hasContentLength = true; @try { intmax_t toRead = [contentLength decimalValue]; - if (toRead > SIZE_MAX) + if (toRead < 0) + @throw [OFInvalidServerReplyException + exception]; + + if (sizeof(intmax_t) > sizeof(size_t) && + toRead > (intmax_t)SIZE_MAX) @throw [OFOutOfRangeException exception]; _toRead = (size_t)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; Index: src/OFKernelEventObserver_kqueue.m ================================================================== --- src/OFKernelEventObserver_kqueue.m +++ src/OFKernelEventObserver_kqueue.m @@ -178,11 +178,11 @@ if (eventList[i].flags & EV_ERROR) @throw [OFObserveFailedException exceptionWithObserver: self errNo: (int)eventList[i].data]; - if (eventList[i].ident == _cancelFD[0]) { + if (eventList[i].ident == (uintptr_t)_cancelFD[0]) { char buffer; assert(eventList[i].filter == EVFILT_READ); OF_ENSURE(read(_cancelFD[0], &buffer, 1) == 1); Index: src/OFKernelEventObserver_poll.h ================================================================== --- src/OFKernelEventObserver_poll.h +++ src/OFKernelEventObserver_poll.h @@ -21,11 +21,11 @@ @class OFDataArray; @interface OFKernelEventObserver_poll: OFKernelEventObserver { OFDataArray *_FDs; - size_t _maxFD; + int _maxFD; id __unsafe_unretained *_FDToObject; } @end OF_ASSUME_NONNULL_END Index: src/OFKernelEventObserver_poll.m ================================================================== --- src/OFKernelEventObserver_poll.m +++ src/OFKernelEventObserver_poll.m @@ -52,11 +52,11 @@ sizeof(struct pollfd)]; [_FDs addItem: &p]; _maxFD = _cancelFD[0]; _FDToObject = [self allocMemoryWithSize: sizeof(id) - count: _maxFD + 1]; + count: (size_t)_maxFD + 1]; } @catch (id e) { [self release]; @throw e; } @@ -91,11 +91,11 @@ if (fd > _maxFD) { _maxFD = fd; _FDToObject = [self resizeMemory: _FDToObject size: sizeof(id) - count: _maxFD + 1]; + count: (size_t)_maxFD + 1]; } _FDToObject[fd] = object; [_FDs addItem: &p]; } Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -385,11 +385,11 @@ #if defined(OF_OBJFW_RUNTIME) for (struct objc_method_list *methodlist = object_getClass(class)->methodlist; methodlist != NULL; methodlist = methodlist->next) { - for (int i = 0; i < methodlist->count; i++) { + for (unsigned int i = 0; i < methodlist->count; i++) { SEL selector = (SEL)&methodlist->methods[i].sel; /* * Don't replace methods implemented in the receiving * class. @@ -403,11 +403,11 @@ } } for (struct objc_method_list *methodlist = class->methodlist; methodlist != NULL; methodlist = methodlist->next) { - for (int i = 0; i < methodlist->count; i++) { + for (unsigned int i = 0; i < methodlist->count; i++) { SEL selector = (SEL)&methodlist->methods[i].sel; /* * Don't replace methods implemented in the receiving * class. Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -846,11 +846,12 @@ @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"rb" errNo: errno]; - if (st.st_size > SIZE_MAX) + if (sizeof(of_offset_t) > sizeof(size_t) && + st.st_size > (of_offset_t)SIZE_MAX) @throw [OFOutOfRangeException exception]; file = [[OFFile alloc] initWithPath: path mode: @"rb"]; Index: src/OFTCPSocket+SOCKS5.m ================================================================== --- src/OFTCPSocket+SOCKS5.m +++ src/OFTCPSocket+SOCKS5.m @@ -30,11 +30,14 @@ int _OFTCPSocket_SOCKS5_reference; static void send_or_exception(OFTCPSocket *self, int socket, char *buffer, size_t length) { - if (send(socket, buffer, length, 0) != length) + if (length > SSIZE_MAX) + @throw [OFOutOfRangeException exception]; + + if (send(socket, buffer, length, 0) != (ssize_t)length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length errNo: of_socket_errno()]; } Index: src/OFZIPArchive.h ================================================================== --- src/OFZIPArchive.h +++ src/OFZIPArchive.h @@ -36,11 +36,12 @@ @interface OFZIPArchive: OFObject { OFSeekableStream *_stream; uint32_t _diskNumber, _centralDirectoryDisk; uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries; - uint64_t _centralDirectorySize, _centralDirectoryOffset; + uint64_t _centralDirectorySize; + int64_t _centralDirectoryOffset; OFString *_archiveComment; OFMutableArray OF_GENERIC(OFZIPArchiveEntry*) *_entries; OFMutableDictionary OF_GENERIC(OFString*, OFZIPArchiveEntry*) *_pathToEntryMap; OFStream *_lastReturnedStream; Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -229,12 +229,13 @@ if (_diskNumber == 0xFFFF || _centralDirectoryDisk == 0xFFFF || _centralDirectoryEntriesInDisk == 0xFFFF || _centralDirectoryEntries == 0xFFFF || _centralDirectorySize == 0xFFFFFFFF || - _centralDirectoryOffset == 0xFFFFFFFF) { - uint64_t offset64, size; + _centralDirectoryOffset == -1) { + int64_t offset64; + uint64_t size; seekOrThrowInvalidFormat(_stream, offset - 20, SEEK_END); if ([_stream readLittleEndianInt32] != 0x07064B50) { objc_autoreleasePoolPop(pool); @@ -246,11 +247,11 @@ * central directory record. */ [_stream readLittleEndianInt32]; offset64 = [_stream readLittleEndianInt64]; - if ((of_offset_t)offset64 != offset64) + if (offset64 < 0 || (of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat(_stream, (of_offset_t)offset64, SEEK_SET); @@ -272,11 +273,12 @@ [_stream readLittleEndianInt64]; _centralDirectoryEntries = [_stream readLittleEndianInt64]; _centralDirectorySize = [_stream readLittleEndianInt64]; _centralDirectoryOffset = [_stream readLittleEndianInt64]; - if ((of_offset_t)_centralDirectoryOffset != + if (_centralDirectoryOffset < 0 || + (of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; } objc_autoreleasePoolPop(pool); @@ -284,11 +286,12 @@ - (void)OF_readEntries { void *pool = objc_autoreleasePoolPush(); - if ((of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) + if (_centralDirectoryOffset < 0 || + (of_offset_t)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat(_stream, (of_offset_t)_centralDirectoryOffset, SEEK_SET); @@ -321,11 +324,11 @@ - (OFStream*)streamForReadingFile: (OFString*)path { void *pool = objc_autoreleasePoolPush(); OFZIPArchiveEntry *entry = [_pathToEntryMap objectForKey: path]; OFZIPArchive_LocalFileHeader *localFileHeader; - uint64_t offset64; + int64_t offset64; if (entry == nil) @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"rb" errNo: ENOENT]; @@ -333,11 +336,11 @@ [_lastReturnedStream close]; [_lastReturnedStream release]; _lastReturnedStream = nil; offset64 = [entry OF_localFileHeaderOffset]; - if ((of_offset_t)offset64 != offset64) + if (offset64 < 0 || (of_offset_t)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat(_stream, (of_offset_t)offset64, SEEK_SET); localFileHeader = [[[OFZIPArchive_LocalFileHeader alloc] initWithStream: _stream] autorelease]; Index: src/OFZIPArchiveEntry+Private.h ================================================================== --- src/OFZIPArchiveEntry+Private.h +++ src/OFZIPArchiveEntry+Private.h @@ -18,11 +18,11 @@ OF_ASSUME_NONNULL_BEGIN @interface OFZIPArchiveEntry () @property (readonly) uint16_t OF_lastModifiedFileTime, OF_lastModifiedFileDate; -@property (readonly) uint64_t OF_localFileHeaderOffset; +@property (readonly) int64_t OF_localFileHeaderOffset; - (instancetype)OF_initWithStream: (OFStream*)stream; @end OF_ASSUME_NONNULL_END Index: src/OFZIPArchiveEntry.h ================================================================== --- src/OFZIPArchiveEntry.h +++ src/OFZIPArchiveEntry.h @@ -98,11 +98,11 @@ OFDataArray *_extraField; OFString *_fileComment; uint32_t _startDiskNumber; uint16_t _internalAttributes; uint32_t _versionSpecificAttributes; - uint64_t _localFileHeaderOffset; + int64_t _localFileHeaderOffset; } /*! * The file name of the entry. */ Index: src/OFZIPArchiveEntry.m ================================================================== --- src/OFZIPArchiveEntry.m +++ src/OFZIPArchiveEntry.m @@ -203,11 +203,11 @@ _uncompressedSize = of_zip_archive_read_field64( &ZIP64, &ZIP64Size); if (_compressedSize == 0xFFFFFFFF) _compressedSize = of_zip_archive_read_field64( &ZIP64, &ZIP64Size); - if (_localFileHeaderOffset == 0xFFFFFFFF) + if (_localFileHeaderOffset == -1) _localFileHeaderOffset = of_zip_archive_read_field64(&ZIP64, &ZIP64Size); if (_startDiskNumber == 0xFFFF) _startDiskNumber = of_zip_archive_read_field32( Index: src/runtime/protocol.m ================================================================== --- src/runtime/protocol.m +++ src/runtime/protocol.m @@ -42,11 +42,11 @@ if (protocol_isEqual(a, b)) return true; for (struct objc_protocol_list *pl = a->protocol_list; pl != NULL; pl = pl->next) - for (size_t i = 0; i < pl->count; i++) + for (long i = 0; i < pl->count; i++) if (protocol_conformsToProtocol(pl->list[i], b)) return true; return false; }