Check totalLength of file is less than std::numeric_limits<off_t>::max()

If totalLength is larger than std::numeric_limits<off_t>::max(), throw
DownloadFailureException.
pull/4/head
Tatsuhiro Tsujikawa 2011-12-09 01:12:54 +09:00
parent 7989cd898d
commit 31163c6785
5 changed files with 39 additions and 16 deletions

View File

@ -464,14 +464,13 @@ bool FtpNegotiationCommand::onFileSizeDetermined(off_t totalLength)
}
bool FtpNegotiationCommand::recvSize() {
off_t size = 0;
int64_t size = 0;
int status = ftp_->receiveSizeResponse(size);
if(status == 0) {
return false;
}
if(status == 213) {
if(size > INT64_MAX) {
if(size > std::numeric_limits<off_t>::max()) {
throw DL_ABORT_EX2
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(size)),
error_code::FTP_PROTOCOL_ERROR);

View File

@ -36,6 +36,7 @@
#include "Range.h"
#include "util.h"
#include "A2STR.h"
#include "DownloadFailureException.h"
namespace aria2 {
@ -136,11 +137,13 @@ RangeHandle HttpHeader::getRange() const
if(clenStr.empty()) {
return SharedHandle<Range>(new Range());
} else {
off_t contentLength = util::parseLLInt(clenStr);
int64_t contentLength = util::parseLLInt(clenStr);
if(contentLength < 0) {
throw DL_ABORT_EX("Content-Length must be positive");
}
if(contentLength == 0) {
} else if(contentLength > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(contentLength)));
} else if(contentLength == 0) {
return SharedHandle<Range>(new Range());
} else {
return SharedHandle<Range>
@ -176,13 +179,25 @@ RangeHandle HttpHeader::getRange() const
if(minus == slash) {
return SharedHandle<Range>(new Range());
}
off_t startByte = util::parseLLInt(std::string(byteRangeSpec, minus));
off_t endByte = util::parseLLInt(std::string(minus+1, slash));
off_t entityLength =
int64_t startByte = util::parseLLInt(std::string(byteRangeSpec, minus));
int64_t endByte = util::parseLLInt(std::string(minus+1, slash));
int64_t entityLength =
util::parseLLInt(std::string(slash+1, rangeStr.end()));
if(startByte < 0 || endByte < 0 || entityLength < 0) {
throw DL_ABORT_EX("byte-range-spec must be positive");
}
if(startByte > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(startByte)));
}
if(endByte > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(endByte)));
}
if(entityLength > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(entityLength)));
}
return SharedHandle<Range>(new Range(startByte, endByte, entityLength));
}

View File

@ -148,8 +148,9 @@ void SizeMetalinkParserState::endElement
const std::string& characters)
{
// current metalink specification doesn't require size element.
off_t size;
if(util::parseLLIntNoThrow(size, characters) && size >= 0) {
int64_t size;
if(util::parseLLIntNoThrow(size, characters) && size >= 0 &&
size <= std::numeric_limits<off_t>::max()) {
psm->setFileLengthOfEntry(size);
}
}

View File

@ -254,7 +254,8 @@ void SizeMetalinkParserStateV4::endElement
const std::string& characters)
{
off_t size;
if(util::parseLLIntNoThrow(size, characters) && size >= 0) {
if(util::parseLLIntNoThrow(size, characters) && size >= 0 &&
size <= std::numeric_limits<off_t>::max()) {
psm->setFileLengthOfEntry(size);
} else {
psm->cancelEntryTransaction();

View File

@ -60,6 +60,7 @@
#include "FileEntry.h"
#include "error_code.h"
#include "array_fun.h"
#include "DownloadFailureException.h"
namespace aria2 {
@ -232,7 +233,7 @@ void extractFileEntries
const List* filesList = downcast<List>(infoDict->get(C_FILES));
if(filesList) {
fileEntries.reserve(filesList->size());
off_t length = 0;
int64_t length = 0;
off_t offset = 0;
// multi-file mode
torrent->mode = MULTI;
@ -248,7 +249,10 @@ void extractFileEntries
error_code::BITTORRENT_PARSE_ERROR);
}
length += fileLengthData->i();
if(length > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(length)));
}
std::string pathKey;
if(fileDict->containsKey(C_PATH_UTF8)) {
pathKey = C_PATH_UTF8;
@ -304,8 +308,11 @@ void extractFileEntries
throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str()),
error_code::BITTORRENT_PARSE_ERROR);
}
off_t totalLength = lengthData->i();
int64_t totalLength = lengthData->i();
if(totalLength > std::numeric_limits<off_t>::max()) {
throw DOWNLOAD_FAILURE_EXCEPTION
(fmt(EX_TOO_LARGE_FILE, static_cast<long long int>(totalLength)));
}
// For each uri in urlList, if it ends with '/', then
// concatenate name to it. Specification just says so.
std::vector<std::string> uris;