fixed crash when add_torrent was fed with invalid resume data

This commit is contained in:
Arvid Norberg
2008-09-21 02:08:04 +00:00
parent 0338510b9b
commit 8ffc345308
3 changed files with 34 additions and 34 deletions

View File

@@ -130,8 +130,6 @@ namespace libtorrent
~torrent(); ~torrent();
void parse_resume_data(std::vector<char>* resume_data);
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
sha1_hash const& obfuscated_hash() const sha1_hash const& obfuscated_hash() const
{ return m_obfuscated_hash; } { return m_obfuscated_hash; }

View File

@@ -47,7 +47,11 @@ namespace
namespace libtorrent namespace libtorrent
{ {
int fail_bdecode() { return -1; } int fail_bdecode(lazy_entry& ret)
{
ret = lazy_entry();
return -1;
}
// fills in 'val' with what the string between start and the // fills in 'val' with what the string between start and the
// first occurance of the delimiter is interpreted as an int. // first occurance of the delimiter is interpreted as an int.
@@ -58,7 +62,7 @@ namespace libtorrent
while (start < end && *start != delimiter) while (start < end && *start != delimiter)
{ {
using namespace std; using namespace std;
if (!isdigit(*start)) { fail_bdecode(); return 0; } if (!isdigit(*start)) { return 0; }
val *= 10; val *= 10;
val += *start - '0'; val += *start - '0';
++start; ++start;
@@ -87,11 +91,11 @@ namespace libtorrent
lazy_entry* top = stack.back(); lazy_entry* top = stack.back();
if (int(stack.size()) > depth_limit) return fail_bdecode(); if (int(stack.size()) > depth_limit) return fail_bdecode(ret);
if (start >= end) return fail_bdecode(); if (start >= end) return fail_bdecode(ret);
char t = *start; char t = *start;
++start; ++start;
if (start >= end && t != 'e') return fail_bdecode(); if (start >= end && t != 'e') return fail_bdecode(ret);
switch (top->type()) switch (top->type())
{ {
@@ -105,12 +109,12 @@ namespace libtorrent
} }
boost::int64_t len = t - '0'; boost::int64_t len = t - '0';
start = parse_int(start, end, ':', len); start = parse_int(start, end, ':', len);
if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode(); if (start == 0 || start + len + 3 > end || *start != ':') return fail_bdecode(ret);
++start; ++start;
if (start == end) fail_bdecode(); if (start == end) fail_bdecode(ret);
lazy_entry* ent = top->dict_append(start); lazy_entry* ent = top->dict_append(start);
start += len; start += len;
if (start >= end) fail_bdecode(); if (start >= end) fail_bdecode(ret);
stack.push_back(ent); stack.push_back(ent);
t = *start; t = *start;
++start; ++start;
@@ -145,7 +149,7 @@ namespace libtorrent
char const* int_start = start; char const* int_start = start;
start = find_char(start, end, 'e'); start = find_char(start, end, 'e');
top->construct_int(int_start, start - int_start); top->construct_int(int_start, start - int_start);
if (start == end) return fail_bdecode(); if (start == end) return fail_bdecode(ret);
TORRENT_ASSERT(*start == 'e'); TORRENT_ASSERT(*start == 'e');
++start; ++start;
stack.pop_back(); stack.pop_back();
@@ -154,11 +158,11 @@ namespace libtorrent
default: default:
{ {
using namespace std; using namespace std;
if (!isdigit(t)) return fail_bdecode(); if (!isdigit(t)) return fail_bdecode(ret);
boost::int64_t len = t - '0'; boost::int64_t len = t - '0';
start = parse_int(start, end, ':', len); start = parse_int(start, end, ':', len);
if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode(); if (start == 0 || start + len + 1 > end || *start != ':') return fail_bdecode(ret);
++start; ++start;
top->construct_string(start, int(len)); top->construct_string(start, int(len));
stack.pop_back(); stack.pop_back();

View File

@@ -205,7 +205,7 @@ namespace libtorrent
, m_start_sent(false) , m_start_sent(false)
, m_complete_sent(false) , m_complete_sent(false)
{ {
parse_resume_data(resume_data); if (resume_data) m_resume_data.swap(*resume_data);
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
hasher h; hasher h;
@@ -286,7 +286,7 @@ namespace libtorrent
, m_start_sent(false) , m_start_sent(false)
, m_complete_sent(false) , m_complete_sent(false)
{ {
parse_resume_data(resume_data); if (resume_data) m_resume_data.swap(*resume_data);
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
hasher h; hasher h;
@@ -309,10 +309,10 @@ namespace libtorrent
} }
} }
void torrent::parse_resume_data(std::vector<char>* resume_data) void torrent::start()
{
if (!m_resume_data.empty())
{ {
if (!resume_data) return;
m_resume_data.swap(*resume_data);
if (lazy_bdecode(&m_resume_data[0], &m_resume_data[0] if (lazy_bdecode(&m_resume_data[0], &m_resume_data[0]
+ m_resume_data.size(), m_resume_entry) != 0) + m_resume_data.size(), m_resume_entry) != 0)
{ {
@@ -328,8 +328,6 @@ namespace libtorrent
} }
} }
void torrent::start()
{
// we need to start announcing since we don't have any // we need to start announcing since we don't have any
// metadata. To receive peers to ask for it. // metadata. To receive peers to ask for it.
if (m_torrent_file->is_valid()) init(); if (m_torrent_file->is_valid()) init();