diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 9c4bd751..9af1aba2 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -490,7 +490,15 @@ namespace torrents else if (key == "piece length") { auto [value, l] = ExtractInteger (buf); - if (l) m_PieceLength = value; + if (l) + { + if ((size_t)value < MIN_PIECE_LENGTH || (size_t)value > MAX_PIECE_LENGTH) + { + LogPrint (eLogError, "Torrents: invalid piece length ", value); + value = 0; + } + m_PieceLength = value; + } return l; } else if (key == "pieces") @@ -501,6 +509,8 @@ namespace torrents } if (m_PieceLength > 0 && m_Length > 0) m_Pieces.reserve (m_Length/m_PieceLength + 1); + else + m_Error = "Malformed metaInfo"; return ParsePieces (buf); } else if (key == "files") diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index 538aa062..ca7d4812 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -36,6 +36,8 @@ namespace i2p 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 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; @@ -219,6 +221,7 @@ 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; } 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; } @@ -285,7 +288,7 @@ namespace torrents private: - std::string m_Name, m_Announce; + std::string m_Name, m_Announce, m_Error; std::filesystem::path m_FullPath; size_t m_Length, m_PieceLength; std::vector m_Info; // for BEP9 diff --git a/libi2pd_client/TorrentsRPC.cpp b/libi2pd_client/TorrentsRPC.cpp index 5853e8da..01179593 100644 --- a/libi2pd_client/TorrentsRPC.cpp +++ b/libi2pd_client/TorrentsRPC.cpp @@ -355,7 +355,8 @@ namespace torrents return priorities; } }, - { "error", [](std::shared_ptr torrent) { return boost::json::value(0); } }, // no error + { "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 ()); } }, { "eta", [](std::shared_ptr torrent) { auto downloadRate = torrent->GetDownloadRate ();