mirror of
https://github.com/transmission/transmission.git
synced 2026-02-14 23:19:34 +00:00
fix: fail if pieces length in info dict is not multiple of 20 (#8409)
* fix: fail if `pieces` length in info dict is not multiple of 20 * fix(tests): replace potentially malicious test torrent for pieces length
This commit is contained in:
@@ -366,17 +366,16 @@ struct MetainfoHandler final : public tr::benc::BasicHandler<MaxBencDepth>
|
||||
}
|
||||
else if (pathIs(InfoKey, PiecesKey))
|
||||
{
|
||||
if (std::size(value) % sizeof(tr_sha1_digest_t) == 0)
|
||||
static auto constexpr Sha1Len = std::tuple_size_v<tr_sha1_digest_t>;
|
||||
auto const len = std::size(value);
|
||||
if (len % Sha1Len != 0U)
|
||||
{
|
||||
auto const n = std::size(value) / sizeof(tr_sha1_digest_t);
|
||||
tm_.pieces_.resize(n);
|
||||
std::copy_n(std::data(value), std::size(value), reinterpret_cast<char*>(std::data(tm_.pieces_)));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.error.set(EINVAL, fmt::format("invalid piece size: {}", std::size(value)));
|
||||
unhandled = true;
|
||||
context.error.set(EINVAL, fmt::format("invalid 'pieces' size: {}", len));
|
||||
return false;
|
||||
}
|
||||
|
||||
tm_.pieces_.resize(len / Sha1Len);
|
||||
std::copy_n(std::data(value), len, reinterpret_cast<char*>(std::data(tm_.pieces_)));
|
||||
}
|
||||
else if (pathStartsWith(PieceLayersKey))
|
||||
{
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
d8:announce28:https://example.com/announce8:checksum64:78d16df696e22610ab7c2e10a335a6b2543eaa8c10508a36b9760c69cdb3fb557:comment14:sample torrent10:created by13:uTorrent/204013:creation datei1317056433e8:encoding5:UTF-84:infod5:filesld6:lengthi8388608e4:pathl9:file1.txteed6:lengthi8388608e4:pathl9:file2.mkveed6:lengthi8388608e4:pathl9:file3.nfoeee4:name15:ThisIsMyTorrent12:piece lengthi4194304e6:pieces119:+ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª7:privatei1e6:source15:Example Trackeree
|
||||
@@ -207,10 +207,14 @@ TEST_F(TorrentMetainfoTest, GetRightStyleWebseedString)
|
||||
}
|
||||
|
||||
// Test for https://github.com/transmission/transmission/issues/3591
|
||||
TEST_F(TorrentMetainfoTest, parseBencOOBWrite)
|
||||
TEST_F(TorrentMetainfoTest, parseBencPiecesSize)
|
||||
{
|
||||
auto const src_filename = tr_pathbuf{ LIBTRANSMISSION_TEST_ASSETS_DIR, "/invalid-pieces-length.torrent"sv };
|
||||
auto error = tr_error{};
|
||||
auto tm = tr_torrent_metainfo{};
|
||||
EXPECT_FALSE(tm.parse_benc(tr_base64_decode("ZGg0OmluZm9kNjpwaWVjZXMzOkFpzQ==")));
|
||||
EXPECT_FALSE(tm.parse_torrent_file(src_filename, nullptr, &error));
|
||||
EXPECT_EQ(error.code(), EINVAL);
|
||||
EXPECT_EQ(error.message(), "invalid 'pieces' size: 119"sv);
|
||||
}
|
||||
|
||||
} // namespace tr::test
|
||||
|
||||
Reference in New Issue
Block a user