summaryrefslogtreecommitdiff
path: root/src/MetalinkParserStateV4Impl.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-03-02 14:07:30 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-03-02 14:07:30 +0000
commitba78b6f16712c40917312412c91f5e0c11742e12 (patch)
treee6773b0b12914fc372002d8de2a4c6d67a91112e /src/MetalinkParserStateV4Impl.cc
parenteb32f5647923afdc30cb170b84424230714c411f (diff)
2010-03-02 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added strict attribute validation for metalink4. When specification violation is found, discard the whole document. * src/ExpatMetalinkProcessor.cc * src/MetalinkParserStateMachine.cc * src/MetalinkParserStateMachine.h * src/MetalinkParserStateV4Impl.cc * src/XML2SAXMetalinkProcessor.cc * test/Makefile.am * test/MetalinkProcessorTest.cc * test/metalink4-attrs.xml: Removed * test/metalink4-dirtraversal.xml: Removed
Diffstat (limited to 'src/MetalinkParserStateV4Impl.cc')
-rw-r--r--src/MetalinkParserStateV4Impl.cc96
1 files changed, 54 insertions, 42 deletions
diff --git a/src/MetalinkParserStateV4Impl.cc b/src/MetalinkParserStateV4Impl.cc
index fae41831..d95b2772 100644
--- a/src/MetalinkParserStateV4Impl.cc
+++ b/src/MetalinkParserStateV4Impl.cc
@@ -95,16 +95,17 @@ void MetalinkMetalinkParserStateV4::beginElement
const std::vector<XmlAttr>& attrs)
{
if(nsUri == METALINK4_NAMESPACE_URI && localname == FILE) {
+ stm->setFileStateV4();
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, NAME);
- if(itr != attrs.end()) {
- if((*itr).value.empty() || util::detectDirTraversal((*itr).value)) {
- stm->setSkipTagState();
- } else {
- stm->setFileStateV4();
- stm->newEntryTransaction();
- stm->setFileNameOfEntry((*itr).value);
- }
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing file@name");
+ return;
+ } else if(util::detectDirTraversal((*itr).value)) {
+ stm->logError("Bad file@name");
+ return;
}
+ stm->newEntryTransaction();
+ stm->setFileNameOfEntry((*itr).value);
} else {
stm->setSkipTagState();
}
@@ -133,9 +134,11 @@ void FileMetalinkParserStateV4::beginElement
{
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, NAME);
if(itr != attrs.end()) {
- name = (*itr).value;
- if(util::detectDirTraversal(name)) {
+ if((*itr).value.empty() || util::detectDirTraversal((*itr).value)) {
+ stm->logError("Bad metaurl@name");
return;
+ } else {
+ name = (*itr).value;
}
}
}
@@ -148,17 +151,20 @@ void FileMetalinkParserStateV4::beginElement
try {
priority = util::parseInt((*itr).value);
if(priority < 1 || MetalinkResource::getLowestPriority() < priority) {
- priority = MetalinkResource::getLowestPriority();
+ stm->logError("metaurl@priority is out of range");
+ return;
}
} catch(RecoverableException& e) {
- priority = MetalinkResource::getLowestPriority();
+ stm->logError("Bad metaurl@priority");
+ return;
}
}
}
std::string mediatype;
{
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, MEDIATYPE);
- if(itr == attrs.end()) {
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing metaurl@mediatype");
return;
} else {
mediatype = (*itr).value;
@@ -186,10 +192,12 @@ void FileMetalinkParserStateV4::beginElement
try {
priority = util::parseInt((*itr).value);
if(priority < 1 || MetalinkResource::getLowestPriority() < priority) {
- priority = MetalinkResource::getLowestPriority();
+ stm->logError("url@priority is out of range");
+ return;
}
} catch(RecoverableException& e) {
- priority = MetalinkResource::getLowestPriority();
+ stm->logError("Bad url@priority");
+ return;
}
}
}
@@ -201,7 +209,8 @@ void FileMetalinkParserStateV4::beginElement
else if(localname == HASH) {
stm->setHashStateV4();
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, TYPE);
- if(itr == attrs.end()) {
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing hash@type");
return;
} else {
std::string type = (*itr).value;
@@ -210,42 +219,45 @@ void FileMetalinkParserStateV4::beginElement
}
} else if(localname == PIECES) {
stm->setPiecesStateV4();
- try {
- size_t length;
- {
- std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, LENGTH);
- if(itr == attrs.end()) {
- return;
- } else {
- length = util::parseInt((*itr).value);
- }
+ size_t length;
+ {
+ std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, LENGTH);
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing pieces@length");
+ return;
+ } else {
+ try {
+ length = util::parseInt((*itr).value);
+ } catch(RecoverableException& e) {
+ stm->logError("Bad pieces@length");
+ return;
+ }
}
- std::string type;
- {
- std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, TYPE);
- if(itr == attrs.end()) {
- return;
- } else {
- type = (*itr).value;
- }
+ }
+ std::string type;
+ {
+ std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, TYPE);
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing pieces@type");
+ return;
+ } else {
+ type = (*itr).value;
}
- stm->newChunkChecksumTransactionV4();
- stm->setLengthOfChunkChecksumV4(length);
- stm->setTypeOfChunkChecksumV4(type);
- } catch(RecoverableException& e) {
- stm->cancelChunkChecksumTransactionV4();
}
+ stm->newChunkChecksumTransactionV4();
+ stm->setLengthOfChunkChecksumV4(length);
+ stm->setTypeOfChunkChecksumV4(type);
}
#endif // ENABLE_MESSAGE_DIGEST
else if(localname == SIGNATURE) {
stm->setSignatureStateV4();
std::vector<XmlAttr>::const_iterator itr = findAttr(attrs, MEDIATYPE);
- if(itr == attrs.end()) {
+ if(itr == attrs.end() || (*itr).value.empty()) {
+ stm->logError("Missing signature@mediatype");
return;
- } else {
- stm->newSignatureTransaction();
- stm->setTypeOfSignature((*itr).value);
}
+ stm->newSignatureTransaction();
+ stm->setTypeOfSignature((*itr).value);
} else {
stm->setSkipTagState();
}