Index: src/OFGZIPStream.m ================================================================== --- src/OFGZIPStream.m +++ src/OFGZIPStream.m @@ -21,11 +21,11 @@ #import "OFInflateStream.h" #import "OFDate.h" #import "crc32.h" -#import "OFChecksumFailedException.h" +#import "OFChecksumMismatchException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFTruncatedDataException.h" @@ -79,10 +79,11 @@ if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; for (;;) { uint8_t byte; + uint32_t CRC32, uncompressedSize; if ([_stream isAtEndOfStream]) { if (_state != OF_GZIP_STREAM_ID1) @throw [OFTruncatedDataException exception]; @@ -259,26 +260,43 @@ length: 4 - _bytesRead]; if (_bytesRead < 4) return 0; - if ((((uint32_t)_buffer[3] << 24) | (_buffer[2] << 16) | - (_buffer[1] << 8) | _buffer[0]) != ~_CRC32) - @throw [OFChecksumFailedException exception]; + CRC32 = ((uint32_t)_buffer[3] << 24) | + (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]; + if (~_CRC32 != CRC32) { + OFString *actual = [OFString stringWithFormat: + @"%08" PRIX32, ~_CRC32]; + OFString *expected = [OFString stringWithFormat: + @"%08" PRIX32, CRC32]; + + @throw [OFChecksumMismatchException + exceptionWithActualChecksum: actual + expectedChecksum: expected]; + } _bytesRead = 0; _CRC32 = ~0; _state++; break; case OF_GZIP_STREAM_UNCOMPRESSED_SIZE: _bytesRead += [_stream readIntoBuffer: _buffer length: 4 - _bytesRead]; - if ((((uint32_t)_buffer[3] << 24) | (_buffer[2] << 16) | - (_buffer[1] << 8) | _buffer[0]) != - _uncompressedSize) - @throw [OFChecksumFailedException exception]; + uncompressedSize = ((uint32_t)_buffer[3] << 24) | + (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]; + if (_uncompressedSize != uncompressedSize) { + OFString *actual = [OFString stringWithFormat: + @"%" PRIu32, _uncompressedSize]; + OFString *expected = [OFString stringWithFormat: + @"%" PRIu32, uncompressedSize]; + + @throw [OFChecksumMismatchException + exceptionWithActualChecksum: actual + expectedChecksum: expected]; + } _bytesRead = 0; _uncompressedSize = 0; _state = OF_GZIP_STREAM_ID1; break; Index: src/OFLHAArchive.m ================================================================== --- src/OFLHAArchive.m +++ src/OFLHAArchive.m @@ -30,11 +30,11 @@ #import "OFString.h" #import "crc16.h" #import "huffman_tree.h" -#import "OFChecksumFailedException.h" +#import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFTruncatedDataException.h" @@ -808,12 +808,20 @@ _CRC16 = of_crc16(_CRC16, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; - if (_CRC16 != [_entry CRC16]) - @throw [OFChecksumFailedException exception]; + if (_CRC16 != [_entry CRC16]) { + OFString *actualChecksum = [OFString stringWithFormat: + @"%04" PRIX16, _CRC16]; + OFString *expectedChecksum = [OFString stringWithFormat: + @"%04" PRIX16, [_entry CRC16]]; + + @throw [OFChecksumMismatchException + exceptionWithActualChecksum: actualChecksum + expectedChecksum: expectedChecksum]; + } } return ret; } Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -33,11 +33,11 @@ #import "OFInflateStream.h" #import "OFInflate64Stream.h" #import "crc32.h" -#import "OFChecksumFailedException.h" +#import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" @@ -816,12 +816,20 @@ _CRC32 = of_crc32(_CRC32, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; - if (~_CRC32 != [_entry CRC32]) - @throw [OFChecksumFailedException exception]; + if (~_CRC32 != [_entry CRC32]) { + OFString *actualChecksum = [OFString stringWithFormat: + @"%08" PRIX32, ~_CRC32]; + OFString *expectedChecksum = [OFString stringWithFormat: + @"%08" PRIX32, [_entry CRC32]]; + + @throw [OFChecksumMismatchException + exceptionWithActualChecksum: actualChecksum + expectedChecksum: expectedChecksum]; + } } return ret; } Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -130,11 +130,11 @@ # import "OFAddressTranslationFailedException.h" # import "OFAlreadyConnectedException.h" # import "OFBindFailedException.h" #endif #import "OFChangeCurrentDirectoryPathFailedException.h" -#import "OFChecksumFailedException.h" +#import "OFChecksumMismatchException.h" #ifdef OF_HAVE_THREADS # import "OFConditionBroadcastFailedException.h" # import "OFConditionSignalFailedException.h" # import "OFConditionStillWaitingException.h" # import "OFConditionWaitFailedException.h" Index: src/exceptions/Makefile ================================================================== --- src/exceptions/Makefile +++ src/exceptions/Makefile @@ -3,11 +3,11 @@ STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A} STATIC_LIB_NOINST = ${EXCEPTIONS_A} SRCS = OFAllocFailedException.m \ OFChangeCurrentDirectoryPathFailedException.m \ - OFChecksumFailedException.m \ + OFChecksumMismatchException.m \ OFCopyItemFailedException.m \ OFCreateDirectoryFailedException.m \ OFCreateSymbolicLinkFailedException.m \ OFEnumerationMutationException.m \ OFException.m \ DELETED src/exceptions/OFChecksumFailedException.h Index: src/exceptions/OFChecksumFailedException.h ================================================================== --- src/exceptions/OFChecksumFailedException.h +++ src/exceptions/OFChecksumFailedException.h @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#import "OFException.h" - -OF_ASSUME_NONNULL_BEGIN - -/*! - * @class OFChecksumFailedException \ - * OFChecksumFailedException.h ObjFW/OFChecksumFailedException.h - * - * @brief An exception indicating that a checksum did not match. - */ -@interface OFChecksumFailedException: OFException -@end - -OF_ASSUME_NONNULL_END DELETED src/exceptions/OFChecksumFailedException.m Index: src/exceptions/OFChecksumFailedException.m ================================================================== --- src/exceptions/OFChecksumFailedException.m +++ src/exceptions/OFChecksumFailedException.m @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "OFChecksumFailedException.h" -#import "OFString.h" - -@implementation OFChecksumFailedException -- (OFString *)description -{ - return @"Checksum mismatch!"; -} -@end ADDED src/exceptions/OFChecksumMismatchException.h Index: src/exceptions/OFChecksumMismatchException.h ================================================================== --- src/exceptions/OFChecksumMismatchException.h +++ src/exceptions/OFChecksumMismatchException.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" + +OF_ASSUME_NONNULL_BEGIN + +/*! + * @class OFChecksumMismatchException \ + * OFChecksumMismatchException.h ObjFW/OFChecksumMismatchException.h + * + * @brief An exception indicating that a checksum did not match. + */ +@interface OFChecksumMismatchException: OFException +{ + OFString *_actualChecksum, *_expectedChecksum; +} + +/*! + * @brief The actual checksum calculated. + */ +@property (readonly, nonatomic) OFString *actualChecksum; + +/*! + * @brief The expected checksum. + */ +@property (readonly, nonatomic) OFString *expectedChecksum; + ++ (instancetype)exception OF_UNAVAILABLE; + +/*! + * @brief Creates a new, autoreleased checksum mismatch exception. + * + * @param actualChecksum The actual checksum calculated + * @param expectedChecksum The expected checksum + * @return A new, autoreleased checksum mismatch exception. + */ ++ (instancetype)exceptionWithActualChecksum: (OFString *)actualChecksum + expectedChecksum: (OFString *)expectedChecksum; + +- (instancetype)init OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated checksum mismatch exception. + * + * @param actualChecksum The actual checksum calculated + * @param expectedChecksum The expected checksum + * @return An initialized checksum mismatch exception. + */ +- (instancetype)initWithActualChecksum: (OFString *)actualChecksum + expectedChecksum: (OFString *)expectedChecksum + OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END ADDED src/exceptions/OFChecksumMismatchException.m Index: src/exceptions/OFChecksumMismatchException.m ================================================================== --- src/exceptions/OFChecksumMismatchException.m +++ src/exceptions/OFChecksumMismatchException.m @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFChecksumMismatchException.h" +#import "OFString.h" + +@implementation OFChecksumMismatchException +@synthesize actualChecksum = _actualChecksum; +@synthesize expectedChecksum = _expectedChecksum; + ++ (instancetype)exception +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (instancetype)exceptionWithActualChecksum: (OFString *)actualChecksum + expectedChecksum: (OFString *)expectedChecksum +{ + return [[[self alloc] + initWithActualChecksum: actualChecksum + expectedChecksum: expectedChecksum] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithActualChecksum: (OFString *)actualChecksum + expectedChecksum: (OFString *)expectedChecksum +{ + self = [super init]; + + @try { + _actualChecksum = [actualChecksum copy]; + _expectedChecksum = [expectedChecksum copy]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_actualChecksum release]; + [_expectedChecksum release]; + + [super dealloc]; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"Checksum was %@ but %@ was expected!", + _actualChecksum, _expectedChecksum]; +} +@end