port lazy_bdecode from upstream to 'fix bound-checking issue in bdecoder'

c821b9eb0e
This commit is contained in:
Miguel Freitas 2015-10-18 20:15:53 -02:00
parent 33a4e14941
commit cfa194b3f8

View File

@ -116,12 +116,16 @@ namespace libtorrent
{ {
char const* const orig_start = start; char const* const orig_start = start;
ret.clear(); ret.clear();
if (start == end) return 0;
std::vector<lazy_entry*> stack; std::vector<lazy_entry*> stack;
if (start == end) {
ec = errors::unexpected_eof;
return -1;
}
stack.push_back(&ret); stack.push_back(&ret);
while (start < end) while (start <= end)
{ {
if (stack.empty()) break; // done! if (stack.empty()) break; // done!
@ -145,12 +149,14 @@ namespace libtorrent
} }
if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_string); if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_string);
boost::int64_t len = t - '0'; boost::int64_t len = t - '0';
error_code e; error_code e = errors::no_error;
start = parse_int(start, end, ':', len, e); start = parse_int(start, end, ':', len, e);
if (e) if (e)
TORRENT_FAIL_BDECODE(e); TORRENT_FAIL_BDECODE(e);
if (start + len + 1 > end) // remaining buffer size excluding ':'
const ptrdiff_t buff_size = end - start - 1;
if (len > buff_size)
TORRENT_FAIL_BDECODE(errors::unexpected_eof); TORRENT_FAIL_BDECODE(errors::unexpected_eof);
if (len < 0) if (len < 0)
@ -180,7 +186,10 @@ namespace libtorrent
stack.push_back(ent); stack.push_back(ent);
break; break;
} }
default: break; case lazy_entry::int_t:
case lazy_entry::string_t:
case lazy_entry::none_t:
break;
} }
--item_limit; --item_limit;
@ -191,10 +200,10 @@ namespace libtorrent
{ {
case 'd': case 'd':
top->construct_dict(start - 1); top->construct_dict(start - 1);
continue; break;
case 'l': case 'l':
top->construct_list(start - 1); top->construct_list(start - 1);
continue; break;
case 'i': case 'i':
{ {
char const* int_start = start; char const* int_start = start;
@ -204,7 +213,7 @@ namespace libtorrent
TORRENT_ASSERT(*start == 'e'); TORRENT_ASSERT(*start == 'e');
++start; ++start;
stack.pop_back(); stack.pop_back();
continue; break;
} }
default: default:
{ {
@ -212,23 +221,26 @@ namespace libtorrent
TORRENT_FAIL_BDECODE(errors::expected_value); TORRENT_FAIL_BDECODE(errors::expected_value);
boost::int64_t len = t - '0'; boost::int64_t len = t - '0';
error_code e; error_code e = errors::no_error;
start = parse_int(start, end, ':', len, e); start = parse_int(start, end, ':', len, e);
if (e) if (e)
TORRENT_FAIL_BDECODE(e); TORRENT_FAIL_BDECODE(e);
if (start + len + 1 > end)
// remaining buffer size excluding ':'
const ptrdiff_t buff_size = end - start - 1;
if (len > buff_size)
TORRENT_FAIL_BDECODE(errors::unexpected_eof); TORRENT_FAIL_BDECODE(errors::unexpected_eof);
if (len < 0) if (len < 0)
TORRENT_FAIL_BDECODE(errors::overflow); TORRENT_FAIL_BDECODE(errors::overflow);
++start; ++start;
if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
top->construct_string(start, int(len)); top->construct_string(start, int(len));
stack.pop_back();
start += len; start += len;
continue; stack.pop_back();
break;
} }
} }
return 0;
} }
return 0; return 0;
} }