mirror of https://github.com/aria2/aria2
				
				
				
			2009-04-17 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed segmentation fault when GZipDecoder::decode() returns 0 byte. * src/DownloadCommand.cc * src/bitfield.h * test/bitfieldTest.cc Fixed the bug that causes infinite loop if broken web server returns chunked response without last "0" chunk-size marker and closes connection. * src/DownloadCommand.cc Instantiate properly configured HttpDownloadCommand for non-resumable downlaods. * src/HttpResponseCommand.ccpull/1/head
							parent
							
								
									d2d4f67bbe
								
							
						
					
					
						commit
						65a358c68b
					
				
							
								
								
									
										17
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										17
									
								
								ChangeLog
								
								
								
								
							| 
						 | 
					@ -1,3 +1,20 @@
 | 
				
			||||||
 | 
					2009-04-17  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Fixed segmentation fault when GZipDecoder::decode() returns 0
 | 
				
			||||||
 | 
						byte.
 | 
				
			||||||
 | 
						* src/DownloadCommand.cc
 | 
				
			||||||
 | 
						* src/bitfield.h
 | 
				
			||||||
 | 
						* test/bitfieldTest.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Fixed the bug that causes infinite loop if broken web server
 | 
				
			||||||
 | 
						returns chunked response without last "0" chunk-size marker and
 | 
				
			||||||
 | 
						closes connection.
 | 
				
			||||||
 | 
						* src/DownloadCommand.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Instantiate properly configured HttpDownloadCommand for
 | 
				
			||||||
 | 
						non-resumable downlaods.
 | 
				
			||||||
 | 
						* src/HttpResponseCommand.cc
 | 
				
			||||||
 | 
						
 | 
				
			||||||
