fixed crash when add_torrent was fed with invalid resume data
This commit is contained in:
@@ -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; }
|
||||||
|
@@ -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();
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user