mirror of https://github.com/aria2/aria2
2010-07-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed ChunkedDecoder. It does not read trailer and final CRLF. * src/ChunkedDecoder.cc * src/ChunkedDecoder.h * test/ChunkedDecoderTest.ccpull/1/head
parent
eecb81dc60
commit
20cea7f693
|
@ -1,3 +1,10 @@
|
||||||
|
2010-07-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
|
Fixed ChunkedDecoder. It does not read trailer and final CRLF.
|
||||||
|
* src/ChunkedDecoder.cc
|
||||||
|
* src/ChunkedDecoder.h
|
||||||
|
* test/ChunkedDecoderTest.cc
|
||||||
|
|
||||||
2010-07-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
2010-07-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Removed unusable typedefs
|
Removed unusable typedefs
|
||||||
|
|
|
@ -64,6 +64,27 @@ static bool readChunkSize(uint64_t& chunkSize, std::string& in)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool readTrailer(std::string& in)
|
||||||
|
{
|
||||||
|
std::string::size_type crlfPos = in.find(A2STR::CRLF);
|
||||||
|
if(crlfPos == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(crlfPos == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if(in.size() > crlfPos+3) {
|
||||||
|
if(in[crlfPos+2] == '\r' && in[crlfPos+3] == '\n') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw DL_ABORT_EX("No CRLF at the end of chunk stream.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool readData(std::string& out, uint64_t& chunkSize, std::string& in)
|
static bool readData(std::string& out, uint64_t& chunkSize, std::string& in)
|
||||||
{
|
{
|
||||||
uint64_t readlen = std::min(chunkSize, static_cast<uint64_t>(in.size()));
|
uint64_t readlen = std::min(chunkSize, static_cast<uint64_t>(in.size()));
|
||||||
|
@ -91,8 +112,7 @@ std::string ChunkedDecoder::decode(const unsigned char* inbuf, size_t inlen)
|
||||||
if(state_ == READ_SIZE) {
|
if(state_ == READ_SIZE) {
|
||||||
if(readChunkSize(chunkSize_, buf_)) {
|
if(readChunkSize(chunkSize_, buf_)) {
|
||||||
if(chunkSize_ == 0) {
|
if(chunkSize_ == 0) {
|
||||||
state_ = STREAM_END;
|
state_ = READ_TRAILER;
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
state_ = READ_DATA;
|
state_ = READ_DATA;
|
||||||
}
|
}
|
||||||
|
@ -105,6 +125,13 @@ std::string ChunkedDecoder::decode(const unsigned char* inbuf, size_t inlen)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if(state_ == READ_TRAILER) {
|
||||||
|
if(readTrailer(buf_)) {
|
||||||
|
state_ = STREAM_END;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return outbuf;
|
return outbuf;
|
||||||
|
|
|
@ -44,6 +44,7 @@ private:
|
||||||
enum STATE {
|
enum STATE {
|
||||||
READ_SIZE,
|
READ_SIZE,
|
||||||
READ_DATA,
|
READ_DATA,
|
||||||
|
READ_TRAILER,
|
||||||
STREAM_END
|
STREAM_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ class ChunkedDecoderTest:public CppUnit::TestFixture {
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(ChunkedDecoderTest);
|
CPPUNIT_TEST_SUITE(ChunkedDecoderTest);
|
||||||
CPPUNIT_TEST(testDecode);
|
CPPUNIT_TEST(testDecode);
|
||||||
|
CPPUNIT_TEST(testDecode_withoutTrailer);
|
||||||
CPPUNIT_TEST(testDecode_tooLargeChunkSize);
|
CPPUNIT_TEST(testDecode_tooLargeChunkSize);
|
||||||
CPPUNIT_TEST(testDecode_chunkSizeMismatch);
|
CPPUNIT_TEST(testDecode_chunkSizeMismatch);
|
||||||
CPPUNIT_TEST(testGetName);
|
CPPUNIT_TEST(testGetName);
|
||||||
|
@ -17,6 +18,7 @@ public:
|
||||||
void setUp() {}
|
void setUp() {}
|
||||||
|
|
||||||
void testDecode();
|
void testDecode();
|
||||||
|
void testDecode_withoutTrailer();
|
||||||
void testDecode_tooLargeChunkSize();
|
void testDecode_tooLargeChunkSize();
|
||||||
void testDecode_chunkSizeMismatch();
|
void testDecode_chunkSizeMismatch();
|
||||||
void testGetName();
|
void testGetName();
|
||||||
|
@ -102,12 +104,35 @@ void ChunkedDecoderTest::testDecode()
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string(),
|
CPPUNIT_ASSERT_EQUAL(std::string(),
|
||||||
decoder.decode(msg.c_str(), msg.size()));
|
decoder.decode(msg.c_str(), msg.size()));
|
||||||
}
|
}
|
||||||
|
// feed trailer
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT_EQUAL
|
||||||
|
(std::string(),
|
||||||
|
decoder.decode
|
||||||
|
(reinterpret_cast<const unsigned char*>("trailer\r\n"), 9));
|
||||||
|
}
|
||||||
|
// feed final CRLF
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT_EQUAL
|
||||||
|
(std::string(),
|
||||||
|
decoder.decode(reinterpret_cast<const unsigned char*>("\r\n"), 2));
|
||||||
|
}
|
||||||
// input is over
|
// input is over
|
||||||
CPPUNIT_ASSERT(decoder.finished());
|
CPPUNIT_ASSERT(decoder.finished());
|
||||||
|
|
||||||
decoder.release();
|
decoder.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkedDecoderTest::testDecode_withoutTrailer()
|
||||||
|
{
|
||||||
|
ChunkedDecoder decoder;
|
||||||
|
decoder.init();
|
||||||
|
CPPUNIT_ASSERT_EQUAL
|
||||||
|
(std::string(),
|
||||||
|
decoder.decode(reinterpret_cast<const unsigned char*>("0\r\n\r\n"), 5));
|
||||||
|
CPPUNIT_ASSERT(decoder.finished());
|
||||||
|
}
|
||||||
|
|
||||||
void ChunkedDecoderTest::testDecode_tooLargeChunkSize()
|
void ChunkedDecoderTest::testDecode_tooLargeChunkSize()
|
||||||
{
|
{
|
||||||
// chunkSize should be under 2^64-1
|
// chunkSize should be under 2^64-1
|
||||||
|
|
Loading…
Reference in New Issue