diff --git a/src/magnet_uri.cpp b/src/magnet_uri.cpp index 84d55b3aa..80e212e98 100644 --- a/src/magnet_uri.cpp +++ b/src/magnet_uri.cpp @@ -216,12 +216,18 @@ namespace libtorrent { } string_view btih = url_has_argument(uri, "xt"); + std::string unescaped_btih; if (btih.empty()) { ec = errors::missing_info_hash_in_uri; return; } - + if (btih.find('%') != string_view::npos) + { + unescaped_btih = unescape_string(btih, ec); + if (ec) return; + btih = unescaped_btih; + } if (btih.substr(0, 9) != "urn:btih:") { ec = errors::missing_info_hash_in_uri; diff --git a/test/test_magnet.cpp b/test/test_magnet.cpp index 687b4878c..c4bf69191 100644 --- a/test/test_magnet.cpp +++ b/test/test_magnet.cpp @@ -224,6 +224,32 @@ TORRENT_TEST(magnet) p2 = s->abort(); } +TORRENT_TEST(parse_escaped_hash_parameter) +{ + error_code ec; + add_torrent_params p; + parse_magnet_uri("magnet:?xt=urn%3Abtih%3Acdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", p, ec); + TEST_CHECK(!ec); + TEST_EQUAL(aux::to_hex(p.info_hash), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"); +} + +TORRENT_TEST(parse_escaped_hash_parameter_in_hex) +{ + error_code ec; + add_torrent_params p; + parse_magnet_uri("magnet:?xt=urn:btih:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc%64", p, ec); + TEST_CHECK(!ec); + TEST_EQUAL(aux::to_hex(p.info_hash), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"); +} + +TORRENT_TEST(parse_invalid_escaped_hash_parameter) +{ + error_code ec; + add_torrent_params p; + parse_magnet_uri("magnet:?xt=urn%%3A", p, ec); + TEST_EQUAL(ec, error_code(errors::invalid_escaped_string)); +} + TORRENT_TEST(parse_missing_hash) { // parse_magnet_uri