diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 39f6079d..0e293d7d 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -503,7 +503,7 @@ namespace torrents { if ((size_t)value < MIN_PIECE_LENGTH || (size_t)value > MAX_PIECE_LENGTH) { - LogPrint (eLogError, "Torrents: invalid piece length ", value); + LogPrint (eLogError, "Torrents: Invalid piece length ", value); value = 0; } m_PieceLength = value; @@ -517,7 +517,18 @@ namespace torrents m_Pieces.swap (tmp); } if (m_PieceLength > 0 && m_Length > 0) - m_Pieces.reserve (m_Length/m_PieceLength + 1); + { + auto d = lldiv (m_Length, m_PieceLength); + size_t numPieces = d.quot; + if (d.rem > 0) numPieces++; + if (numPieces <= MAX_NUM_TORRENT_PIECES) + m_Pieces.reserve (numPieces); + else + { + LogPrint (eLogError, "Torrents: Too many pieces ", numPieces); + m_Error = eTorrentErrorMalformedMetaInfo; + } + } else m_Error = eTorrentErrorMalformedMetaInfo; return ParsePieces (buf); @@ -2053,7 +2064,15 @@ namespace torrents else if (key == "metadata_size") { auto [s, l] = ExtractInteger (buf); - if (l) m_RemoteMetadataSize = s; + if (l) + { + if (s < 0 || (size_t)s > MAX_NUM_TORRENT_PIECES*SHA_DIGEST_LENGTH) + { + LogPrint (eLogError, "Torrents: Invalid metadata_size ", s); + s = 0; + } + m_RemoteMetadataSize = s; + } return l; } else if (key == "reqq") diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index 7637269e..0903642a 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -38,7 +38,8 @@ 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 size_t MAX_NUM_TORRENT_PIECES = 1024*1024; // 1M + constexpr size_t MAX_TORRENT_LENGTH = MAX_PIECE_LENGTH*MAX_NUM_TORRENT_PIECES; // 64T 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;