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>
|
||||
|
||||
Removed unusable typedefs
|
||||
|
|
|
@ -64,6 +64,27 @@ static bool readChunkSize(uint64_t& chunkSize, std::string& in)
|
|||
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)
|
||||
{
|
||||
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(readChunkSize(chunkSize_, buf_)) {
|
||||
if(chunkSize_ == 0) {
|
||||
state_ = STREAM_END;
|
||||
break;
|
||||
state_ = READ_TRAILER;
|
||||
} else {
|
||||
state_ = READ_DATA;
|
||||
}
|
||||
|
@ -105,6 +125,13 @@ std::string ChunkedDecoder::decode(const unsigned char* inbuf, size_t inlen)
|
|||
} else {
|
||||
break;
|
||||
}
|
||||
} else if(state_ == READ_TRAILER) {
|
||||
if(readTrailer(buf_)) {
|
||||
state_ = STREAM_END;
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return outbuf;
|
||||
|
|
|
@ -44,6 +44,7 @@ private:
|
|||
enum STATE {
|
||||
READ_SIZE,
|
||||
READ_DATA,
|
||||
READ_TRAILER,
|
||||
STREAM_END
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ class ChunkedDecoderTest:public CppUnit::TestFixture {
|
|||
|
||||
CPPUNIT_TEST_SUITE(ChunkedDecoderTest);
|
||||
CPPUNIT_TEST(testDecode);
|
||||
CPPUNIT_TEST(testDecode_withoutTrailer);
|
||||
CPPUNIT_TEST(testDecode_tooLargeChunkSize);
|
||||
CPPUNIT_TEST(testDecode_chunkSizeMismatch);
|
||||
CPPUNIT_TEST(testGetName);
|
||||
|
@ -17,6 +18,7 @@ public:
|
|||
void setUp() {}
|
||||
|
||||
void testDecode();
|
||||
void testDecode_withoutTrailer();
|
||||
void testDecode_tooLargeChunkSize();
|
||||
void testDecode_chunkSizeMismatch();
|
||||
void testGetName();
|
||||
|
@ -102,12 +104,35 @@ void ChunkedDecoderTest::testDecode()
|
|||
CPPUNIT_ASSERT_EQUAL(std::string(),
|
||||
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
|
||||
CPPUNIT_ASSERT(decoder.finished());
|
||||
|
||||
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()
|
||||
{
|
||||
// chunkSize should be under 2^64-1
|
||||
|
|
Loading…
Reference in New Issue