Commit a38fa2aa authored by Dave Watson's avatar Dave Watson Committed by Alecs King

test failure conditions in LengthFieldBasedFrameDecoder

Summary: Moar unittests.

Test Plan:
unittests

Reviewed By: hans@fb.com

Subscribers: doug, fugalh, folly-diffs@, jsedgwick, yfeldblum, chalfant

FB internal diff: D1959161

Signature: t1:1959161:1429292487:b7d10be35c2cf1d0bc1b399f4f523392a138a217
parent 7d1d6185
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <folly/wangle/codec/FixedLengthFrameDecoder.h> #include <folly/wangle/codec/FixedLengthFrameDecoder.h>
#include <folly/wangle/codec/LineBasedFrameDecoder.h>
#include <folly/wangle/codec/LengthFieldBasedFrameDecoder.h> #include <folly/wangle/codec/LengthFieldBasedFrameDecoder.h>
#include <folly/wangle/codec/LengthFieldPrepender.h> #include <folly/wangle/codec/LengthFieldPrepender.h>
#include <folly/wangle/codec/LineBasedFrameDecoder.h>
using namespace folly; using namespace folly;
using namespace folly::wangle; using namespace folly::wangle;
...@@ -54,7 +54,7 @@ class BytesReflector ...@@ -54,7 +54,7 @@ class BytesReflector
} }
}; };
TEST(CodecTest, FixedLengthFrameDecoder) { TEST(FixedLengthFrameDecoder, FailWhenLengthFieldEndOffset) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -89,7 +89,7 @@ TEST(CodecTest, FixedLengthFrameDecoder) { ...@@ -89,7 +89,7 @@ TEST(CodecTest, FixedLengthFrameDecoder) {
EXPECT_EQ(called, 3); EXPECT_EQ(called, 3);
} }
TEST(CodecTest, LengthFieldFramePipeline) { TEST(LengthFieldFramePipeline, SimpleTest) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -110,7 +110,7 @@ TEST(CodecTest, LengthFieldFramePipeline) { ...@@ -110,7 +110,7 @@ TEST(CodecTest, LengthFieldFramePipeline) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFramePipelineLittleEndian) { TEST(LengthFieldFramePipeline, LittleEndian) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -131,7 +131,7 @@ TEST(CodecTest, LengthFieldFramePipelineLittleEndian) { ...@@ -131,7 +131,7 @@ TEST(CodecTest, LengthFieldFramePipelineLittleEndian) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderSimple) { TEST(LengthFieldFrameDecoder, Simple) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -162,7 +162,7 @@ TEST(CodecTest, LengthFieldFrameDecoderSimple) { ...@@ -162,7 +162,7 @@ TEST(CodecTest, LengthFieldFrameDecoderSimple) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderNoStrip) { TEST(LengthFieldFrameDecoder, NoStrip) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -193,7 +193,7 @@ TEST(CodecTest, LengthFieldFrameDecoderNoStrip) { ...@@ -193,7 +193,7 @@ TEST(CodecTest, LengthFieldFrameDecoderNoStrip) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderAdjustment) { TEST(LengthFieldFrameDecoder, Adjustment) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -224,7 +224,7 @@ TEST(CodecTest, LengthFieldFrameDecoderAdjustment) { ...@@ -224,7 +224,7 @@ TEST(CodecTest, LengthFieldFrameDecoderAdjustment) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderPreHeader) { TEST(LengthFieldFrameDecoder, PreHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -256,7 +256,7 @@ TEST(CodecTest, LengthFieldFrameDecoderPreHeader) { ...@@ -256,7 +256,7 @@ TEST(CodecTest, LengthFieldFrameDecoderPreHeader) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderPostHeader) { TEST(LengthFieldFrameDecoder, PostHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -288,7 +288,7 @@ TEST(CodecTest, LengthFieldFrameDecoderPostHeader) { ...@@ -288,7 +288,7 @@ TEST(CodecTest, LengthFieldFrameDecoderPostHeader) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeader) { TEST(LengthFieldFrameDecoderStrip, PrePostHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -321,7 +321,7 @@ TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeader) { ...@@ -321,7 +321,7 @@ TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeader) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeaderFrameInclHeader) { TEST(LengthFieldFrameDecoder, StripPrePostHeaderFrameInclHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -354,7 +354,86 @@ TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeaderFrameInclHeader) { ...@@ -354,7 +354,86 @@ TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeaderFrameInclHeader) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LineBasedFrameDecoder) { TEST(LengthFieldFrameDecoder, FailTestLengthFieldEndOffset) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
pipeline
.addBack(LengthFieldBasedFrameDecoder(4, 10, 4, -2, 4))
.addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
ASSERT_EQ(nullptr, buf);
called++;
}))
.finalize();
auto bufFrame = IOBuf::create(8);
bufFrame->append(8);
RWPrivateCursor c(bufFrame.get());
c.writeBE((uint32_t)0); // frame size
c.write((uint32_t)0); // crap
IOBufQueue q(IOBufQueue::cacheChainLength());
q.append(std::move(bufFrame));
pipeline.read(q);
EXPECT_EQ(called, 1);
}
TEST(LengthFieldFrameDecoder, FailTestLengthFieldFrameSize) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
pipeline
.addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 4))
.addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
ASSERT_EQ(nullptr, buf);
called++;
}))
.finalize();
auto bufFrame = IOBuf::create(16);
bufFrame->append(16);
RWPrivateCursor c(bufFrame.get());
c.writeBE((uint32_t)12); // frame size
c.write((uint32_t)0); // nothing
c.write((uint32_t)0); // nothing
c.write((uint32_t)0); // nothing
IOBufQueue q(IOBufQueue::cacheChainLength());
q.append(std::move(bufFrame));
pipeline.read(q);
EXPECT_EQ(called, 1);
}
TEST(LengthFieldFrameDecoder, FailTestLengthFieldInitialBytes) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
pipeline
.addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 10))
.addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
ASSERT_EQ(nullptr, buf);
called++;
}))
.finalize();
auto bufFrame = IOBuf::create(16);
bufFrame->append(16);
RWPrivateCursor c(bufFrame.get());
c.writeBE((uint32_t)4); // frame size
c.write((uint32_t)0); // nothing
c.write((uint32_t)0); // nothing
c.write((uint32_t)0); // nothing
IOBufQueue q(IOBufQueue::cacheChainLength());
q.append(std::move(bufFrame));
pipeline.read(q);
EXPECT_EQ(called, 1);
}
TEST(LineBasedFrameDecoder, Simple) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -405,7 +484,7 @@ TEST(CodecTest, LineBasedFrameDecoder) { ...@@ -405,7 +484,7 @@ TEST(CodecTest, LineBasedFrameDecoder) {
EXPECT_EQ(called, 2); EXPECT_EQ(called, 2);
} }
TEST(CodecTest, LineBasedFrameDecoderSaveDelimiter) { TEST(LineBasedFrameDecoder, SaveDelimiter) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -454,13 +533,14 @@ TEST(CodecTest, LineBasedFrameDecoderSaveDelimiter) { ...@@ -454,13 +533,14 @@ TEST(CodecTest, LineBasedFrameDecoderSaveDelimiter) {
EXPECT_EQ(called, 2); EXPECT_EQ(called, 2);
} }
TEST(CodecTest, LineBasedFrameDecoderFail) { TEST(LineBasedFrameDecoder, Fail) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
pipeline pipeline
.addBack(LineBasedFrameDecoder(10)) .addBack(LineBasedFrameDecoder(10))
.addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) { .addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
ASSERT_EQ(nullptr, buf);
called++; called++;
})) }))
.finalize(); .finalize();
...@@ -501,7 +581,7 @@ TEST(CodecTest, LineBasedFrameDecoderFail) { ...@@ -501,7 +581,7 @@ TEST(CodecTest, LineBasedFrameDecoderFail) {
EXPECT_EQ(called, 2); EXPECT_EQ(called, 2);
} }
TEST(CodecTest, LineBasedFrameDecoderNewLineOnly) { TEST(LineBasedFrameDecoder, NewLineOnly) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
...@@ -528,7 +608,7 @@ TEST(CodecTest, LineBasedFrameDecoderNewLineOnly) { ...@@ -528,7 +608,7 @@ TEST(CodecTest, LineBasedFrameDecoderNewLineOnly) {
EXPECT_EQ(called, 1); EXPECT_EQ(called, 1);
} }
TEST(CodecTest, LineBasedFrameDecoderCarriageNewLineOnly) { TEST(LineBasedFrameDecoder, CarriageNewLineOnly) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline; ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0; int called = 0;
......
...@@ -38,7 +38,7 @@ LengthFieldBasedFrameDecoder::LengthFieldBasedFrameDecoder( ...@@ -38,7 +38,7 @@ LengthFieldBasedFrameDecoder::LengthFieldBasedFrameDecoder(
std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode( std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode(
Context* ctx, IOBufQueue& buf, size_t&) { Context* ctx, IOBufQueue& buf, size_t&) {
// discarding too long frame // discarding too long frame
if (buf.chainLength() <= lengthFieldEndOffset_) { if (buf.chainLength() < lengthFieldEndOffset_) {
return nullptr; return nullptr;
} }
...@@ -48,12 +48,18 @@ std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode( ...@@ -48,12 +48,18 @@ std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode(
frameLength += lengthAdjustment_ + lengthFieldEndOffset_; frameLength += lengthAdjustment_ + lengthFieldEndOffset_;
if (frameLength < lengthFieldEndOffset_) { if (frameLength < lengthFieldEndOffset_) {
throw std::runtime_error("Frame too small"); buf.trimStart(lengthFieldEndOffset_);
ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
"Frame too small"));
return nullptr;
} }
if (frameLength > maxFrameLength_) { if (frameLength > maxFrameLength_) {
throw std::runtime_error("Frame larger than " + buf.trimStart(frameLength);
folly::to<std::string>(maxFrameLength_)); ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
"Frame larger than " +
folly::to<std::string>(maxFrameLength_)));
return nullptr;
} }
if (buf.chainLength() < frameLength) { if (buf.chainLength() < frameLength) {
...@@ -61,7 +67,10 @@ std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode( ...@@ -61,7 +67,10 @@ std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode(
} }
if (initialBytesToStrip_ > frameLength) { if (initialBytesToStrip_ > frameLength) {
throw std::runtime_error("InitialBytesToSkip larger than frame"); buf.trimStart(frameLength);
ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
"InitialBytesToSkip larger than frame"));
return nullptr;
} }
buf.trimStart(initialBytesToStrip_); buf.trimStart(initialBytesToStrip_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment