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>
 | 
			
		||||
 | 
			
		||||
	Rewritten array operation functions.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -156,17 +156,14 @@ bool DownloadCommand::executeInternal() {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
#endif // ENABLE_MESSAGE_DIGEST
 | 
			
		||||
 | 
			
		||||
  if(bufSizeFinal > 0) {
 | 
			
		||||
    segment->updateWrittenLength(bufSizeFinal);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  peerStat->updateDownloadLength(bufSize);
 | 
			
		||||
 | 
			
		||||
  _requestGroup->getSegmentMan()->updateDownloadSpeedFor(peerStat);
 | 
			
		||||
 | 
			
		||||
  if(_requestGroup->getTotalLength() != 0 && bufSize == 0 &&
 | 
			
		||||
     !socket->wantRead() && !socket->wantWrite()) {
 | 
			
		||||
    throw DlRetryEx(EX_GOT_EOF);
 | 
			
		||||
  }
 | 
			
		||||
  bool segmentComplete = false;
 | 
			
		||||
  if(_transferEncodingDecoder.isNull() && _contentEncodingDecoder.isNull()) {
 | 
			
		||||
    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) {
 | 
			
		||||
    logger->info(MSG_SEGMENT_DOWNLOAD_COMPLETED, cuid);
 | 
			
		||||
#ifdef ENABLE_MESSAGE_DIGEST
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,6 +68,12 @@
 | 
			
		|||
 | 
			
		||||
namespace aria2 {
 | 
			
		||||
 | 
			
		||||
static SharedHandle<Decoder> getTransferEncodingDecoder
 | 
			
		||||
(const SharedHandle<HttpResponse>& httpResponse);
 | 
			
		||||
 | 
			
		||||
static SharedHandle<Decoder> getContentEncodingDecoder
 | 
			
		||||
(const SharedHandle<HttpResponse>& httpResponse);
 | 
			
		||||
 | 
			
		||||
HttpResponseCommand::HttpResponseCommand(int32_t cuid,
 | 
			
		||||
					 const RequestHandle& req,
 | 
			
		||||
					 RequestGroup* requestGroup,
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +153,8 @@ bool HttpResponseCommand::executeInternal()
 | 
			
		|||
      if(req->getMethod() == Request::METHOD_GET &&
 | 
			
		||||
	 (totalLength != 0 ||
 | 
			
		||||
	  !httpResponse->getHttpHeader()->defined(HttpHeader::CONTENT_LENGTH))){
 | 
			
		||||
	// dctx->knowsTotalLength() == true only when server says the
 | 
			
		||||
	// size of file is 0 explicitly.
 | 
			
		||||
	dctx->markTotalLengthIsUnknown();
 | 
			
		||||
      }
 | 
			
		||||
      return handleOtherEncoding(httpResponse);
 | 
			
		||||
| 
						 | 
				
			
			@ -158,8 +166,19 @@ bool HttpResponseCommand::executeInternal()
 | 
			
		|||
    _requestGroup->validateTotalLength(httpResponse->getEntityLength());
 | 
			
		||||
    // update last modified time
 | 
			
		||||
    updateLastModifiedTime(httpResponse->getLastModifiedTime());
 | 
			
		||||
 | 
			
		||||
    if(_requestGroup->getTotalLength() == 0) {
 | 
			
		||||
      // 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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -299,11 +318,12 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
 | 
			
		|||
  _requestGroup->shouldCancelDownloadForSafety();
 | 
			
		||||
  _requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
 | 
			
		||||
 | 
			
		||||
  // In this context, knowsTotalLength() is true only when the file is
 | 
			
		||||
  // really zero-length.
 | 
			
		||||
  if(_requestGroup->getDownloadContext()->knowsTotalLength()) {
 | 
			
		||||
    poolConnection();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  e->commands.push_back
 | 
			
		||||
    (createHttpDownloadCommand(httpResponse,
 | 
			
		||||
			       getTransferEncodingDecoder(httpResponse),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,6 +91,9 @@ inline size_t countBit32(uint32_t n)
 | 
			
		|||
// Counts set bit in bitfield.
 | 
			
		||||
inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
 | 
			
		||||
{
 | 
			
		||||
  if(nbits == 0) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  size_t count = 0;
 | 
			
		||||
  size_t size = sizeof(uint32_t);
 | 
			
		||||
  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)36, bitfield::countSetBit(bitfield, 47));
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL((size_t)28, bitfield::countSetBit(bitfield, 32));
 | 
			
		||||
  CPPUNIT_ASSERT_EQUAL((size_t)0, bitfield::countSetBit(bitfield, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bitfieldTest::testLastByteMask()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue