Index: src/OFHTTPRequest.m ================================================================== --- src/OFHTTPRequest.m +++ src/OFHTTPRequest.m @@ -195,10 +195,11 @@ OFDataArray *data; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object, *contentLengthHeader; int status; const char *type = NULL; + size_t contentLength; BOOL chunked; char *buffer; size_t bytesReceived; if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"]) @@ -370,10 +371,19 @@ withStatusCode: status]; data = (storesData ? [OFDataArray dataArray] : nil); chunked = [[serverHeaders objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; + + contentLengthHeader = [serverHeaders objectForKey: @"Content-Length"]; + + if (contentLengthHeader != nil) { + contentLength = (size_t)[contentLengthHeader decimalValue]; + + if (contentLength > SIZE_MAX) + @throw [OFOutOfRangeException exceptionWithClass: isa]; + } buffer = [self allocMemoryWithSize: of_pagesize]; bytesReceived = 0; @try { OFAutoreleasePool *pool2 = [[OFAutoreleasePool alloc] init]; @@ -401,11 +411,13 @@ } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exceptionWithClass: isa]; } - if (toRead == 0) + if (toRead == 0 || + (contentLengthHeader != nil && + contentLength >= bytesReceived)) break; while (toRead > 0) { size_t length = (toRead < of_pagesize ? toRead : of_pagesize); @@ -449,10 +461,14 @@ [pool2 releaseObjects]; bytesReceived += length; [data addNItems: length fromCArray: buffer]; + + if (contentLengthHeader != nil && + bytesReceived >= contentLength) + break; } } [pool2 release]; } @finally { @@ -459,27 +475,18 @@ [self freeMemory: buffer]; } [sock close]; - if ((contentLengthHeader = - [serverHeaders objectForKey: @"Content-Length"]) != nil) { - intmax_t cl = [contentLengthHeader decimalValue]; - - if (cl > SIZE_MAX) - @throw [OFOutOfRangeException exceptionWithClass: isa]; - - /* - * We only want to throw on these status codes as we will throw - * an OFHTTPRequestFailedException for all other status codes - * later. - */ - if (cl != bytesReceived && (status == 200 || status == 301 || - status == 302 || status == 303)) - @throw [OFTruncatedDataException - exceptionWithClass: isa]; - } + /* + * We only want to throw on these status codes as we will throw an + * OFHTTPRequestFailedException for all other status codes later. + */ + if (contentLengthHeader != nil && contentLength != bytesReceived && + (status == 200 || status == 301 || status == 302 || status == 303 || + status == 307)) + @throw [OFTruncatedDataException exceptionWithClass: isa]; [serverHeaders makeImmutable]; result = [[OFHTTPRequestResult alloc] initWithStatusCode: status headers: serverHeaders