summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-03-02 15:14:39 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-03-02 15:14:39 +0000
commit3bb7855a5658c3c093d9c2efbfc8e3417cd55cfd (patch)
treee1c699ac6bb905b617821619053a82c648b1929b /src
parentba78b6f16712c40917312412c91f5e0c11742e12 (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.cc31
-rw-r--r--src/MetalinkParserStateMachine.cc5
-rw-r--r--src/MetalinkParserStateMachine.h2
-rw-r--r--src/MetalinkParserStateV3Impl.cc2
-rw-r--r--src/MetalinkParserStateV4Impl.cc5
-rw-r--r--src/util.cc10
-rw-r--r--src/util.h6
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[] = {
diff --git a/src/util.h b/src/util.h
index d1985209..4aefe6b0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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.