From 7bbc5769a58f98d1641d2ec230fef857cbcccf29 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 12 Mar 2010 15:00:28 +0000 Subject: [PATCH] 2010-03-12 Tatsuhiro Tsujikawa Inspect all xt in magnet to find urn:btih. * src/bittorrent_helper.cc * test/BittorrentHelperTest.cc --- ChangeLog | 6 ++++++ src/bittorrent_helper.cc | 38 ++++++++++++++++++++---------------- test/BittorrentHelperTest.cc | 6 ++++++ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc91afe8..862cd351 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-03-12 Tatsuhiro Tsujikawa + + Inspect all xt in magnet to find urn:btih. + * src/bittorrent_helper.cc + * test/BittorrentHelperTest.cc + 2010-03-12 Tatsuhiro Tsujikawa Use global option for DHTSetup. diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc index 864a5396..ffc9decb 100644 --- a/src/bittorrent_helper.cc +++ b/src/bittorrent_helper.cc @@ -863,25 +863,29 @@ BDE parseMagnet(const std::string& magnet) if(!r.containsKey("xt")) { throw DL_ABORT_EX("Missing xt parameter in Magnet URI."); } + std::string infoHash; const BDE& xts = r["xt"]; - if(xts.size() == 0 || !util::startsWith(xts[0].s(), "urn:btih:")) { - throw DL_ABORT_EX("Bad BitTorrent Magnet URI."); + for(BDE::List::const_iterator xtiter = xts.listBegin(), + eoi = xts.listEnd(); xtiter != eoi && infoHash.empty(); ++xtiter) { + if(util::startsWith((*xtiter).s(), "urn:btih:")) { + std::string xtarg = (*xtiter).s().substr(9); + size_t size = xtarg.size(); + if(size == 32) { + std::string rawhash = base32::decode(xtarg); + if(rawhash.size() == 20) { + infoHash.swap(rawhash); + } + } else if(size == 40) { + std::string rawhash = util::fromHex(xtarg); + if(!rawhash.empty()) { + infoHash.swap(rawhash); + } + } + } } - std::string infoHash = xts[0].s().substr(9); - if(infoHash.size() == 32) { - std::string rawhash = base32::decode(infoHash); - if(rawhash.size() != 20) { - throw DL_ABORT_EX("Invalid BitTorrent Info Hash."); - } - infoHash = rawhash; - } else if(infoHash.size() == 40) { - std::string rawhash = util::fromHex(infoHash); - if(rawhash.empty()) { - throw DL_ABORT_EX("Invalid BitTorrent Info Hash."); - } - infoHash = rawhash; - } else { - throw DL_ABORT_EX("Invalid BitTorrent Info Hash."); + if(infoHash.empty()) { + throw DL_ABORT_EX("Bad BitTorrent Magnet URI. " + "No valid BitTorrent Info Hash found."); } BDE announceList = BDE::list(); if(r.containsKey("tr")) { diff --git a/test/BittorrentHelperTest.cc b/test/BittorrentHelperTest.cc index 7028c78e..087ee709 100644 --- a/test/BittorrentHelperTest.cc +++ b/test/BittorrentHelperTest.cc @@ -729,6 +729,12 @@ void BittorrentHelperTest::testParseMagnet() (std::string("[METADATA]248d0a1cd08284299de78d5c1ed359bb46717d8c"), attrs[bittorrent::NAME].s()); CPPUNIT_ASSERT(attrs[bittorrent::ANNOUNCE_LIST].size() == 0); + + magnet = "magnet:?xt=urn:sha1:7899bdb90a026c746f3cbc10839dd9b2a2a3e985&" + "xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c"; + attrs = bittorrent::parseMagnet(magnet); + CPPUNIT_ASSERT_EQUAL(std::string("248d0a1cd08284299de78d5c1ed359bb46717d8c"), + util::toHex(attrs[bittorrent::INFO_HASH].s())); } void BittorrentHelperTest::testParseMagnet_base32()