| Index: net/spdy/spdy_framer_test.cc
|
| diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
|
| index 2fa77ed650c4d2c98c42df673784517c660f62af..ff6f3ea4026849a07bc6ceac6158346744190f63 100644
|
| --- a/net/spdy/spdy_framer_test.cc
|
| +++ b/net/spdy/spdy_framer_test.cc
|
| @@ -198,6 +198,12 @@ class SpdyFramerTestUtil {
|
| // Do nothing.
|
| }
|
|
|
| + virtual bool OnUnknownFrame(SpdyStreamId stream_id,
|
| + int frame_type) override {
|
| + LOG(FATAL);
|
| + return false;
|
| + }
|
| +
|
| char* ReleaseBuffer() {
|
| CHECK(finished_);
|
| return buffer_.release();
|
| @@ -249,6 +255,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| altsvc_count_(0),
|
| priority_count_(0),
|
| test_altsvc_ir_(0),
|
| + on_unknown_frame_result_(false),
|
| last_window_update_stream_(0),
|
| last_window_update_delta_(0),
|
| last_push_promise_stream_(0),
|
| @@ -438,6 +445,18 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| ++altsvc_count_;
|
| }
|
|
|
| + virtual void OnPriority(SpdyStreamId stream_id,
|
| + SpdyStreamId parent_stream_id,
|
| + uint8 weight,
|
| + bool exclusive) OVERRIDE {
|
| + ++priority_count_;
|
| + }
|
| +
|
| + virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override {
|
| + DLOG(INFO) << "Unknown frame type " << frame_type;
|
| + return on_unknown_frame_result_;
|
| + }
|
| +
|
| virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
|
| SpdyFrameType type,
|
| size_t payload_len,
|
| @@ -446,13 +465,6 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| last_frame_len_ = frame_len;
|
| }
|
|
|
| - virtual void OnPriority(SpdyStreamId stream_id,
|
| - SpdyStreamId parent_stream_id,
|
| - uint8 weight,
|
| - bool exclusive) OVERRIDE {
|
| - ++priority_count_;
|
| - }
|
| -
|
| virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id,
|
| SpdyFrameType type,
|
| size_t frame_len) OVERRIDE {
|
| @@ -523,6 +535,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface,
|
| int altsvc_count_;
|
| int priority_count_;
|
| SpdyAltSvcIR test_altsvc_ir_;
|
| + bool on_unknown_frame_result_;
|
| SpdyStreamId last_window_update_stream_;
|
| uint32 last_window_update_delta_;
|
| SpdyStreamId last_push_promise_stream_;
|
| @@ -3526,6 +3539,51 @@ TEST_P(SpdyFramerTest, ReadDuplicateSettings) {
|
| }
|
| }
|
|
|
| +// Tests handling of SETTINGS frame with a setting we don't recognize.
|
| +TEST_P(SpdyFramerTest, ReadUnknownSettingsId) {
|
| + SpdyFramer framer(spdy_version_);
|
| +
|
| + const unsigned char kV2FrameData[] = {
|
| + 0x80, spdy_version_ch_, 0x00, 0x04,
|
| + 0x00, 0x00, 0x00, 0x1C,
|
| + 0x00, 0x00, 0x00, 0x01,
|
| + 0x10, 0x00, 0x00, 0x00, // 1st Setting
|
| + 0x00, 0x00, 0x00, 0x02,
|
| + };
|
| + const unsigned char kV3FrameData[] = {
|
| + 0x80, spdy_version_ch_, 0x00, 0x04,
|
| + 0x00, 0x00, 0x00, 0x1C,
|
| + 0x00, 0x00, 0x00, 0x01,
|
| + 0x00, 0x00, 0x00, 0x10, // 1st Setting
|
| + 0x00, 0x00, 0x00, 0x02,
|
| + };
|
| + const unsigned char kV4FrameData[] = {
|
| + 0x00, 0x06, 0x04, 0x00,
|
| + 0x00, 0x00, 0x00, 0x00,
|
| + 0x00, 0x10, // 1st Setting
|
| + 0x00, 0x00, 0x00, 0x02,
|
| + };
|
| +
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| + visitor.use_compression_ = false;
|
| + if (IsSpdy2()) {
|
| + visitor.SimulateInFramer(kV2FrameData, sizeof(kV2FrameData));
|
| + } else if (IsSpdy3()) {
|
| + visitor.SimulateInFramer(kV3FrameData, sizeof(kV3FrameData));
|
| + } else {
|
| + visitor.SimulateInFramer(kV4FrameData, sizeof(kV4FrameData));
|
| + }
|
| +
|
| + if (!IsSpdy4()) {
|
| + EXPECT_EQ(0, visitor.setting_count_);
|
| + EXPECT_EQ(1, visitor.error_count_);
|
| + } else {
|
| + // In SPDY 4+, we ignore unknown settings because of extensions.
|
| + EXPECT_EQ(0, visitor.setting_count_);
|
| + EXPECT_EQ(0, visitor.error_count_);
|
| + }
|
| +}
|
| +
|
| // Tests handling of SETTINGS frame with entries out of order.
|
| TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
|
| SpdyFramer framer(spdy_version_);
|
| @@ -3580,7 +3638,6 @@ TEST_P(SpdyFramerTest, ReadOutOfOrderSettings) {
|
| // In SPDY 4+, settings are allowed in any order.
|
| EXPECT_EQ(3, visitor.setting_count_);
|
| EXPECT_EQ(0, visitor.error_count_);
|
| - // EXPECT_EQ(1, visitor.settings_ack_count_);
|
| }
|
| }
|
|
|
| @@ -4125,13 +4182,50 @@ TEST_P(SpdyFramerTest, ReadGarbage) {
|
| EXPECT_EQ(1, visitor.error_count_);
|
| }
|
|
|
| +TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) {
|
| + if (spdy_version_ <= SPDY3) {
|
| + return;
|
| + }
|
| + SpdyFramer framer(spdy_version_);
|
| +
|
| + // The unrecognized frame type should still have a valid length.
|
| + const unsigned char unknown_frame[] = {
|
| + 0x00, 0x08, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff,
|
| + 0xff, 0xff, 0xff, 0xff,
|
| + };
|
| + TestSpdyVisitor visitor(spdy_version_);
|
| +
|
| + // Simulate the case where the stream id validation checks out.
|
| + visitor.on_unknown_frame_result_ = true;
|
| + visitor.use_compression_ = false;
|
| + visitor.SimulateInFramer(unknown_frame, arraysize(unknown_frame));
|
| + EXPECT_EQ(0, visitor.error_count_);
|
| +
|
| + // Follow it up with a valid control frame to make sure we handle
|
| + // subsequent frames correctly.
|
| + SpdySettingsIR settings_ir;
|
| + settings_ir.AddSetting(SpdyConstants::ParseSettingId(spdy_version_, 1),
|
| + false, // persist
|
| + false, // persisted
|
| + 10);
|
| + scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
|
| + visitor.SimulateInFramer(
|
| + reinterpret_cast<unsigned char*>(control_frame->data()),
|
| + control_frame->size());
|
| + EXPECT_EQ(0, visitor.error_count_);
|
| + EXPECT_EQ(1u, static_cast<unsigned>(visitor.setting_count_));
|
| + EXPECT_EQ(1u, static_cast<unsigned>(visitor.settings_ack_sent_));
|
| +}
|
| +
|
| TEST_P(SpdyFramerTest, ReadGarbageWithValidLength) {
|
| if (!IsSpdy4()) {
|
| return;
|
| }
|
| SpdyFramer framer(spdy_version_);
|
| const unsigned char kFrameData[] = {
|
| - 0x00, 0x10, 0xff, 0xff,
|
| + 0x00, 0x08, 0xff, 0xff,
|
| 0xff, 0xff, 0xff, 0xff,
|
| 0xff, 0xff, 0xff, 0xff,
|
| 0xff, 0xff, 0xff, 0xff,
|
|
|