diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-03-02 15:14:39 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-03-02 15:14:39 +0000 |
| commit | 3bb7855a5658c3c093d9c2efbfc8e3417cd55cfd (patch) | |
| tree | e1c699ac6bb905b617821619053a82c648b1929b /src | |
| parent | ba78b6f16712c40917312412c91f5e0c11742e12 (diff) | |
2010-03-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
In Metalink4, if size element contains invalid size, discard whole
document. Added strict hash value check for metalink3/4.
* src/MetalinkParserController.cc
* src/MetalinkParserStateMachine.cc
* src/MetalinkParserStateMachine.h
* src/MetalinkParserStateV3Impl.cc
* src/MetalinkParserStateV4Impl.cc
* src/util.cc
* src/util.h
* test/MetalinkParserControllerTest.cc
* test/MetalinkProcessorTest.cc
* test/metalink4.xml
Diffstat (limited to 'src')
| -rw-r--r-- | src/MetalinkParserController.cc | 31 | ||||
| -rw-r--r-- | src/MetalinkParserStateMachine.cc | 5 | ||||
| -rw-r--r-- | src/MetalinkParserStateMachine.h | 2 | ||||
| -rw-r--r-- | src/MetalinkParserStateV3Impl.cc | 2 | ||||
| -rw-r--r-- | src/MetalinkParserStateV4Impl.cc | 5 | ||||
| -rw-r--r-- | src/util.cc | 10 | ||||
| -rw-r--r-- | src/util.h | 6 |
7 files changed, 53 insertions, 8 deletions
diff --git a/src/MetalinkParserController.cc b/src/MetalinkParserController.cc index d3045b97..b340af49 100644 --- a/src/MetalinkParserController.cc +++ b/src/MetalinkParserController.cc @@ -53,6 +53,13 @@ namespace aria2 { +static bool isValidHash(const std::string& algo, const std::string& hash) +{ + return util::isHexDigit(hash) && + MessageDigestContext::supports(algo) && + MessageDigestContext::digestLength(algo)*2 == hash.size(); +} + MetalinkParserController::MetalinkParserController(): _metalinker(new Metalinker()) {} @@ -281,7 +288,11 @@ void MetalinkParserController::setHashOfChecksum(const std::string& md) if(_tChecksum.isNull()) { return; } - _tChecksum->setMessageDigest(md); + if(isValidHash(_tChecksum->getAlgo(), md)) { + _tChecksum->setMessageDigest(md); + } else { + cancelChecksumTransaction(); + } #endif // ENABLE_MESSAGE_DIGEST } @@ -352,7 +363,11 @@ void MetalinkParserController::addHashOfChunkChecksumV4(const std::string& md) if(_tChunkChecksumV4.isNull()) { return; } - _tempChunkChecksumsV4.push_back(md); + if(isValidHash(_tChunkChecksumV4->getAlgo(), md)) { + _tempChunkChecksumsV4.push_back(md); + } else { + cancelChunkChecksumTransactionV4(); + } #endif // ENABLE_MESSAGE_DIGEST } @@ -426,7 +441,11 @@ void MetalinkParserController::addHashOfChunkChecksum(size_t order, const std::s if(_tChunkChecksum.isNull()) { return; } - _tempChunkChecksums.push_back(std::pair<size_t, std::string>(order, md)); + if(isValidHash(_tChunkChecksum->getAlgo(), md)) { + _tempChunkChecksums.push_back(std::make_pair(order, md)); + } else { + cancelChunkChecksumTransaction(); + } #endif // ENABLE_MESSAGE_DIGEST } @@ -446,7 +465,11 @@ void MetalinkParserController::setMessageDigestOfChunkChecksum(const std::string if(_tChunkChecksum.isNull()) { return; } - _tempHashPair.second = md; + if(isValidHash(_tChunkChecksum->getAlgo(), md)) { + _tempHashPair.second = md; + } else { + cancelChunkChecksumTransaction(); + } #endif // ENABLE_MESSAGE_DIGEST } diff --git a/src/MetalinkParserStateMachine.cc b/src/MetalinkParserStateMachine.cc index 2f114d4a..5d28ef3c 100644 --- a/src/MetalinkParserStateMachine.cc +++ b/src/MetalinkParserStateMachine.cc @@ -290,6 +290,11 @@ void MetalinkParserStateMachine::commitEntryTransaction() _ctrl->commitEntryTransaction(); } +void MetalinkParserStateMachine::cancelEntryTransaction() +{ + _ctrl->cancelEntryTransaction(); +} + void MetalinkParserStateMachine::newResourceTransaction() { _ctrl->newResourceTransaction(); diff --git a/src/MetalinkParserStateMachine.h b/src/MetalinkParserStateMachine.h index 472b05da..1eea88b5 100644 --- a/src/MetalinkParserStateMachine.h +++ b/src/MetalinkParserStateMachine.h @@ -166,6 +166,8 @@ public: void commitEntryTransaction(); + void cancelEntryTransaction(); + void newResourceTransaction(); void setURLOfResource(const std::string& url); diff --git a/src/MetalinkParserStateV3Impl.cc b/src/MetalinkParserStateV3Impl.cc index c4068836..98a931dd 100644 --- a/src/MetalinkParserStateV3Impl.cc +++ b/src/MetalinkParserStateV3Impl.cc @@ -183,7 +183,7 @@ void SizeMetalinkParserState::endElement const std::string& characters) { try { - stm->setFileLengthOfEntry(util::parseLLInt(characters)); + stm->setFileLengthOfEntry(util::parseULLInt(characters)); } catch(RecoverableException& e) { // current metalink specification doesn't require size element. } diff --git a/src/MetalinkParserStateV4Impl.cc b/src/MetalinkParserStateV4Impl.cc index d95b2772..fc81e89a 100644 --- a/src/MetalinkParserStateV4Impl.cc +++ b/src/MetalinkParserStateV4Impl.cc @@ -281,9 +281,10 @@ void SizeMetalinkParserStateV4::endElement const std::string& characters) { try { - stm->setFileLengthOfEntry(util::parseLLInt(characters)); + stm->setFileLengthOfEntry(util::parseULLInt(characters)); } catch(RecoverableException& e) { - // current metalink specification doesn't require size element. + stm->cancelEntryTransaction(); + stm->logError("Bad size"); } } diff --git a/src/util.cc b/src/util.cc index 5b6b6832..01e4bb96 100644 --- a/src/util.cc +++ b/src/util.cc @@ -216,6 +216,16 @@ bool isHexDigit(const char c) return isDigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'); } +bool isHexDigit(const std::string& s) +{ + for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) { + if(!isHexDigit(*i)) { + return false; + } + } + return true; +} + bool inRFC3986ReservedChars(const char c) { static const char reserved[] = { @@ -254,11 +254,15 @@ void sleep(long seconds); void usleep(long microseconds); bool isNumber(const std::string& what); + +bool isHexDigit(const char c); + +bool isHexDigit(const std::string& s); bool isLowercase(const std::string& what); bool isUppercase(const std::string& what); - + /** * Converts alphabets to unsigned int, assuming alphabets as a base 26 * integer and 'a' or 'A' is 0. |
