Index: src/OFDeflateStream.m ================================================================== --- src/OFDeflateStream.m +++ src/OFDeflateStream.m @@ -31,12 +31,12 @@ #endif #import "OFDataArray.h" #import "OFInitializationFailedException.h" #import "OFInvalidFormatException.h" +#import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" -#import "OFReadFailedException.h" #define BUFFER_SIZE OF_INFLATE_STREAM_BUFFER_SIZE #define MAX_BITS 15 @@ -304,11 +304,11 @@ return self; } - (void)dealloc { - [_stream release]; + [self close]; if (_decompression != NULL && _decompression->state == HUFFMAN_TREE) if (_decompression->context.huffmanTree.codeLenTree != NULL) releaseTree( _decompression->context.huffmanTree.codeLenTree); @@ -349,18 +349,20 @@ uint16_t value; size_t bytesWritten = 0; uint8_t *slidingWindow; uint16_t slidingWindowIndex; + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + if (ivars == NULL) { [self of_initDecompression]; ivars = _decompression; } if (ivars->atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + return 0; start: switch ((enum state)ivars->state) { case BLOCK_HEADER: if OF_UNLIKELY (ivars->inLastBlock) { @@ -821,12 +823,12 @@ } #ifndef DEFLATE64 - (bool)lowlevelIsAtEndOfStream { - if (_decompression == NULL) - return false; + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; return _decompression->atEndOfStream; } - (int)fileDescriptorForReading @@ -837,6 +839,14 @@ - (bool)hasDataInReadBuffer { return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]); } #endif + +- (void)close +{ + [_stream release]; + _stream = nil; + + [super close]; +} @end Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -33,10 +33,11 @@ #import "OFLocalization.h" #import "OFDataArray.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" +#import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSeekFailedException.h" #import "OFWriteFailedException.h" @@ -307,23 +308,22 @@ } - (bool)lowlevelIsAtEndOfStream { if (!OF_FILE_HANDLE_IS_VALID(_handle)) - return true; + @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; - if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (!OF_FILE_HANDLE_IS_VALID(_handle)) + @throw [OFNotOpenException exceptionWithObject: self]; #if defined(OF_WINDOWS) if (length > UINT_MAX) @throw [OFOutOfRangeException exception]; @@ -352,13 +352,12 @@ } - (void)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { - if (!OF_FILE_HANDLE_IS_VALID(_handle) || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; + if (!OF_FILE_HANDLE_IS_VALID(_handle)) + @throw [OFNotOpenException exceptionWithObject: self]; #if defined(OF_WINDOWS) if (length > INT_MAX) @throw [OFOutOfRangeException exception]; @@ -395,13 +394,11 @@ whence: (int)whence { of_offset_t ret; if (!OF_FILE_HANDLE_IS_VALID(_handle)) - @throw [OFSeekFailedException exceptionWithStream: self - offset: offset - whence: whence]; + @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_MORPHOS # if defined(OF_WINDOWS) ret = _lseeki64(_handle, offset, whence); # elif defined(OF_HAVE_OFF64_T) Index: src/OFGZIPStream.m ================================================================== --- src/OFGZIPStream.m +++ src/OFGZIPStream.m @@ -22,10 +22,12 @@ #import "crc32.h" #import "OFChecksumFailedException.h" #import "OFInvalidFormatException.h" +#import "OFNotOpenException.h" +#import "OFTruncatedDataException.h" @implementation OFGZIPStream + (instancetype)streamWithStream: (OFStream *)stream { return [[[self alloc] initWithStream: stream] autorelease]; @@ -51,23 +53,34 @@ return self; } - (void)dealloc { - [_stream release]; + [self close]; + [_inflateStream release]; [_modificationDate release]; [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { - uint8_t byte; + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; for (;;) { + uint8_t byte; + + if ([_stream isAtEndOfStream]) { + if (_state != OF_GZIP_STREAM_ID1) + @throw [OFTruncatedDataException exception]; + + return 0; + } + switch (_state) { case OF_GZIP_STREAM_ID1: case OF_GZIP_STREAM_ID2: case OF_GZIP_STREAM_COMPRESSION_METHOD: if ([_stream readIntoBuffer: &byte @@ -95,10 +108,13 @@ readIntoBuffer: _buffer + _bytesRead length: 4 - _bytesRead]; if (_bytesRead < 4) return 0; + + [_modificationDate release]; + _modificationDate = nil; _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]]; @@ -260,10 +276,13 @@ } } - (bool)lowlevelIsAtEndOfStream { + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + return [_stream isAtEndOfStream]; } - (bool)hasDataInReadBuffer { @@ -271,6 +290,14 @@ return ([super hasDataInReadBuffer] || [_inflateStream hasDataInReadBuffer]); return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]); } + +- (void)close +{ + [_stream release]; + _stream = nil; + + [super close]; +} @end Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -31,13 +31,13 @@ #import "OFHTTPRequestFailedException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFNotImplementedException.h" +#import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" -#import "OFReadFailedException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" @@ -126,14 +126,15 @@ } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { + if (_socket == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + if (_atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length - errNo: ENOTCONN]; + return 0; if (!_hasContentLength && !_chunked) return [_socket readIntoBuffer: buffer length: length]; @@ -229,10 +230,13 @@ } } - (bool)lowlevelIsAtEndOfStream { + if (_socket == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + if (!_hasContentLength && !_chunked) return [_socket isAtEndOfStream]; return _atEndOfStream; } Index: src/OFProcess.m ================================================================== --- src/OFProcess.m +++ src/OFProcess.m @@ -36,10 +36,11 @@ #import "OFDictionary.h" #import "OFDataArray.h" #import "OFLocalization.h" #import "OFInitializationFailedException.h" +#import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_WINDOWS @@ -436,11 +437,11 @@ #ifndef OF_WINDOWS if (_readPipe[0] == -1) #else if (_readPipe[0] == NULL) #endif - return true; + @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer @@ -447,13 +448,12 @@ length: (size_t)length { #ifndef OF_WINDOWS ssize_t ret; - if (_readPipe[0] == -1 || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (_readPipe[0] == -1) + @throw [OFNotOpenException exceptionWithObject: self]; if ((ret = read(_readPipe[0], buffer, length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: errno]; @@ -461,13 +461,12 @@ DWORD ret; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; - if (_readPipe[0] == NULL || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (_readPipe[0] == NULL) + @throw [OFNotOpenException exceptionWithObject: self]; if (!ReadFile(_readPipe[0], buffer, (DWORD)length, &ret, NULL)) { if (GetLastError() == ERROR_BROKEN_PIPE) { _atEndOfStream = true; return 0; @@ -486,13 +485,12 @@ - (void)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { #ifndef OF_WINDOWS - if (_writePipe[1] == -1 || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; + if (_writePipe[1] == -1) + @throw [OFNotOpenException exceptionWithObject: self]; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if (write(_writePipe[1], buffer, length) != (ssize_t)length) @@ -503,13 +501,12 @@ DWORD ret; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; - if (_writePipe[1] == NULL || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; + if (_writePipe[1] == NULL) + @throw [OFNotOpenException exceptionWithObject: self]; if (!WriteFile(_writePipe[1], buffer, (DWORD)length, &ret, NULL) || ret != (DWORD)length) { int errNo = 0; Index: src/OFStdIOStream.m ================================================================== --- src/OFStdIOStream.m +++ src/OFStdIOStream.m @@ -33,10 +33,11 @@ #import "OFApplication.h" #ifdef OF_WINDOWS # include "OFStdIOStream_Win32Console.h" #endif +#import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifdef OF_MORPHOS @@ -165,15 +166,14 @@ - (bool)lowlevelIsAtEndOfStream { #ifndef OF_MORPHOS if (_fd == -1) - return true; #else if (_handle == 0) - return true; #endif + @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer @@ -180,13 +180,12 @@ length: (size_t)length { ssize_t ret; #ifndef OF_MORPHOS - if (_fd == -1 || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (_fd == -1) + @throw [OFNotOpenException exceptionWithObject: self]; # ifndef OF_WINDOWS if ((ret = read(_fd, buffer, length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length @@ -199,13 +198,12 @@ @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: errno]; # endif #else - if (_handle == 0 || _atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (_handle == 0) + @throw [OFNotOpenException exceptionWithObject: self]; if (length > LONG_MAX) @throw [OFOutOfRangeException exception]; if ((ret = Read(_handle, buffer, length)) < 0) @@ -221,13 +219,12 @@ - (void)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { #ifndef OF_MORPHOS - if (_fd == -1 || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; + if (_fd == -1) + @throw [OFNotOpenException exceptionWithObject: self]; # ifndef OF_WINDOWS if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; @@ -243,13 +240,12 @@ @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length errNo: errno]; # endif #else - if (_handle == 0 || _atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length]; + if (_handle == 0) + @throw [OFNotOpenException exceptionWithObject: self]; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if (Write(_handle, (void *)buffer, length) != (LONG)length) Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -46,10 +46,11 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOutOfRangeException.h" #import "OFSetOptionFailedException.h" +#import "OFTruncatedDataException.h" #import "of_asprintf.h" #define MIN_READ_SIZE 512 @@ -174,13 +175,17 @@ - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length { size_t readLength = 0; - while (readLength < length) + while (readLength < length) { + if ([self isAtEndOfStream]) + @throw [OFTruncatedDataException exception]; + readLength += [self readIntoBuffer: (char *)buffer + readLength length: length - readLength]; + } } #ifdef OF_HAVE_SOCKETS - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length Index: src/OFStreamSocket.m ================================================================== --- src/OFStreamSocket.m +++ src/OFStreamSocket.m @@ -48,10 +48,13 @@ return [[[self alloc] init] autorelease]; } - (bool)lowlevelIsAtEndOfStream { + if (_socket == INVALID_SOCKET) + @throw [OFNotOpenException exceptionWithObject: self]; + return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length @@ -59,15 +62,10 @@ ssize_t ret; if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; - if (_atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length - errNo: ENOTCONN]; - #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length @@ -93,15 +91,10 @@ length: (size_t)length { if (_socket == INVALID_SOCKET) @throw [OFNotOpenException exceptionWithObject: self]; - if (_atEndOfStream) - @throw [OFWriteFailedException exceptionWithObject: self - requestedLength: length - errNo: ENOTCONN]; - #ifndef OF_WINDOWS if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if (send(_socket, buffer, length, 0) != (ssize_t)length) Index: src/OFTarArchiveEntry.m ================================================================== --- src/OFTarArchiveEntry.m +++ src/OFTarArchiveEntry.m @@ -23,12 +23,12 @@ #import "OFTarArchiveEntry.h" #import "OFTarArchiveEntry+Private.h" #import "OFStream.h" #import "OFDate.h" +#import "OFNotOpenException.h" #import "OFOutOfRangeException.h" -#import "OFReadFailedException.h" static OFString * stringFromBuffer(const char *buffer, size_t length) { for (size_t i = 0; i < length; i++) @@ -113,11 +113,12 @@ return self; } - (void)dealloc { - [_stream release]; + [self close]; + [_fileName release]; [_modificationDate release]; [_targetFileName release]; [_owner release]; [_group release]; @@ -128,13 +129,15 @@ - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { size_t ret; + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + if (_atEndOfStream) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + return 0; if ((uint64_t)length > _toRead) length = (size_t)_toRead; ret = [_stream readIntoBuffer: buffer @@ -148,10 +151,13 @@ return ret; } - (bool)lowlevelIsAtEndOfStream { + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + return _atEndOfStream; } - (bool)hasDataInReadBuffer { @@ -158,11 +164,12 @@ return ([super hasDataInReadBuffer] || [_stream hasDataInReadBuffer]); } - (void)close { - _atEndOfStream = true; + [_stream release]; + _stream = nil; [super close]; } - (void)of_skip Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -35,13 +35,13 @@ #import "OFChecksumFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" +#import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" -#import "OFReadFailedException.h" #import "OFSeekFailedException.h" #import "OFUnsupportedVersionException.h" /* * FIXME: Current limitations: @@ -75,11 +75,11 @@ OFStream *_stream, *_decompressedStream; OFZIPArchive_LocalFileHeader *_localFileHeader; bool _hasDataDescriptor; uint64_t _size; uint32_t _CRC32; - bool _atEndOfStream, _closed; + bool _atEndOfStream; } - initWithStream: (OFStream *)path localFileHeader: (OFZIPArchive_LocalFileHeader *)localFileHeader; @end @@ -491,11 +491,12 @@ return self; } - (void)dealloc { - [_stream release]; + [self close]; + [_decompressedStream release]; [_localFileHeader release]; [super dealloc]; } @@ -508,13 +509,15 @@ - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { size_t min, ret; - if (_atEndOfStream || _closed) - @throw [OFReadFailedException exceptionWithObject: self - requestedLength: length]; + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + + if (_atEndOfStream) + return 0; if (_hasDataDescriptor) { if ([_decompressedStream isAtEndOfStream]) { uint32_t CRC32; @@ -558,10 +561,11 @@ return ret; } - (void)close { - _closed = true; + [_stream release]; + _stream = nil; [super close]; } @end