mirror of https://github.com/aria2/aria2
2009-12-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Check structure depth when decoding. * src/bencode.cc * src/bencode.h * test/BencodeTest.ccpull/1/head
parent
49bd2c1b92
commit
838fcbbecd
|
@ -1,3 +1,10 @@
|
||||||
|
2009-12-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Check structure depth when decoding.
|
||||||
|
* src/bencode.cc
|
||||||
|
* src/bencode.h
|
||||||
|
* test/BencodeTest.cc
|
||||||
|
|
||||||
2009-12-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2009-12-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Documented tellStopped XML-RPC method in man page.
|
Documented tellStopped XML-RPC method in man page.
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace aria2 {
|
||||||
|
|
||||||
namespace bencode {
|
namespace bencode {
|
||||||
|
|
||||||
static BDE decodeiter(std::istream& ss);
|
static BDE decodeiter(std::istream& ss, size_t depth);
|
||||||
|
|
||||||
static void checkdelim(std::istream& ss, const char delim = ':')
|
static void checkdelim(std::istream& ss, const char delim = ':')
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ static BDE decodeinteger(std::istream& ss)
|
||||||
return BDE(integer);
|
return BDE(integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BDE decodedict(std::istream& ss)
|
static BDE decodedict(std::istream& ss, size_t depth)
|
||||||
{
|
{
|
||||||
BDE dict = BDE::dict();
|
BDE dict = BDE::dict();
|
||||||
char c;
|
char c;
|
||||||
|
@ -106,14 +106,14 @@ static BDE decodedict(std::istream& ss)
|
||||||
} else {
|
} else {
|
||||||
ss.unget();
|
ss.unget();
|
||||||
std::string key = decoderawstring(ss);
|
std::string key = decoderawstring(ss);
|
||||||
dict[key] = decodeiter(ss);
|
dict[key] = decodeiter(ss, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw DL_ABORT_EX("Bencode decoding failed:"
|
throw DL_ABORT_EX("Bencode decoding failed:"
|
||||||
" Unexpected EOF in dict context. 'e' expected.");
|
" Unexpected EOF in dict context. 'e' expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static BDE decodelist(std::istream& ss)
|
static BDE decodelist(std::istream& ss, size_t depth)
|
||||||
{
|
{
|
||||||
BDE list = BDE::list();
|
BDE list = BDE::list();
|
||||||
char c;
|
char c;
|
||||||
|
@ -122,15 +122,23 @@ static BDE decodelist(std::istream& ss)
|
||||||
return list;
|
return list;
|
||||||
} else {
|
} else {
|
||||||
ss.unget();
|
ss.unget();
|
||||||
list << decodeiter(ss);
|
list << decodeiter(ss, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw DL_ABORT_EX("Bencode decoding failed:"
|
throw DL_ABORT_EX("Bencode decoding failed:"
|
||||||
" Unexpected EOF in list context. 'e' expected.");
|
" Unexpected EOF in list context. 'e' expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static BDE decodeiter(std::istream& ss)
|
static void checkDepth(size_t depth)
|
||||||
{
|
{
|
||||||
|
if(depth >= MAX_STRUCTURE_DEPTH) {
|
||||||
|
throw DL_ABORT_EX("Bencode decoding failed: Structure is too deep.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BDE decodeiter(std::istream& ss, size_t depth)
|
||||||
|
{
|
||||||
|
checkDepth(depth);
|
||||||
char c;
|
char c;
|
||||||
if(!ss.get(c)) {
|
if(!ss.get(c)) {
|
||||||
throw DL_ABORT_EX("Bencode decoding failed:"
|
throw DL_ABORT_EX("Bencode decoding failed:"
|
||||||
|
@ -138,9 +146,9 @@ static BDE decodeiter(std::istream& ss)
|
||||||
" 'd', 'l', 'i' or digit is expected.");
|
" 'd', 'l', 'i' or digit is expected.");
|
||||||
}
|
}
|
||||||
if(c == 'd') {
|
if(c == 'd') {
|
||||||
return decodedict(ss);
|
return decodedict(ss, depth+1);
|
||||||
} else if(c == 'l') {
|
} else if(c == 'l') {
|
||||||
return decodelist(ss);
|
return decodelist(ss, depth+1);
|
||||||
} else if(c == 'i') {
|
} else if(c == 'i') {
|
||||||
return decodeinteger(ss);
|
return decodeinteger(ss);
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,7 +159,7 @@ static BDE decodeiter(std::istream& ss)
|
||||||
|
|
||||||
BDE decode(std::istream& in)
|
BDE decode(std::istream& in)
|
||||||
{
|
{
|
||||||
return decodeiter(in);
|
return decodeiter(in, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BDE decode(const std::string& s)
|
BDE decode(const std::string& s)
|
||||||
|
@ -167,7 +175,7 @@ BDE decode(const std::string& s, size_t& end)
|
||||||
}
|
}
|
||||||
std::istringstream ss(s);
|
std::istringstream ss(s);
|
||||||
|
|
||||||
BDE bde = decodeiter(ss);
|
BDE bde = decodeiter(ss, 0);
|
||||||
end = ss.tellg();
|
end = ss.tellg();
|
||||||
return bde;
|
return bde;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace aria2 {
|
||||||
|
|
||||||
namespace bencode {
|
namespace bencode {
|
||||||
|
|
||||||
|
const size_t MAX_STRUCTURE_DEPTH = 100;
|
||||||
|
|
||||||
BDE decode(std::istream& in);
|
BDE decode(std::istream& in);
|
||||||
|
|
||||||
// Decode the data in s.
|
// Decode the data in s.
|
||||||
|
|
|
@ -10,12 +10,14 @@ class BencodeTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(BencodeTest);
|
CPPUNIT_TEST_SUITE(BencodeTest);
|
||||||
CPPUNIT_TEST(testDecode);
|
CPPUNIT_TEST(testDecode);
|
||||||
|
CPPUNIT_TEST(testDecode_overflow);
|
||||||
CPPUNIT_TEST(testEncode);
|
CPPUNIT_TEST(testEncode);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
private:
|
private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void testDecode();
|
void testDecode();
|
||||||
|
void testDecode_overflow();
|
||||||
void testEncode();
|
void testEncode();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,6 +157,24 @@ void BencodeTest::testDecode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BencodeTest::testDecode_overflow()
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
size_t depth = bencode::MAX_STRUCTURE_DEPTH+1;
|
||||||
|
for(size_t i = 0; i < depth; ++i) {
|
||||||
|
s += "l";
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < depth; ++i) {
|
||||||
|
s += "e";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bencode::decode(s);
|
||||||
|
CPPUNIT_FAIL("exception must be thrown.");
|
||||||
|
} catch(RecoverableException& e) {
|
||||||
|
// success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BencodeTest::testEncode()
|
void BencodeTest::testEncode()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue