• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/qpack/qpack_encoder_stream_receiver.h"
6 
7 #include "absl/strings/escaping.h"
8 #include "absl/strings/string_view.h"
9 #include "quiche/quic/platform/api/quic_test.h"
10 
11 using testing::Eq;
12 using testing::StrictMock;
13 
14 namespace quic {
15 namespace test {
16 namespace {
17 
18 class MockDelegate : public QpackEncoderStreamReceiver::Delegate {
19  public:
20   ~MockDelegate() override = default;
21 
22   MOCK_METHOD(void, OnInsertWithNameReference,
23               (bool is_static, uint64_t name_index, absl::string_view value),
24               (override));
25   MOCK_METHOD(void, OnInsertWithoutNameReference,
26               (absl::string_view name, absl::string_view value), (override));
27   MOCK_METHOD(void, OnDuplicate, (uint64_t index), (override));
28   MOCK_METHOD(void, OnSetDynamicTableCapacity, (uint64_t capacity), (override));
29   MOCK_METHOD(void, OnErrorDetected,
30               (QuicErrorCode error_code, absl::string_view error_message),
31               (override));
32 };
33 
34 class QpackEncoderStreamReceiverTest : public QuicTest {
35  protected:
QpackEncoderStreamReceiverTest()36   QpackEncoderStreamReceiverTest() : stream_(&delegate_) {}
37   ~QpackEncoderStreamReceiverTest() override = default;
38 
Decode(absl::string_view data)39   void Decode(absl::string_view data) { stream_.Decode(data); }
delegate()40   StrictMock<MockDelegate>* delegate() { return &delegate_; }
41 
42  private:
43   QpackEncoderStreamReceiver stream_;
44   StrictMock<MockDelegate> delegate_;
45 };
46 
TEST_F(QpackEncoderStreamReceiverTest,InsertWithNameReference)47 TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReference) {
48   // Static, index fits in prefix, empty value.
49   EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 5, Eq("")));
50   // Static, index fits in prefix, Huffman encoded value.
51   EXPECT_CALL(*delegate(), OnInsertWithNameReference(true, 2, Eq("foo")));
52   // Not static, index does not fit in prefix, not Huffman encoded value.
53   EXPECT_CALL(*delegate(), OnInsertWithNameReference(false, 137, Eq("bar")));
54   // Value length does not fit in prefix.
55   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
56   EXPECT_CALL(*delegate(),
57               OnInsertWithNameReference(false, 42, Eq(std::string(127, 'Z'))));
58 
59   Decode(absl::HexStringToBytes(
60       "c500"
61       "c28294e7"
62       "bf4a03626172"
63       "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
64       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
65       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
66       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
67 }
68 
TEST_F(QpackEncoderStreamReceiverTest,InsertWithNameReferenceIndexTooLarge)69 TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceIndexTooLarge) {
70   EXPECT_CALL(*delegate(),
71               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
72                               Eq("Encoded integer too large.")));
73 
74   Decode(absl::HexStringToBytes("bfffffffffffffffffffffff"));
75 }
76 
TEST_F(QpackEncoderStreamReceiverTest,InsertWithNameReferenceValueTooLong)77 TEST_F(QpackEncoderStreamReceiverTest, InsertWithNameReferenceValueTooLong) {
78   EXPECT_CALL(*delegate(),
79               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
80                               Eq("Encoded integer too large.")));
81 
82   Decode(absl::HexStringToBytes("c57fffffffffffffffffffff"));
83 }
84 
TEST_F(QpackEncoderStreamReceiverTest,InsertWithoutNameReference)85 TEST_F(QpackEncoderStreamReceiverTest, InsertWithoutNameReference) {
86   // Empty name and value.
87   EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq(""), Eq("")));
88   // Huffman encoded short strings.
89   EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("bar"), Eq("bar")));
90   // Not Huffman encoded short strings.
91   EXPECT_CALL(*delegate(), OnInsertWithoutNameReference(Eq("foo"), Eq("foo")));
92   // Not Huffman encoded long strings; length does not fit on prefix.
93   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
94   EXPECT_CALL(*delegate(),
95               OnInsertWithoutNameReference(Eq(std::string(31, 'Z')),
96                                            Eq(std::string(127, 'Z'))));
97 
98   Decode(absl::HexStringToBytes(
99       "4000"
100       "4362617203626172"
101       "6294e78294e7"
102       "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f005a"
103       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
104       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
105       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
106       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"));
107 }
108 
109 // Name Length value is too large for varint decoder to decode.
TEST_F(QpackEncoderStreamReceiverTest,InsertWithoutNameReferenceNameTooLongForVarintDecoder)110 TEST_F(QpackEncoderStreamReceiverTest,
111        InsertWithoutNameReferenceNameTooLongForVarintDecoder) {
112   EXPECT_CALL(*delegate(),
113               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
114                               Eq("Encoded integer too large.")));
115 
116   Decode(absl::HexStringToBytes("5fffffffffffffffffffff"));
117 }
118 
119 // Name Length value can be decoded by varint decoder but exceeds 1 MB limit.
TEST_F(QpackEncoderStreamReceiverTest,InsertWithoutNameReferenceNameExceedsLimit)120 TEST_F(QpackEncoderStreamReceiverTest,
121        InsertWithoutNameReferenceNameExceedsLimit) {
122   EXPECT_CALL(*delegate(),
123               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
124                               Eq("String literal too long.")));
125 
126   Decode(absl::HexStringToBytes("5fffff7f"));
127 }
128 
129 // Value Length value is too large for varint decoder to decode.
TEST_F(QpackEncoderStreamReceiverTest,InsertWithoutNameReferenceValueTooLongForVarintDecoder)130 TEST_F(QpackEncoderStreamReceiverTest,
131        InsertWithoutNameReferenceValueTooLongForVarintDecoder) {
132   EXPECT_CALL(*delegate(),
133               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
134                               Eq("Encoded integer too large.")));
135 
136   Decode(absl::HexStringToBytes("436261727fffffffffffffffffffff"));
137 }
138 
139 // Value Length value can be decoded by varint decoder but exceeds 1 MB limit.
TEST_F(QpackEncoderStreamReceiverTest,InsertWithoutNameReferenceValueExceedsLimit)140 TEST_F(QpackEncoderStreamReceiverTest,
141        InsertWithoutNameReferenceValueExceedsLimit) {
142   EXPECT_CALL(*delegate(),
143               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG,
144                               Eq("String literal too long.")));
145 
146   Decode(absl::HexStringToBytes("436261727fffff7f"));
147 }
148 
TEST_F(QpackEncoderStreamReceiverTest,Duplicate)149 TEST_F(QpackEncoderStreamReceiverTest, Duplicate) {
150   // Small index fits in prefix.
151   EXPECT_CALL(*delegate(), OnDuplicate(17));
152   // Large index requires two extension bytes.
153   EXPECT_CALL(*delegate(), OnDuplicate(500));
154 
155   Decode(absl::HexStringToBytes("111fd503"));
156 }
157 
TEST_F(QpackEncoderStreamReceiverTest,DuplicateIndexTooLarge)158 TEST_F(QpackEncoderStreamReceiverTest, DuplicateIndexTooLarge) {
159   EXPECT_CALL(*delegate(),
160               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
161                               Eq("Encoded integer too large.")));
162 
163   Decode(absl::HexStringToBytes("1fffffffffffffffffffff"));
164 }
165 
TEST_F(QpackEncoderStreamReceiverTest,SetDynamicTableCapacity)166 TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacity) {
167   // Small capacity fits in prefix.
168   EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(17));
169   // Large capacity requires two extension bytes.
170   EXPECT_CALL(*delegate(), OnSetDynamicTableCapacity(500));
171 
172   Decode(absl::HexStringToBytes("313fd503"));
173 }
174 
TEST_F(QpackEncoderStreamReceiverTest,SetDynamicTableCapacityTooLarge)175 TEST_F(QpackEncoderStreamReceiverTest, SetDynamicTableCapacityTooLarge) {
176   EXPECT_CALL(*delegate(),
177               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE,
178                               Eq("Encoded integer too large.")));
179 
180   Decode(absl::HexStringToBytes("3fffffffffffffffffffff"));
181 }
182 
TEST_F(QpackEncoderStreamReceiverTest,InvalidHuffmanEncoding)183 TEST_F(QpackEncoderStreamReceiverTest, InvalidHuffmanEncoding) {
184   EXPECT_CALL(*delegate(),
185               OnErrorDetected(QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR,
186                               Eq("Error in Huffman-encoded string.")));
187 
188   Decode(absl::HexStringToBytes("c281ff"));
189 }
190 
191 }  // namespace
192 }  // namespace test
193 }  // namespace quic
194