xref: /aosp_15_r20/external/pigweed/pw_varint/stream_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_varint/stream.h"
16 
17 #include <array>
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21 #include <limits>
22 
23 #include "pw_stream/memory_stream.h"
24 #include "pw_unit_test/framework.h"
25 #include "pw_varint/varint.h"
26 
27 namespace pw::varint {
28 namespace {
29 template <size_t kStringSize>
MakeBuffer(const char (& data)[kStringSize])30 auto MakeBuffer(const char (&data)[kStringSize]) {
31   constexpr size_t kSizeBytes = kStringSize - 1;
32   static_assert(kSizeBytes <= 10, "Varint arrays never need be larger than 10");
33 
34   std::array<std::byte, kSizeBytes> array;
35   std::memcpy(array.data(), data, kSizeBytes);
36   return array;
37 }
38 }  // namespace
39 
TEST(VarintRead,Signed64_SingleByte)40 TEST(VarintRead, Signed64_SingleByte) {
41   int64_t value = -1234;
42 
43   {
44     const auto buffer = MakeBuffer("\x00");
45     stream::MemoryReader reader(buffer);
46     const auto sws = Read(reader, &value);
47     EXPECT_TRUE(sws.ok());
48     EXPECT_EQ(sws.size(), 1u);
49     EXPECT_EQ(value, 0);
50   }
51 
52   {
53     const auto buffer = MakeBuffer("\x01");
54     stream::MemoryReader reader(buffer);
55     const auto sws = Read(reader, &value);
56     EXPECT_TRUE(sws.ok());
57     EXPECT_EQ(sws.size(), 1u);
58     EXPECT_EQ(value, -1);
59   }
60 
61   {
62     const auto buffer = MakeBuffer("\x02");
63     stream::MemoryReader reader(buffer);
64     const auto sws = Read(reader, &value);
65     EXPECT_TRUE(sws.ok());
66     EXPECT_EQ(sws.size(), 1u);
67     EXPECT_EQ(value, 1);
68   }
69 
70   {
71     const auto buffer = MakeBuffer("\x03");
72     stream::MemoryReader reader(buffer);
73     const auto sws = Read(reader, &value);
74     EXPECT_TRUE(sws.ok());
75     EXPECT_EQ(sws.size(), 1u);
76     EXPECT_EQ(value, -2);
77   }
78 
79   {
80     const auto buffer = MakeBuffer("\x04");
81     stream::MemoryReader reader(buffer);
82     const auto sws = Read(reader, &value);
83     EXPECT_TRUE(sws.ok());
84     EXPECT_EQ(sws.size(), 1u);
85     EXPECT_EQ(value, 2);
86   }
87 }
88 
TEST(VarintRead,Signed64_MultiByte)89 TEST(VarintRead, Signed64_MultiByte) {
90   int64_t value = -1234;
91 
92   {
93     const auto buffer = MakeBuffer("\x80\x01");
94     stream::MemoryReader reader(buffer);
95     const auto sws = Read(reader, &value);
96     EXPECT_TRUE(sws.ok());
97     EXPECT_EQ(sws.size(), 2u);
98     EXPECT_EQ(value, 64);
99   }
100 
101   {
102     const auto buffer = MakeBuffer("\x81\x01");
103     stream::MemoryReader reader(buffer);
104     const auto sws = Read(reader, &value);
105     EXPECT_TRUE(sws.ok());
106     EXPECT_EQ(sws.size(), 2u);
107     EXPECT_EQ(value, -65);
108   }
109 
110   {
111     const auto buffer = MakeBuffer("\x82\x01");
112     stream::MemoryReader reader(buffer);
113     const auto sws = Read(reader, &value);
114     EXPECT_TRUE(sws.ok());
115     EXPECT_EQ(sws.size(), 2u);
116     EXPECT_EQ(value, 65);
117   }
118 
119   {
120     const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f");
121     stream::MemoryReader reader(buffer);
122     const auto sws = Read(reader, &value);
123     EXPECT_TRUE(sws.ok());
124     EXPECT_EQ(sws.size(), 5u);
125     EXPECT_EQ(value, std::numeric_limits<int32_t>::min());
126   }
127 
128   {
129     const auto buffer = MakeBuffer("\xfe\xff\xff\xff\x0f");
130     stream::MemoryReader reader(buffer);
131     const auto sws = Read(reader, &value);
132     EXPECT_TRUE(sws.ok());
133     EXPECT_EQ(sws.size(), 5u);
134     EXPECT_EQ(value, std::numeric_limits<int32_t>::max());
135   }
136 
137   {
138     const auto buffer = MakeBuffer("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01");
139     stream::MemoryReader reader(buffer);
140     const auto sws = Read(reader, &value);
141     EXPECT_TRUE(sws.ok());
142     EXPECT_EQ(sws.size(), 10u);
143     EXPECT_EQ(value, std::numeric_limits<int64_t>::min());
144   }
145 
146   {
147     const auto buffer = MakeBuffer("\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x01");
148     stream::MemoryReader reader(buffer);
149     const auto sws = Read(reader, &value);
150     EXPECT_TRUE(sws.ok());
151     EXPECT_EQ(sws.size(), 10u);
152     EXPECT_EQ(value, std::numeric_limits<int64_t>::max());
153   }
154 }
155 
TEST(VarintRead,Unsigned64_SingleByte)156 TEST(VarintRead, Unsigned64_SingleByte) {
157   uint64_t value = 1234;
158 
159   {
160     const auto buffer = MakeBuffer("\x00");
161     stream::MemoryReader reader(buffer);
162     const auto sws = Read(reader, &value);
163     EXPECT_TRUE(sws.ok());
164     EXPECT_EQ(sws.size(), 1u);
165     EXPECT_EQ(value, 0u);
166   }
167 
168   {
169     const auto buffer = MakeBuffer("\x04");
170     stream::MemoryReader reader(buffer);
171     const auto sws = Read(reader, &value);
172     EXPECT_TRUE(sws.ok());
173     EXPECT_EQ(sws.size(), 1u);
174     EXPECT_EQ(value, 4u);
175   }
176 
177   {
178     const auto buffer = MakeBuffer("\x41");
179     stream::MemoryReader reader(buffer);
180     const auto sws = Read(reader, &value);
181     EXPECT_TRUE(sws.ok());
182     EXPECT_EQ(sws.size(), 1u);
183     EXPECT_EQ(value, 65u);
184   }
185 }
186 
TEST(VarintRead,Unsigned64_MultiByte)187 TEST(VarintRead, Unsigned64_MultiByte) {
188   uint64_t value;
189 
190   {
191     const auto buffer = MakeBuffer("\x80\x01");
192     stream::MemoryReader reader(buffer);
193     const auto sws = Read(reader, &value);
194     EXPECT_TRUE(sws.ok());
195     EXPECT_EQ(sws.size(), 2u);
196     EXPECT_EQ(value, 128u);
197   }
198 
199   {
200     const auto buffer = MakeBuffer("\x81\x01");
201     stream::MemoryReader reader(buffer);
202     const auto sws = Read(reader, &value);
203     EXPECT_TRUE(sws.ok());
204     EXPECT_EQ(sws.size(), 2u);
205     EXPECT_EQ(value, 129u);
206   }
207 
208   {
209     const auto buffer = MakeBuffer("\xfe\xff\xff\xff\x0f");
210     stream::MemoryReader reader(buffer);
211     const auto sws = Read(reader, &value);
212     EXPECT_TRUE(sws.ok());
213     EXPECT_EQ(sws.size(), 5u);
214     EXPECT_EQ(value, std::numeric_limits<uint32_t>::max() - 1);
215   }
216 
217   {
218     const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f");
219     stream::MemoryReader reader(buffer);
220     const auto sws = Read(reader, &value);
221     EXPECT_TRUE(sws.ok());
222     EXPECT_EQ(sws.size(), 5u);
223     EXPECT_EQ(value, std::numeric_limits<uint32_t>::max());
224   }
225 
226   {
227     const auto buffer = MakeBuffer("\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x01");
228     stream::MemoryReader reader(buffer);
229     const auto sws = Read(reader, &value);
230     EXPECT_TRUE(sws.ok());
231     EXPECT_EQ(sws.size(), 10u);
232     EXPECT_EQ(value, std::numeric_limits<uint64_t>::max() - 1);
233   }
234 
235   {
236     const auto buffer = MakeBuffer("\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01");
237     stream::MemoryReader reader(buffer);
238     const auto sws = Read(reader, &value);
239     EXPECT_TRUE(sws.ok());
240     EXPECT_EQ(sws.size(), 10u);
241     EXPECT_EQ(value, std::numeric_limits<uint64_t>::max());
242   }
243 }
244 
TEST(VarintRead,Errors)245 TEST(VarintRead, Errors) {
246   uint64_t value;
247 
248   {
249     std::array<std::byte, 0> buffer{};
250     stream::MemoryReader reader(buffer);
251     const auto sws = Read(reader, &value);
252     EXPECT_FALSE(sws.ok());
253     EXPECT_EQ(sws.status(), Status::OutOfRange());
254     EXPECT_EQ(sws.size(), buffer.size());
255   }
256 
257   {
258     const auto buffer = MakeBuffer("\xff\xff");
259     stream::MemoryReader reader(buffer);
260     const auto sws = Read(reader, &value);
261     EXPECT_FALSE(sws.ok());
262     EXPECT_EQ(sws.status(), Status::DataLoss());
263     EXPECT_EQ(sws.size(), buffer.size());
264   }
265 
266   {
267     std::array<std::byte, varint::kMaxVarint64SizeBytes + 1> buffer{};
268     for (auto& b : buffer) {
269       b = std::byte{0xff};
270     }
271 
272     stream::MemoryReader reader(buffer);
273     const auto sws = Read(reader, &value);
274     EXPECT_FALSE(sws.ok());
275     EXPECT_EQ(sws.status(), Status::DataLoss());
276     EXPECT_EQ(sws.size(), varint::kMaxVarint64SizeBytes);
277   }
278 }
279 
TEST(VarintRead,SizeLimit)280 TEST(VarintRead, SizeLimit) {
281   uint64_t value;
282 
283   {
284     // buffer contains a valid varint, but we limit the read length to ensure
285     // that the final byte is not read, turning it into an error.
286     const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f");
287     stream::MemoryReader reader(buffer);
288     const auto sws = Read(reader, &value, 4);
289     EXPECT_FALSE(sws.ok());
290     EXPECT_EQ(sws.status(), Status::DataLoss());
291     EXPECT_EQ(sws.size(), 4u);
292     EXPECT_EQ(reader.Tell(), 4u);
293   }
294 
295   {
296     // If we tell varint::Read() to read zero bytes, it should always return
297     // OutOfRange() without moving the reader.
298     const auto buffer = MakeBuffer("\xff\xff\xff\xff\x0f");
299     stream::MemoryReader reader(buffer);
300     const auto sws = Read(reader, &value, 0);
301     EXPECT_FALSE(sws.ok());
302     EXPECT_EQ(sws.status(), Status::OutOfRange());
303     EXPECT_EQ(sws.size(), 0u);
304     EXPECT_EQ(reader.Tell(), 0u);
305   }
306 }
307 
308 }  // namespace pw::varint
309