xref: /aosp_15_r20/external/cronet/net/websockets/websocket_inflater_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 The Chromium Authors
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 "net/websockets/websocket_inflater.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "net/base/io_buffer.h"
11 #include "net/websockets/websocket_deflater.h"
12 #include "net/websockets/websocket_test_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace net {
16 
17 namespace {
18 
ToString(IOBufferWithSize * buffer)19 std::string ToString(IOBufferWithSize* buffer) {
20   return std::string(buffer->data(), buffer->size());
21 }
22 
TEST(WebSocketInflaterTest,Construct)23 TEST(WebSocketInflaterTest, Construct) {
24   WebSocketInflater inflater;
25   ASSERT_TRUE(inflater.Initialize(15));
26 
27   EXPECT_EQ(0u, inflater.CurrentOutputSize());
28 }
29 
TEST(WebSocketInflaterTest,InflateHelloTakeOverContext)30 TEST(WebSocketInflaterTest, InflateHelloTakeOverContext) {
31   WebSocketInflater inflater;
32   ASSERT_TRUE(inflater.Initialize(15));
33   scoped_refptr<IOBufferWithSize> actual1, actual2;
34 
35   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
36   ASSERT_TRUE(inflater.Finish());
37   actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
38   ASSERT_TRUE(actual1.get());
39   EXPECT_EQ("Hello", ToString(actual1.get()));
40   EXPECT_EQ(0u, inflater.CurrentOutputSize());
41 
42   ASSERT_TRUE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
43   ASSERT_TRUE(inflater.Finish());
44   actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
45   ASSERT_TRUE(actual2.get());
46   EXPECT_EQ("Hello", ToString(actual2.get()));
47   EXPECT_EQ(0u, inflater.CurrentOutputSize());
48 }
49 
TEST(WebSocketInflaterTest,InflateHelloSmallCapacity)50 TEST(WebSocketInflaterTest, InflateHelloSmallCapacity) {
51   WebSocketInflater inflater(1, 1);
52   ASSERT_TRUE(inflater.Initialize(15));
53   std::string actual;
54 
55   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
56   ASSERT_TRUE(inflater.Finish());
57   for (size_t i = 0; i < 5; ++i) {
58     ASSERT_EQ(1u, inflater.CurrentOutputSize());
59     scoped_refptr<IOBufferWithSize> buffer = inflater.GetOutput(1);
60     ASSERT_TRUE(buffer.get());
61     ASSERT_EQ(1, buffer->size());
62     actual += ToString(buffer.get());
63   }
64   EXPECT_EQ("Hello", actual);
65   EXPECT_EQ(0u, inflater.CurrentOutputSize());
66 }
67 
TEST(WebSocketInflaterTest,InflateHelloSmallCapacityGetTotalOutput)68 TEST(WebSocketInflaterTest, InflateHelloSmallCapacityGetTotalOutput) {
69   WebSocketInflater inflater(1, 1);
70   ASSERT_TRUE(inflater.Initialize(15));
71   scoped_refptr<IOBufferWithSize> actual;
72 
73   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
74   ASSERT_TRUE(inflater.Finish());
75   ASSERT_EQ(1u, inflater.CurrentOutputSize());
76   actual = inflater.GetOutput(1024);
77   EXPECT_EQ("Hello", ToString(actual.get()));
78   EXPECT_EQ(0u, inflater.CurrentOutputSize());
79 }
80 
TEST(WebSocketInflaterTest,InflateInvalidData)81 TEST(WebSocketInflaterTest, InflateInvalidData) {
82   WebSocketInflater inflater;
83   ASSERT_TRUE(inflater.Initialize(15));
84   EXPECT_FALSE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
85 }
86 
TEST(WebSocketInflaterTest,ChokedInvalidData)87 TEST(WebSocketInflaterTest, ChokedInvalidData) {
88   WebSocketInflater inflater(1, 1);
89   ASSERT_TRUE(inflater.Initialize(15));
90 
91   EXPECT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9INVALID DATA", 16));
92   EXPECT_TRUE(inflater.Finish());
93   EXPECT_EQ(1u, inflater.CurrentOutputSize());
94   EXPECT_FALSE(inflater.GetOutput(1024).get());
95 }
96 
TEST(WebSocketInflaterTest,MultipleAddBytesCalls)97 TEST(WebSocketInflaterTest, MultipleAddBytesCalls) {
98   WebSocketInflater inflater;
99   ASSERT_TRUE(inflater.Initialize(15));
100   std::string input("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
101   scoped_refptr<IOBufferWithSize> actual;
102 
103   for (char& c : input) {
104     ASSERT_TRUE(inflater.AddBytes(&c, 1));
105   }
106   ASSERT_TRUE(inflater.Finish());
107   actual = inflater.GetOutput(5);
108   ASSERT_TRUE(actual.get());
109   EXPECT_EQ("Hello", ToString(actual.get()));
110 }
111 
TEST(WebSocketInflaterTest,Reset)112 TEST(WebSocketInflaterTest, Reset) {
113   WebSocketInflater inflater;
114   ASSERT_TRUE(inflater.Initialize(15));
115   scoped_refptr<IOBufferWithSize> actual1, actual2;
116 
117   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
118   ASSERT_TRUE(inflater.Finish());
119   actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
120   ASSERT_TRUE(actual1.get());
121   EXPECT_EQ("Hello", ToString(actual1.get()));
122   EXPECT_EQ(0u, inflater.CurrentOutputSize());
123 
124   // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
125   ASSERT_TRUE(inflater.AddBytes("\x01", 1));
126   ASSERT_TRUE(inflater.Finish());
127   ASSERT_EQ(0u, inflater.CurrentOutputSize());
128 
129   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
130   ASSERT_TRUE(inflater.Finish());
131   actual2 = inflater.GetOutput(inflater.CurrentOutputSize());
132   ASSERT_TRUE(actual2.get());
133   EXPECT_EQ("Hello", ToString(actual2.get()));
134   EXPECT_EQ(0u, inflater.CurrentOutputSize());
135 }
136 
TEST(WebSocketInflaterTest,ResetAndLostContext)137 TEST(WebSocketInflaterTest, ResetAndLostContext) {
138   WebSocketInflater inflater;
139   scoped_refptr<IOBufferWithSize> actual1, actual2;
140   ASSERT_TRUE(inflater.Initialize(15));
141 
142   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
143   ASSERT_TRUE(inflater.Finish());
144   actual1 = inflater.GetOutput(inflater.CurrentOutputSize());
145   ASSERT_TRUE(actual1.get());
146   EXPECT_EQ("Hello", ToString(actual1.get()));
147   EXPECT_EQ(0u, inflater.CurrentOutputSize());
148 
149   // Reset the stream with a block [BFINAL = 1, BTYPE = 00, LEN = 0]
150   ASSERT_TRUE(inflater.AddBytes("\x01", 1));
151   ASSERT_TRUE(inflater.Finish());
152   ASSERT_EQ(0u, inflater.CurrentOutputSize());
153 
154   // The context is already reset.
155   ASSERT_FALSE(inflater.AddBytes("\xf2\x00\x11\x00\x00", 5));
156 }
157 
TEST(WebSocketInflaterTest,CallAddBytesAndFinishWithoutGetOutput)158 TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutput) {
159   WebSocketInflater inflater;
160   scoped_refptr<IOBufferWithSize> actual1, actual2;
161   ASSERT_TRUE(inflater.Initialize(15));
162 
163   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
164   ASSERT_TRUE(inflater.Finish());
165   EXPECT_EQ(5u, inflater.CurrentOutputSize());
166 
167   // This is a test for memory leak detectors.
168 }
169 
TEST(WebSocketInflaterTest,CallAddBytesAndFinishWithoutGetOutputChoked)170 TEST(WebSocketInflaterTest, CallAddBytesAndFinishWithoutGetOutputChoked) {
171   WebSocketInflater inflater(1, 1);
172   scoped_refptr<IOBufferWithSize> actual1, actual2;
173   ASSERT_TRUE(inflater.Initialize(15));
174 
175   ASSERT_TRUE(inflater.AddBytes("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
176   ASSERT_TRUE(inflater.Finish());
177   EXPECT_EQ(1u, inflater.CurrentOutputSize());
178 
179   // This is a test for memory leak detectors.
180 }
181 
TEST(WebSocketInflaterTest,LargeRandomDeflateInflate)182 TEST(WebSocketInflaterTest, LargeRandomDeflateInflate) {
183   const size_t size = 64 * 1024;
184   LinearCongruentialGenerator generator(133);
185   std::vector<char> input;
186   std::vector<char> output;
187   scoped_refptr<IOBufferWithSize> compressed;
188 
189   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
190   ASSERT_TRUE(deflater.Initialize(8));
191   WebSocketInflater inflater(256, 256);
192   ASSERT_TRUE(inflater.Initialize(8));
193 
194   for (size_t i = 0; i < size; ++i)
195     input.push_back(static_cast<char>(generator.Generate()));
196 
197   ASSERT_TRUE(deflater.AddBytes(input.data(), input.size()));
198   ASSERT_TRUE(deflater.Finish());
199 
200   compressed = deflater.GetOutput(deflater.CurrentOutputSize());
201 
202   ASSERT_TRUE(compressed.get());
203   ASSERT_EQ(0u, deflater.CurrentOutputSize());
204 
205   ASSERT_TRUE(inflater.AddBytes(compressed->data(), compressed->size()));
206   ASSERT_TRUE(inflater.Finish());
207 
208   while (inflater.CurrentOutputSize() > 0) {
209     scoped_refptr<IOBufferWithSize> uncompressed =
210         inflater.GetOutput(inflater.CurrentOutputSize());
211     ASSERT_TRUE(uncompressed.get());
212     output.insert(output.end(),
213                   uncompressed->data(),
214                   uncompressed->data() + uncompressed->size());
215   }
216 
217   EXPECT_EQ(output, input);
218 }
219 
220 }  // unnamed namespace
221 
222 }  // namespace net
223