diff --git a/libtransmission/magnet-metainfo.cc b/libtransmission/magnet-metainfo.cc index ad5d3ebd6..1e83fb1b7 100644 --- a/libtransmission/magnet-metainfo.cc +++ b/libtransmission/magnet-metainfo.cc @@ -119,7 +119,7 @@ std::optional parseBase32Hash(std::string_view sv) std::begin(sv), std::end(sv), [](unsigned char ch) - { return '0' <= ch && ch <= '0' + std::size(bitzi::Base32Lookup) && bitzi::Base32Lookup[ch - '0'] != 0xFF; })) + { return '0' <= ch && ch < '0' + std::size(bitzi::Base32Lookup) && bitzi::Base32Lookup[ch - '0'] != 0xFF; })) { return {}; } diff --git a/tests/libtransmission/magnet-metainfo-test.cc b/tests/libtransmission/magnet-metainfo-test.cc index fec921077..e426524eb 100644 --- a/tests/libtransmission/magnet-metainfo-test.cc +++ b/tests/libtransmission/magnet-metainfo-test.cc @@ -3,14 +3,16 @@ // or any future license endorsed by Mnemosyne LLC. // License text can be found in the licenses/ folder. -#include "transmission.h" -#include "magnet-metainfo.h" -#include "utils.h" +#include +#include #include "gtest/gtest.h" -#include -#include +#include "transmission.h" + +#include "crypto-utils.h" +#include "magnet-metainfo.h" +#include "utils.h" using namespace std::literals; @@ -89,3 +91,31 @@ TEST(MagnetMetainfo, magnetParse) EXPECT_EQ(ExpectedHash, mm.infoHash()); } } + +TEST(WebUtilsTest, parseMagnetFuzzRegressions) +{ + auto buf = std::vector{}; + + static auto constexpr Tests = std::array{ + "UICOl7RLjChs/QZZwNH4sSQwuH890UMHuoxoWBmMkr0=", + }; + + for (auto const& test : Tests) + { + auto mm = tr_magnet_metainfo{}; + mm.parseMagnet(tr_base64_decode(test)); + } +} + +TEST(WebUtilsTest, parseMagnetFuzz) +{ + auto buf = std::vector{}; + + for (size_t i = 0; i < 100000; ++i) + { + buf.resize(tr_rand_int(1024)); + tr_rand_buffer(std::data(buf), std::size(buf)); + auto mm = tr_magnet_metainfo{}; + EXPECT_FALSE(mm.parseMagnet({ std::data(buf), std::size(buf) })); + } +}