Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -239,11 +239,11 @@ headers = [response headers]; if ((contentLength = [headers objectForKey: @"Content-Length"]) != nil) if ([self count] != - (size_t)[contentLength decimalValue]) + [contentLength decimalValue]) @throw [OFTruncatedDataException exception]; } @catch (id e) { [self release]; @throw e; Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -108,11 +108,16 @@ contentLength = [headers objectForKey: @"Content-Length"]; if (contentLength != nil) { _hasContentLength = true; @try { - _toRead = (size_t)[contentLength decimalValue]; + intmax_t toRead = [contentLength decimalValue]; + + if (toRead > SIZE_MAX) + @throw [OFOutOfRangeException exception]; + + _toRead = (size_t)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } @@ -185,12 +190,16 @@ if (range.location != OF_NOT_FOUND) line = [line substringWithRange: of_range(0, range.location)]; @try { - _toRead = - (size_t)[line hexadecimalValue]; + uintmax_t toRead = [line hexadecimalValue]; + + if (toRead > SIZE_MAX) + @throw [OFOutOfRangeException exception]; + + _toRead = (size_t)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } if (_toRead == 0) { Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -312,11 +312,11 @@ didReadLine: (OFString*)line exception: (OFException*)exception; - (bool)parseProlog: (OFString*)line; - (bool)parseHeaders: (OFString*)line; - (bool)socket: (OFTCPSocket*)socket - didReadIntoBuffer: (const char*)buffer + didReadIntoBuffer: (char*)buffer length: (size_t)length exception: (OFException*)exception; - (bool)sendErrorAndClose: (short)statusCode; - (void)createResponse; @end @@ -455,14 +455,14 @@ { OFString *key, *value; size_t pos; if ([line length] == 0) { - size_t contentLength; + intmax_t contentLength; @try { - contentLength = (size_t)[[_headers + contentLength = [[_headers objectForKey: @"Content-Length"] decimalValue]; } @catch (OFInvalidFormatException *e) { return [self sendErrorAndClose: 400]; } @@ -534,11 +534,11 @@ return true; } - (bool)socket: (OFTCPSocket*)socket - didReadIntoBuffer: (const char*)buffer + didReadIntoBuffer: (char*)buffer length: (size_t)length exception: (OFException*)exception { if ([socket isAtEndOfStream] || exception != nil) return false; @@ -545,10 +545,18 @@ [_entity addItems: buffer count: length]; if ([_entity count] >= _contentLength) { + /* + * Manually free the buffer here. While this is not required + * now as the async read is the only thing referencing self and + * the buffer is allocated on self, it is required once + * Connection: keep-alive is implemented. + */ + [self freeMemory: buffer]; + @try { [self createResponse]; } @catch (OFWriteFailedException *e) { return false; }