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