@@ -77,11 +77,11 @@ @interface OFHTTPClientRequestBodyStream: OFStream { OFHTTPClientRequestHandler *_handler; OFTCPSocket *_socket; bool _chunked; - uintmax_t _toWrite; + unsigned long long _toWrite; bool _atEndOfStream; } - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler socket: (OFTCPSocket *)sock; @@ -91,11 +91,11 @@ @interface OFHTTPClientResponse: OFHTTPResponse { OFTCPSocket *_socket; bool _hasContentLength, _chunked, _keepAlive; bool _atEndOfStream, _setAtEndOfStream; - intmax_t _toRead; + long long _toRead; } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithSocket: (OFTCPSocket *)sock; @@ -443,10 +443,12 @@ } } - (bool)handleFirstLine: (OFString *)line { + long long status; + /* * It's possible that the write succeeds on a connection that is * keep-alive, but the connection has already been closed by the remote * end due to a timeout. In this case, we need to reconnect. */ @@ -462,11 +464,16 @@ _version = [[line substringWithRange: of_range(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; - _status = (int)[line substringWithRange: of_range(9, 3)].decimalValue; + status = [line substringWithRange: of_range(9, 3)].longLongValue; + + if (status < 0 || status > 599) + @throw [OFInvalidServerReplyException exception]; + + _status = (int)status; return true; } - (bool)handleServerHeader: (OFString *)line @@ -730,11 +737,10 @@ { self = [super init]; @try { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; - intmax_t contentLength; OFString *transferEncoding, *contentLengthString; _handler = [handler retain]; _socket = [sock retain]; @@ -747,15 +753,11 @@ if (contentLengthString != nil) { if (_chunked || contentLengthString.length == 0) @throw [OFInvalidArgumentException exception]; - contentLength = contentLengthString.decimalValue; - if (contentLength < 0) - @throw [OFOutOfRangeException exception]; - - _toWrite = contentLength; + _toWrite = contentLengthString.unsignedLongLongValue; } else if (!_chunked) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; @@ -893,15 +895,17 @@ @throw [OFInvalidServerReplyException exception]; _hasContentLength = true; @try { - _toRead = contentLength.decimalValue; + unsigned long long toRead = + contentLength.unsignedLongLongValue; - if (_toRead < 0) - @throw [OFInvalidServerReplyException - exception]; + if (toRead > LLONG_MAX) + @throw [OFOutOfRangeException exception]; + + _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } @@ -924,11 +928,11 @@ /* Content-Length */ if (!_chunked) { size_t ret; - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; @@ -979,11 +983,11 @@ if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { - if (length > (uintmax_t)_toRead) + if (length > (unsigned long long)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; @@ -1024,12 +1028,17 @@ @throw [OFInvalidServerReplyException exception]; } @try { - if ((_toRead = line.hexadecimalValue) < 0) + unsigned long long toRead = + [line unsignedLongLongValueWithBase: 16]; + + if (toRead > LLONG_MAX) @throw [OFOutOfRangeException exception]; + + _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } if (_toRead == 0) {