fix bounds checking in parsing of gzip header

This commit is contained in:
arvidn 2017-10-01 01:24:07 +02:00 committed by Arvid Norberg
parent 9d276ada8a
commit 17d78d3b8f
3 changed files with 24 additions and 8 deletions

View File

@ -112,13 +112,13 @@ namespace libtorrent {
namespace {
// returns -1 if gzip header is invalid or the header size in bytes
int gzip_header(span<char const> const buf)
int gzip_header(span<char const> const in)
{
// The zip header cannot be shorter than 10 bytes
if (buf.size() < 10) return -1;
if (in.size() < 10) return -1;
span<unsigned char const> buffer(
reinterpret_cast<const unsigned char*>(buf.data()), buf.size());
reinterpret_cast<const unsigned char*>(in.data()), in.size());
// gzip is defined in https://tools.ietf.org/html/rfc1952
@ -150,22 +150,22 @@ namespace {
if (flags & FNAME)
{
if (buf.empty()) return -1;
if (buffer.empty()) return -1;
while (buffer[0] != 0)
{
buffer = buffer.subspan(1);
if (buf.empty()) return -1;
if (buffer.empty()) return -1;
}
buffer = buffer.subspan(1);
}
if (flags & FCOMMENT)
{
if (buf.empty()) return -1;
if (buffer.empty()) return -1;
while (buffer[0] != 0)
{
buffer = buffer.subspan(1);
if (buf.empty()) return -1;
if (buffer.empty()) return -1;
}
buffer = buffer.subspan(1);
}
@ -176,7 +176,7 @@ namespace {
buffer = buffer.subspan(2);
}
return static_cast<int>(buf.size() - buffer.size());
return static_cast<int>(in.size() - buffer.size());
}
} // anonymous namespace

BIN
test/invalid1.gz Normal file

Binary file not shown.

View File

@ -74,6 +74,22 @@ TORRENT_TEST(corrupt)
TEST_CHECK(ec);
}
TORRENT_TEST(invalid1)
{
std::vector<char> zipped;
error_code ec;
load_file(combine_path("..", "invalid1.gz"), zipped, ec, 1000000);
if (ec) std::printf("failed to open file: (%d) %s\n", ec.value()
, ec.message().c_str());
TEST_CHECK(!ec);
std::vector<char> inflated;
inflate_gzip(zipped, inflated, 1000000, ec);
// we expect this to fail
TEST_CHECK(ec);
}
TORRENT_TEST(empty)
{
std::vector<char> empty;