2009-04-16  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 | 
					2009-04-16  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Rewritten array operation functions.
 | 
						Rewritten array operation functions.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,17 +156,14 @@ bool DownloadCommand::executeInternal() {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // ENABLE_MESSAGE_DIGEST
 | 
					#endif // ENABLE_MESSAGE_DIGEST
 | 
				
			||||||
 | 
					  if(bufSizeFinal > 0) {
 | 
				
			||||||
 | 
					    segment->updateWrittenLength(bufSizeFinal);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  segment->updateWrittenLength(bufSizeFinal);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  peerStat->updateDownloadLength(bufSize);
 | 
					  peerStat->updateDownloadLength(bufSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
 | 
					  _requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(_requestGroup->getTotalLength() != 0 && bufSize == 0 &&
 | 
					 | 
				
			||||||
     !socket->wantRead() && !socket->wantWrite()) {
 | 
					 | 
				
			||||||
    throw DlRetryEx(EX_GOT_EOF);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  bool segmentComplete = false;
 | 
					  bool segmentComplete = false;
 | 
				
			||||||
  if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
 | 
					  if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
 | 
				
			||||||
    if(segment->complete()) {
 | 
					    if(segment->complete()) {
 | 
				
			||||||
| 
						 | 
					@ -193,6 +190,11 @@ bool DownloadCommand::executeInternal() {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(!segmentComplete && bufSize == 0 &&
 | 
				
			||||||
 | 
					     !socket->wantRead() && !socket->wantWrite()) {
 | 
				
			||||||
 | 
					    throw DlRetryEx(EX_GOT_EOF);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(segmentComplete) {
 | 
					  if(segmentComplete) {
 | 
				
			||||||
    logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
 | 
					    logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
 | 
				
			||||||
#ifdef ENABLE_MESSAGE_DIGEST
 | 
					#ifdef ENABLE_MESSAGE_DIGEST
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace aria2 {
 | 
					namespace aria2 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SharedHandle<Decoder> getTransferEncodingDecoder
 | 
				
			||||||
 | 
					(const SharedHandle<HttpResponse>& httpResponse);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SharedHandle<Decoder> getContentEncodingDecoder
 | 
				
			||||||
 | 
					(const SharedHandle<HttpResponse>& httpResponse);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HttpResponseCommand::HttpResponseCommand(int32_t cuid,
 | 
					HttpResponseCommand::HttpResponseCommand(int32_t cuid,
 | 
				
			||||||
					 const RequestHandle& req,
 | 
										 const RequestHandle& req,
 | 
				
			||||||
					 RequestGroup* requestGroup,
 | 
										 RequestGroup* requestGroup,
 | 
				
			||||||
| 
						 | 
					@ -147,6 +153,8 @@ bool HttpResponseCommand::executeInternal()
 | 
				
			||||||
      if(req->getMethod() == Request::METHOD_GET &&
 | 
					      if(req->getMethod() == Request::METHOD_GET &&
 | 
				
			||||||
	 (totalLength != 0 ||
 | 
						 (totalLength != 0 ||
 | 
				
			||||||
	  !httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
 | 
						  !httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
 | 
				
			||||||
 | 
						// dctx->knowsTotalLength() == true only when server says the
 | 
				
			||||||
 | 
						// size of file is 0 explicitly.
 | 
				
			||||||
	dctx->markTotalLengthIsUnknown();
 | 
						dctx->markTotalLengthIsUnknown();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return handleOtherEncoding(httpResponse);
 | 
					      return handleOtherEncoding(httpResponse);
 | 
				
			||||||
| 
						 | 
					@ -158,8 +166,19 @@ bool HttpResponseCommand::executeInternal()
 | 
				
			||||||
    _requestGroup->validateTotalLength(httpResponse->getEntityLength());
 | 
					    _requestGroup->validateTotalLength(httpResponse->getEntityLength());
 | 
				
			||||||
    // update last modified time
 | 
					    // update last modified time
 | 
				
			||||||
    updateLastModifiedTime(httpResponse->getLastModifiedTime());
 | 
					    updateLastModifiedTime(httpResponse->getLastModifiedTime());
 | 
				
			||||||
 | 
					    if(_requestGroup->getTotalLength() == 0) {
 | 
				
			||||||
    e->commands.push_back(createHttpDownloadCommand(httpResponse));
 | 
					      // Since total length is unknown, the file size in previously
 | 
				
			||||||
 | 
					      // failed download could be larger than the size this time.
 | 
				
			||||||
 | 
					      // Also we can't resume in this case too.  So truncate the file
 | 
				
			||||||
 | 
					      // anyway.
 | 
				
			||||||
 | 
					      _requestGroup->getPieceStorage()->getDiskAdaptor()->truncate(0);
 | 
				
			||||||
 | 
					      e->commands.push_back
 | 
				
			||||||
 | 
						(createHttpDownloadCommand(httpResponse,
 | 
				
			||||||
 | 
									   getTransferEncodingDecoder(httpResponse),
 | 
				
			||||||
 | 
									   getContentEncodingDecoder(httpResponse)));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      e->commands.push_back(createHttpDownloadCommand(httpResponse));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -299,11 +318,12 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
 | 
				
			||||||
  _requestGroup->shouldCancelDownloadForSafety();
 | 
					  _requestGroup->shouldCancelDownloadForSafety();
 | 
				
			||||||
  _requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
 | 
					  _requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // In this context, knowsTotalLength() is true only when the file is
 | 
				
			||||||
 | 
					  // really zero-length.
 | 
				
			||||||
  if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
 | 
					  if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
 | 
				
			||||||
    poolConnection();
 | 
					    poolConnection();
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  e->commands.push_back
 | 
					  e->commands.push_back
 | 
				
			||||||
    (createHttpDownloadCommand(httpResponse,
 | 
					    (createHttpDownloadCommand(httpResponse,
 | 
				
			||||||
			       getTransferEncodingDecoder(httpResponse),
 | 
								       getTransferEncodingDecoder(httpResponse),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,9 @@ inline size_t countBit32(uint32_t n)
 | 
				
			||||||
// Counts set bit in bitfield.
 | 
					// Counts set bit in bitfield.
 | 
				
			||||||
inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
 | 
					inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  if(nbits == 0) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  size_t count = 0;
 | 
					  size_t count = 0;
 | 
				
			||||||
  size_t size = sizeof(uint32_t);
 | 
					  size_t size = sizeof(uint32_t);
 | 
				
			||||||
  size_t len = (nbits+7)/8;
 | 
					  size_t len = (nbits+7)/8;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ void bitfieldTest::testCountSetBit()
 | 
				
			||||||
  CPPUNIT_ASSERT_EQUAL((size_t)37, bitfield::countSetBit(bitfield, 48));
 | 
					  CPPUNIT_ASSERT_EQUAL((size_t)37, bitfield::countSetBit(bitfield, 48));
 | 
				
			||||||
  CPPUNIT_ASSERT_EQUAL((size_t)36, bitfield::countSetBit(bitfield, 47));
 | 
					  CPPUNIT_ASSERT_EQUAL((size_t)36, bitfield::countSetBit(bitfield, 47));
 | 
				
			||||||
  CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
 | 
					  CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
 | 
				
			||||||
 | 
					  CPPUNIT_ASSERT_EQUAL((size_t)0, bitfield::countSetBit(bitfield, 0));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bitfieldTest::testLastByteMask()
 | 
					void bitfieldTest::testLastByteMask()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue