From ec452bfffbf092cba858e07862c24d74c8c13347 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Sep 2026 20:30:00 -0400 Subject: [PATCH] numeric torrent error code. Limit torrent length by 1Pb --- libi2pd_client/Torrents.cpp | 16 +++++++++++++--- libi2pd_client/Torrents.h | 20 ++++++++++++++++++-- libi2pd_client/TorrentsRPC.cpp | 4 ++-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 9af1aba2..0fd548f3 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -424,7 +424,8 @@ namespace torrents Torrent::Torrent (): m_Length (0), m_PieceLength (0), m_IsComplete (false), m_IsStopped (false), m_IsSingleFile (true), - m_Uploaded (0), m_Downloaded (0), m_NextUpdateStatusTime (0), m_NextReconnectTime (0) + m_Uploaded (0), m_Downloaded (0), m_NextUpdateStatusTime (0), m_NextReconnectTime (0), + m_Error (eTorrentErrorNoError) { } @@ -470,7 +471,15 @@ namespace torrents if (key == "length") { auto [value, l] = ExtractInteger (buf); - if (l) m_Length = value; + if (l) + { + if (value < 0 || (size_t)value > MAX_TORRENT_LENGTH) + { + LogPrint (eLogError, "Torrents: Invalid length ", value); + value = 0; + } + m_Length = value; + } return l; } else if (key == "name") @@ -510,7 +519,7 @@ namespace torrents if (m_PieceLength > 0 && m_Length > 0) m_Pieces.reserve (m_Length/m_PieceLength + 1); else - m_Error = "Malformed metaInfo"; + m_Error = eTorrentErrorMalformedMetaInfo; return ParsePieces (buf); } else if (key == "files") @@ -525,6 +534,7 @@ namespace torrents memcpy (m_Info.data (), (const uint8_t *)buf.data (), len); // calculate info hash SHA1 (m_Info.data (), len, m_InfoHash.data ()); + if (m_Error) m_IsStopped = true; return len; } diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index ca7d4812..7637269e 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -38,6 +38,7 @@ namespace torrents constexpr size_t REQUEST_BLOCK_SIZE = 16384; constexpr size_t MIN_PIECE_LENGTH = 16*1024; // 16K constexpr size_t MAX_PIECE_LENGTH = 64*1024*1024; // 64M + constexpr size_t MAX_TORRENT_LENGTH = 1024LL*1024*1024*1024*1024; // 1P constexpr uint16_t TORRENT_PORT = 6881; // not used by required by protocol constexpr int MIN_TRACKER_REQUESTS_INTERVAL = 15000; // in milliseconds constexpr size_t PEER_CONNECTION_RECEIVE_BUFFER_SIZE = 65535; @@ -188,6 +189,18 @@ namespace torrents eTorrentStatusSeeding = 6 }; + enum TorrentError + { + eTorrentErrorNoError = 0, + eTorrentErrorMalformedMetaInfo = 1, + eNumTorrentErrors + }; + + constexpr std::array TorrentErrorStr + { + "", "Malformed metaInfo" + }; + using RequestedBlock = std::tuple; // (index, offset, len) class PeerConnection; class Torrent final @@ -221,7 +234,9 @@ namespace torrents std::string_view GetName () const { return m_Name; } void SetName (std::string_view name) { m_Name = AdjustName (name); } bool IsValid () const { return !m_Name.empty () && m_PieceLength && (m_Length || !m_Files.empty ()); } - std::string_view GetError () const { return m_Error; } + TorrentError GetError () const { return m_Error; } + std::string_view GetErrorStr () const { return TorrentErrorStr[m_Error]; } + void SetError (TorrentError error) { m_Error = error; } const std::filesystem::path& GetFullPath () const { return m_FullPath; } void SetFullPath (const std::filesystem::path& fullPath) { m_FullPath = fullPath; } const std::list >& GetFiles () const { return m_Files; } @@ -288,7 +303,7 @@ namespace torrents private: - std::string m_Name, m_Announce, m_Error; + std::string m_Name, m_Announce; std::filesystem::path m_FullPath; size_t m_Length, m_PieceLength; std::vector m_Info; // for BEP9 @@ -300,6 +315,7 @@ namespace torrents std::list > m_Files; size_t m_Uploaded, m_Downloaded; uint64_t m_NextUpdateStatusTime, m_NextReconnectTime; // in monotonic seconds + TorrentError m_Error; }; class TorrentsTunnel; diff --git a/libi2pd_client/TorrentsRPC.cpp b/libi2pd_client/TorrentsRPC.cpp index 01179593..ab7373ec 100644 --- a/libi2pd_client/TorrentsRPC.cpp +++ b/libi2pd_client/TorrentsRPC.cpp @@ -355,8 +355,8 @@ namespace torrents return priorities; } }, - { "error", [](std::shared_ptr torrent) { return boost::json::value(torrent->GetError ().empty () ? 0 : 3); } }, // no error or local error - { "errorString", [](std::shared_ptr torrent) { return boost::json::value(torrent->GetError ()); } }, + { "error", [](std::shared_ptr torrent) { return boost::json::value(torrent->GetError () ? 3 : 0); } }, // local error or no error + { "errorString", [](std::shared_ptr torrent) { return boost::json::value(torrent->GetErrorStr ()); } }, { "eta", [](std::shared_ptr torrent) { auto downloadRate = torrent->GetDownloadRate ();