2009-12-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Check structure depth when decoding.
	* src/bencode.cc
	* src/bencode.h
	* test/BencodeTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-12-25 14:53:11 +00:00
parent 49bd2c1b92
commit 838fcbbecd
4 changed files with 47 additions and 10 deletions

View File

@ -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>
Documented tellStopped XML-RPC method in man page.

View File

@ -44,7 +44,7 @@ namespace aria2 {
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 = ':')
{
@ -96,7 +96,7 @@ static BDE decodeinteger(std::istream& ss)
return BDE(integer);
}
static BDE decodedict(std::istream& ss)
static BDE decodedict(std::istream& ss, size_t depth)
{
BDE dict = BDE::dict();
char c;
@ -106,14 +106,14 @@ static BDE decodedict(std::istream& ss)
} else {
ss.unget();
std::string key = decoderawstring(ss);
dict[key] = decodeiter(ss);
dict[key] = decodeiter(ss, depth);
}
}
throw DL_ABORT_EX("Bencode decoding failed:"
" 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();
char c;
@ -122,15 +122,23 @@ static BDE decodelist(std::istream& ss)
return list;
} else {
ss.unget();
list << decodeiter(ss);
list << decodeiter(ss, depth);
}
}
throw DL_ABORT_EX("Bencode decoding failed:"
" 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;
if(!ss.get(c)) {
throw DL_ABORT_EX("Bencode decoding failed:"
@ -138,9 +146,9 @@ static BDE decodeiter(std::istream& ss)
" 'd', 'l', 'i' or digit is expected.");
}
if(c == 'd') {
return decodedict(ss);
return decodedict(ss, depth+1);
} else if(c == 'l') {
return decodelist(ss);
return decodelist(ss, depth+1);
} else if(c == 'i') {
return decodeinteger(ss);
} else {
@ -151,7 +159,7 @@ static BDE decodeiter(std::istream& ss)
BDE decode(std::istream& in)
{
return decodeiter(in);
return decodeiter(in, 0);
}
BDE decode(const std::string& s)
@ -167,7 +175,7 @@ BDE decode(const std::string& s, size_t& end)
}
std::istringstream ss(s);
BDE bde = decodeiter(ss);
BDE bde = decodeiter(ss, 0);
end = ss.tellg();
return bde;
}

View File

@ -46,6 +46,8 @@ namespace aria2 {
namespace bencode {
const size_t MAX_STRUCTURE_DEPTH = 100;
BDE decode(std::istream& in);
// Decode the data in s.

View File

@ -10,12 +10,14 @@ class BencodeTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(BencodeTest);
CPPUNIT_TEST(testDecode);
CPPUNIT_TEST(testDecode_overflow);
CPPUNIT_TEST(testEncode);
CPPUNIT_TEST_SUITE_END();
private:
public:
void testDecode();
void testDecode_overflow();
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()
{
{