From ba78b6f16712c40917312412c91f5e0c11742e12 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 2 Mar 2010 14:07:30 +0000 Subject: [PATCH] 2010-03-02 Tatsuhiro Tsujikawa 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 --- ChangeLog | 14 ++ src/ExpatMetalinkProcessor.cc | 38 ++-- src/MetalinkParserStateMachine.cc | 21 ++ src/MetalinkParserStateMachine.h | 13 ++ src/MetalinkParserStateV4Impl.cc | 98 +++++---- src/XML2SAXMetalinkProcessor.cc | 37 ++-- test/Makefile.am | 2 - test/Makefile.in | 2 - test/MetalinkProcessorTest.cc | 349 +++++++++++++++++++++++++++--- test/metalink4-attrs.xml | 11 - test/metalink4-dirtraversal.xml | 27 --- 11 files changed, 461 insertions(+), 151 deletions(-) delete mode 100644 test/metalink4-attrs.xml delete mode 100644 test/metalink4-dirtraversal.xml diff --git a/ChangeLog b/ChangeLog index e7c83499..8d7a0893 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-03-02 Tatsuhiro Tsujikawa + + 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 + 2010-03-02 Tatsuhiro Tsujikawa Added test for Metaurl transaction. diff --git a/src/ExpatMetalinkProcessor.cc b/src/ExpatMetalinkProcessor.cc index 529f8fd8..211d1992 100644 --- a/src/ExpatMetalinkProcessor.cc +++ b/src/ExpatMetalinkProcessor.cc @@ -147,34 +147,32 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle& binar SharedHandle sessionData(new SessionData(_stm)); XML_Parser parser = XML_ParserCreateNS(0, static_cast('\t')); - try { - XML_SetUserData(parser, sessionData.get()); - XML_SetElementHandler(parser, &mlStartElement, &mlEndElement); - XML_SetCharacterDataHandler(parser, &mlCharacters); + auto_delete deleter(parser, XML_ParserFree); + XML_SetUserData(parser, sessionData.get()); + XML_SetElementHandler(parser, &mlStartElement, &mlEndElement); + XML_SetCharacterDataHandler(parser, &mlCharacters); - off_t readOffset = 0; - while(1) { - ssize_t res = binaryStream->readData(buf, bufSize, readOffset); - if(res == 0) { - break; - } - if(XML_Parse(parser, reinterpret_cast(buf), res, 0) == - XML_STATUS_ERROR) { - throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); - } - readOffset += res; + off_t readOffset = 0; + while(1) { + ssize_t res = binaryStream->readData(buf, bufSize, readOffset); + if(res == 0) { + break; } - if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) { + if(XML_Parse(parser, reinterpret_cast(buf), res, 0) == + XML_STATUS_ERROR) { throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); } - } catch(Exception& e) { - XML_ParserFree(parser); - throw; + readOffset += res; + } + if(XML_Parse(parser, 0, 0, 1) == XML_STATUS_ERROR) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); } - XML_ParserFree(parser); if(!_stm->finished()) { throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); } + if(!_stm->getErrors().empty()) { + throw DL_ABORT_EX(_stm->getErrorString()); + } return _stm->getResult(); } diff --git a/src/MetalinkParserStateMachine.cc b/src/MetalinkParserStateMachine.cc index 103662c9..2f114d4a 100644 --- a/src/MetalinkParserStateMachine.cc +++ b/src/MetalinkParserStateMachine.cc @@ -33,6 +33,10 @@ */ /* copyright --> */ #include "MetalinkParserStateMachine.h" + +#include +#include + #include "MetalinkParserStateImpl.h" #include "MetalinkParserStateV3Impl.h" #include "MetalinkParserStateV4Impl.h" @@ -514,4 +518,21 @@ bool MetalinkParserStateMachine::needsCharactersBuffering() const return _stateStack.top()->needsCharactersBuffering(); } +void MetalinkParserStateMachine::logError(const std::string& log) +{ + if(_errors.size() < 10) { + _errors.push_back(log); + } +} + +std::string MetalinkParserStateMachine::getErrorString() const +{ + std::stringstream error; + error << "Specification violation: "; + std::copy(_errors.begin(), _errors.end(), + std::ostream_iterator(error, ", ")); + return error.str(); +} + + } // namespace aria2 diff --git a/src/MetalinkParserStateMachine.h b/src/MetalinkParserStateMachine.h index 601b0d21..472b05da 100644 --- a/src/MetalinkParserStateMachine.h +++ b/src/MetalinkParserStateMachine.h @@ -54,6 +54,9 @@ private: std::stack _stateStack; + // Error messages encountered while parsing document. + std::vector _errors; + static MetalinkParserState* _initialState; static MetalinkParserState* _skipTagState; @@ -245,6 +248,16 @@ public: bool needsCharactersBuffering() const; + // Only stores first 10 errors. + void logError(const std::string& log); + + const std::vector& getErrors() const + { + return _errors; + } + + std::string getErrorString() const; + const SharedHandle& getResult() const { return _ctrl->getResult(); 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& attrs) { if(nsUri == METALINK4_NAMESPACE_URI && localname == FILE) { + stm->setFileStateV4(); std::vector::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::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::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::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::const_iterator itr = findAttr(attrs, LENGTH); - if(itr == attrs.end()) { - return; - } else { - length = util::parseInt((*itr).value); - } + size_t length; + { + std::vector::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::const_iterator itr = findAttr(attrs, TYPE); - if(itr == attrs.end()) { - return; - } else { - type = (*itr).value; - } - } - stm->newChunkChecksumTransactionV4(); - stm->setLengthOfChunkChecksumV4(length); - stm->setTypeOfChunkChecksumV4(type); - } catch(RecoverableException& e) { - stm->cancelChunkChecksumTransactionV4(); } + std::string type; + { + std::vector::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); } #endif // ENABLE_MESSAGE_DIGEST else if(localname == SIGNATURE) { stm->setSignatureStateV4(); std::vector::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(); } diff --git a/src/XML2SAXMetalinkProcessor.cc b/src/XML2SAXMetalinkProcessor.cc index efc78316..2cdd5e6a 100644 --- a/src/XML2SAXMetalinkProcessor.cc +++ b/src/XML2SAXMetalinkProcessor.cc @@ -179,6 +179,12 @@ MetalinkProcessor::parseFile(const std::string& filename) if(retval != 0) { throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); } + if(!_stm->finished()) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + if(!_stm->getErrors().empty()) { + throw DL_ABORT_EX(_stm->getErrorString()); + } return _stm->getResult(); } @@ -198,28 +204,27 @@ MetalinkProcessor::parseFromBinaryStream(const SharedHandle& binar xmlParserCtxtPtr ctx = xmlCreatePushParserCtxt (&mySAXHandler, sessionData.get(), reinterpret_cast(buf), res, 0); - try { - off_t readOffset = res; - while(1) { - ssize_t res = binaryStream->readData(buf, bufSize, readOffset); - if(res == 0) { - break; - } - if(xmlParseChunk(ctx, reinterpret_cast(buf), res, 0) != 0) { - throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); - } - readOffset += res; + auto_delete deleter(ctx, xmlFreeParserCtxt); + + off_t readOffset = res; + while(1) { + ssize_t res = binaryStream->readData(buf, bufSize, readOffset); + if(res == 0) { + break; } - xmlParseChunk(ctx, reinterpret_cast(buf), 0, 1); - } catch(Exception& e) { - xmlFreeParserCtxt(ctx); - throw; + if(xmlParseChunk(ctx, reinterpret_cast(buf), res, 0) != 0) { + throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); + } + readOffset += res; } - xmlFreeParserCtxt(ctx); + xmlParseChunk(ctx, reinterpret_cast(buf), 0, 1); if(!_stm->finished()) { throw DL_ABORT_EX(MSG_CANNOT_PARSE_METALINK); } + if(!_stm->getErrors().empty()) { + throw DL_ABORT_EX(_stm->getErrorString()); + } return _stm->getResult(); } diff --git a/test/Makefile.am b/test/Makefile.am index 14139652..080e0915 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -249,7 +249,5 @@ EXTRA_DIST = 4096chunk.txt\ 2files.metalink\ utf8.torrent\ metalink4.xml\ - metalink4-attrs.xml\ - metalink4-dirtraversal.xml\ metalink3-dirtraversal.xml\ metalink4-groupbymetaurl.xml diff --git a/test/Makefile.in b/test/Makefile.in index ee717047..7598eb15 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -687,8 +687,6 @@ EXTRA_DIST = 4096chunk.txt\ 2files.metalink\ utf8.torrent\ metalink4.xml\ - metalink4-attrs.xml\ - metalink4-dirtraversal.xml\ metalink3-dirtraversal.xml\ metalink4-groupbymetaurl.xml diff --git a/test/MetalinkProcessorTest.cc b/test/MetalinkProcessorTest.cc index b5ef067e..ea28bcdc 100644 --- a/test/MetalinkProcessorTest.cc +++ b/test/MetalinkProcessorTest.cc @@ -17,6 +17,8 @@ # include "Checksum.h" #endif // ENABLE_MESSAGE_DIGEST #include "Signature.h" +#include "StringFormat.h" +#include "RecoverableException.h" namespace aria2 { @@ -24,7 +26,6 @@ class MetalinkProcessorTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(MetalinkProcessorTest); CPPUNIT_TEST(testParseFileV4); - CPPUNIT_TEST(testParseFileV4_dirtraversal); CPPUNIT_TEST(testParseFileV4_attrs); CPPUNIT_TEST(testParseFile); CPPUNIT_TEST(testParseFile_dirtraversal); @@ -50,7 +51,6 @@ private: public: void testParseFileV4(); - void testParseFileV4_dirtraversal(); void testParseFileV4_attrs(); void testParseFile(); void testParseFile_dirtraversal(); @@ -80,7 +80,6 @@ void MetalinkProcessorTest::testParseFileV4() { MetalinkProcessor proc; SharedHandle m = proc.parseFile("metalink4.xml"); - SharedHandle e; SharedHandle r; SharedHandle mu; @@ -133,37 +132,327 @@ void MetalinkProcessorTest::testParseFileV4() #endif // !ENABLE_BITTORRENT } -void MetalinkProcessorTest::testParseFileV4_dirtraversal() -{ - MetalinkProcessor proc; - SharedHandle m = proc.parseFile("metalink4-dirtraversal.xml"); - CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); - CPPUNIT_ASSERT_EQUAL((size_t)0, m->entries[0]->resources.size()); - CPPUNIT_ASSERT_EQUAL((size_t)0, m->entries[0]->metaurls.size()); -} - void MetalinkProcessorTest::testParseFileV4_attrs() { MetalinkProcessor proc; - SharedHandle m = proc.parseFile("metalink4-attrs.xml"); - CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); - std::vector > resources = - m->entries[0]->resources; - CPPUNIT_ASSERT_EQUAL((size_t)3, resources.size()); - CPPUNIT_ASSERT_EQUAL(999999, resources[0]->priority); - CPPUNIT_ASSERT_EQUAL(999999, resources[1]->priority); - CPPUNIT_ASSERT_EQUAL(999999, resources[2]->priority); + SharedHandle m; + SharedHandle dw(new ByteArrayDiskWriter()); + { + // Testing file@name + const char* tmpl = "" + "" + "" + "http://example.org" + "" + ""; + dw->setString(StringFormat(tmpl, "foo").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); - std::vector > metaurls = - m->entries[0]->metaurls; -#ifdef ENABLE_BITTORRENT - CPPUNIT_ASSERT_EQUAL((size_t)3, metaurls.size()); - CPPUNIT_ASSERT_EQUAL(999999, metaurls[0]->priority); - CPPUNIT_ASSERT_EQUAL(999999, metaurls[1]->priority); - CPPUNIT_ASSERT_EQUAL(999999, metaurls[2]->priority); -#else // !ENABLE_BITTORRENT - CPPUNIT_ASSERT_EQUAL((size_t)0, metaurls.size()); -#endif // !ENABLE_BITTORRENT + // empty name + dw->setString(StringFormat(tmpl, "").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + + // dir traversing + dw->setString(StringFormat(tmpl, "../doughnuts").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + } + { + // Testing url@priority + const char* tmpl = "" + "" + "" + "http://example.org" + "" + ""; + dw->setString(StringFormat(tmpl, "0").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + + dw->setString(StringFormat(tmpl, "1").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "100").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "999999").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "1000000").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + } + { + // Testing metaurl@priority + const char* tmpl = + "" + "" + "" + "http://example.org" + "" + ""; + dw->setString(StringFormat(tmpl, "0").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + + dw->setString(StringFormat(tmpl, "1").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "100").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "999999").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + dw->setString(StringFormat(tmpl, "1000000").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + } + { + // Testing metaurl@mediatype + + // no mediatype + dw->setString("" + "" + "" + "http://example.org" + "" + ""); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + + const char* tmpl = + "" + "" + "" + "http://example.org" + "" + ""; + + dw->setString(StringFormat(tmpl, "torrent").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + // empty mediatype + dw->setString(StringFormat(tmpl, "").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + } + { + // Testing metaurl@name + const char* tmpl = + "" + "" + "" + "http://example.org" + "" + ""; + + dw->setString(StringFormat(tmpl, "foo").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_ASSERT_EQUAL((size_t)1, m->entries.size()); + + // dir traversing + dw->setString(StringFormat(tmpl, "../doughnuts").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + // empty name + dw->setString(StringFormat(tmpl, "").str()); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) { + // success + } + } + { + // Testing pieces@length + // No pieces@length + dw->setString + ("" + "" + "" + "http://example.org" + "" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + "" + ""); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + + const char* tmpl = + "" + "" + "" + "http://example.org" + "" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + "" + ""; + + dw->setString(StringFormat(tmpl, "262144").str()); + m = proc.parseFromBinaryStream(dw); + // empty + try { + dw->setString(StringFormat(tmpl, "").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + } + { + // Testing pieces@type + // No pieces@type + dw->setString + ("" + "" + "" + "http://example.org" + "" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + "" + ""); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + + const char* tmpl = + "" + "" + "" + "http://example.org" + "" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + "" + ""; + + dw->setString(StringFormat(tmpl, "sha-1").str()); + m = proc.parseFromBinaryStream(dw); + // empty + try { + dw->setString(StringFormat(tmpl, "").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + } + { + // Testing hash@type + // No hash@type + dw->setString + ("" + "" + "" + "http://example.org" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + ""); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + + const char* tmpl = + "" + "" + "" + "http://example.org" + "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + "" + ""; + + dw->setString(StringFormat(tmpl, "sha-1").str()); + m = proc.parseFromBinaryStream(dw); + // empty + try { + dw->setString(StringFormat(tmpl, "").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + } + { + // Testing signature@mediatype + // No hash@type + dw->setString + ("" + "" + "" + "http://example.org" + "sig" + "" + ""); + try { + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + + const char* tmpl = + "" + "" + "" + "http://example.org" + "sig" + "" + ""; + + dw->setString(StringFormat(tmpl, "application/pgp-signature").str()); + m = proc.parseFromBinaryStream(dw); + // empty + try { + dw->setString(StringFormat(tmpl, "").str()); + m = proc.parseFromBinaryStream(dw); + CPPUNIT_FAIL("exception must be thrown."); + } catch(RecoverableException& e) {} + } } void MetalinkProcessorTest::testParseFile() diff --git a/test/metalink4-attrs.xml b/test/metalink4-attrs.xml deleted file mode 100644 index d1a1c32f..00000000 --- a/test/metalink4-attrs.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - ftp://ftp.example.com/example.ext - http://example.com/example.ext - http://example.org/example.ext - http://example.com/example.ext.torrent - http://example.org/example.ext.torrent - http://example.net/example.ext.torrent - - diff --git a/test/metalink4-dirtraversal.xml b/test/metalink4-dirtraversal.xml deleted file mode 100644 index 87e5fe54..00000000 --- a/test/metalink4-dirtraversal.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.ext - - - http://example.com/example.torrent - -