From 211e3fc98571f3b55d17b1ff38facdc02762e3ad Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 1 Mar 2023 13:10:20 -0600 Subject: [PATCH] fix: always add `announce` key even when including announce-list (#5106) --- libtransmission/makemeta.cc | 6 ++- tests/libtransmission/makemeta-test.cc | 75 +++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/libtransmission/makemeta.cc b/libtransmission/makemeta.cc index 4c6c029f6..108b78f1a 100644 --- a/libtransmission/makemeta.cc +++ b/libtransmission/makemeta.cc @@ -291,8 +291,12 @@ std::string tr_metainfo_builder::benc(tr_error** error) const auto top = tr_variant{}; tr_variantInitDict(&top, 8); - // add the announce-list trackers + // add the announce URLs if (!std::empty(announceList())) + { + tr_variantDictAddStrView(&top, TR_KEY_announce, announceList().at(0).announce.sv()); + } + if (std::size(announceList()) > 1U) { auto* const announce_list = tr_variantDictAddList(&top, TR_KEY_announce_list, 0); tr_variant* tier_list = nullptr; diff --git a/tests/libtransmission/makemeta-test.cc b/tests/libtransmission/makemeta-test.cc index 96c50112b..af4c95768 100644 --- a/tests/libtransmission/makemeta-test.cc +++ b/tests/libtransmission/makemeta-test.cc @@ -216,6 +216,69 @@ TEST_F(MakemetaTest, singleFile) testBuilder(builder); } +TEST_F(MakemetaTest, announceSingleTracker) +{ + auto const files = makeRandomFiles(sandboxDir(), 1); + auto const [filename, payload] = files.front(); + auto builder = tr_metainfo_builder{ filename }; + + // add a tracker + static auto constexpr SingleAnnounce = "udp://tracker.openbittorrent.com:80"sv; + auto trackers = tr_announce_list{}; + trackers.add(SingleAnnounce, trackers.nextTier()); + builder.setAnnounceList(std::move(trackers)); + + // generate the torrent and parse it as a variant + EXPECT_EQ(nullptr, builder.makeChecksums().get()); + auto top = tr_variant{}; + auto const benc = builder.benc(); + EXPECT_TRUE(tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, benc)); + + // confirm there's an "announce" entry + auto single_announce = std::string_view{}; + EXPECT_TRUE(tr_variantDictFindStrView(&top, TR_KEY_announce, &single_announce)); + EXPECT_EQ(SingleAnnounce, single_announce); + + // confirm there's not an "announce-list" entry + EXPECT_EQ(nullptr, tr_variantDictFind(&top, TR_KEY_announce_list)); + + tr_variantClear(&top); +} + +TEST_F(MakemetaTest, announceMultiTracker) +{ + auto const files = makeRandomFiles(sandboxDir(), 1); + auto const [filename, payload] = files.front(); + auto builder = tr_metainfo_builder{ filename }; + + // add the trackers + auto trackers = tr_announce_list{}; + for (auto const& url : { "udp://tracker.openbittorrent.com:80"sv, "udp://tracker.publicbt.com:80"sv }) + { + trackers.add(url, trackers.nextTier()); + } + builder.setAnnounceList(std::move(trackers)); + + // generate the torrent and parse it as a variant + EXPECT_EQ(nullptr, builder.makeChecksums().get()); + auto top = tr_variant{}; + auto const benc = builder.benc(); + EXPECT_TRUE(tr_variantFromBuf(&top, TR_VARIANT_PARSE_BENC | TR_VARIANT_PARSE_INPLACE, benc)); + + // confirm there's an "announce" entry + auto single_announce = std::string_view{}; + EXPECT_TRUE(tr_variantDictFindStrView(&top, TR_KEY_announce, &single_announce)); + EXPECT_EQ(builder.announceList().at(0).announce.sv(), single_announce); + + // confirm there's an "announce-list" entry + tr_variant* announce_list_variant = nullptr; + EXPECT_TRUE(tr_variantDictFindList(&top, TR_KEY_announce_list, &announce_list_variant)); + EXPECT_NE(nullptr, announce_list_variant); + EXPECT_EQ(std::size(builder.announceList()), tr_variantListSize(announce_list_variant)); + + tr_variantClear(&top); +} + TEST_F(MakemetaTest, privateAndSourceHasDifferentInfoHash) { auto const files = makeRandomFiles(sandboxDir(), 1); @@ -224,16 +287,16 @@ TEST_F(MakemetaTest, privateAndSourceHasDifferentInfoHash) auto trackers = tr_announce_list{}; trackers.add("udp://tracker.openbittorrent.com:80"sv, trackers.nextTier()); builder.setAnnounceList(std::move(trackers)); - auto baseMetainfo = testBuilder(builder); + auto base_metainfo = testBuilder(builder); builder.setPrivate(true); - auto privateMetainfo = testBuilder(builder); - EXPECT_NE(baseMetainfo.infoHash(), privateMetainfo.infoHash()); + auto private_metainfo = testBuilder(builder); + EXPECT_NE(base_metainfo.infoHash(), private_metainfo.infoHash()); builder.setSource("FOO"); - auto privateSourceMetainfo = testBuilder(builder); - EXPECT_NE(baseMetainfo.infoHash(), privateSourceMetainfo.infoHash()); - EXPECT_NE(privateMetainfo.infoHash(), privateSourceMetainfo.infoHash()); + auto private_source_metainfo = testBuilder(builder); + EXPECT_NE(base_metainfo.infoHash(), private_source_metainfo.infoHash()); + EXPECT_NE(private_metainfo.infoHash(), private_source_metainfo.infoHash()); } } // namespace libtransmission::test