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_protobuf/stream_decoder.h"
16
17 #include <array>
18
19 #include "gtest/gtest.h"
20 #include "pw_status/status.h"
21 #include "pw_status/status_with_size.h"
22 #include "pw_stream/memory_stream.h"
23 #include "pw_stream/stream.h"
24
25 namespace pw::protobuf {
26 namespace {
27 // Non-seekable wrapper for MemoryReader for testing behavior when seeking is
28 // not available.
29 class NonSeekableMemoryReader : public stream::NonSeekableReader {
30 public:
NonSeekableMemoryReader(stream::MemoryReader & reader)31 explicit NonSeekableMemoryReader(stream::MemoryReader& reader)
32 : reader_(reader) {}
33
bytes_read() const34 size_t bytes_read() const { return reader_.bytes_read(); }
data() const35 const std::byte* data() const { return reader_.data(); }
36
37 private:
DoRead(ByteSpan destination)38 StatusWithSize DoRead(ByteSpan destination) override {
39 const pw::Result<pw::ByteSpan> result = reader_.Read(destination);
40 if (!result.ok()) {
41 return StatusWithSize(result.status(), 0);
42 }
43 return StatusWithSize(result.value().size_bytes());
44 }
45
46 stream::MemoryReader& reader_;
47 };
48
TEST(StreamDecoder,Decode)49 TEST(StreamDecoder, Decode) {
50 // clang-format off
51 constexpr uint8_t encoded_proto[] = {
52 // type=int32, k=1, v=42
53 0x08, 0x2a,
54 // type=sint32, k=2, v=-13
55 0x10, 0x19,
56 // type=bool, k=3, v=false
57 0x18, 0x00,
58 // type=double, k=4, v=3.14159
59 0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
60 // type=fixed32, k=5, v=0xdeadbeef
61 0x2d, 0xef, 0xbe, 0xad, 0xde,
62 // type=string, k=6, v="Hello world"
63 0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
64 // type=sfixed32, k=7, v=-50
65 0x3d, 0xce, 0xff, 0xff, 0xff,
66 // type=sfixed64, k=8, v=-1647993274
67 0x41, 0x46, 0x9e, 0xc5, 0x9d, 0xff, 0xff, 0xff, 0xff,
68 // type=float, k=9, v=2.718
69 0x4d, 0xb6, 0xf3, 0x2d, 0x40,
70 };
71 // clang-format on
72
73 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
74 StreamDecoder decoder(reader);
75
76 EXPECT_EQ(decoder.Next(), OkStatus());
77 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
78 Result<int32_t> int32 = decoder.ReadInt32();
79 ASSERT_EQ(int32.status(), OkStatus());
80 EXPECT_EQ(int32.value(), 42);
81
82 EXPECT_EQ(decoder.Next(), OkStatus());
83 ASSERT_EQ(decoder.FieldNumber().value(), 2u);
84 Result<int32_t> sint32 = decoder.ReadSint32();
85 ASSERT_EQ(sint32.status(), OkStatus());
86 EXPECT_EQ(sint32.value(), -13);
87
88 EXPECT_EQ(decoder.Next(), OkStatus());
89 ASSERT_EQ(decoder.FieldNumber().value(), 3u);
90 Result<bool> boolean = decoder.ReadBool();
91 ASSERT_EQ(boolean.status(), OkStatus());
92 EXPECT_FALSE(boolean.value());
93
94 EXPECT_EQ(decoder.Next(), OkStatus());
95 ASSERT_EQ(decoder.FieldNumber().value(), 4u);
96 Result<double> dbl = decoder.ReadDouble();
97 ASSERT_EQ(dbl.status(), OkStatus());
98 EXPECT_EQ(dbl.value(), 3.14159);
99
100 EXPECT_EQ(decoder.Next(), OkStatus());
101 ASSERT_EQ(decoder.FieldNumber().value(), 5u);
102 Result<uint32_t> fixed32 = decoder.ReadFixed32();
103 ASSERT_EQ(fixed32.status(), OkStatus());
104 EXPECT_EQ(fixed32.value(), 0xdeadbeef);
105
106 char buffer[16];
107 EXPECT_EQ(decoder.Next(), OkStatus());
108 ASSERT_EQ(decoder.FieldNumber().value(), 6u);
109 StatusWithSize sws = decoder.ReadString(buffer);
110 ASSERT_EQ(sws.status(), OkStatus());
111 buffer[sws.size()] = '\0';
112 EXPECT_STREQ(buffer, "Hello world");
113
114 EXPECT_EQ(decoder.Next(), OkStatus());
115 ASSERT_EQ(decoder.FieldNumber().value(), 7u);
116 Result<int32_t> sfixed32 = decoder.ReadSfixed32();
117 ASSERT_EQ(sfixed32.status(), OkStatus());
118 EXPECT_EQ(sfixed32.value(), -50);
119
120 EXPECT_EQ(decoder.Next(), OkStatus());
121 ASSERT_EQ(decoder.FieldNumber().value(), 8u);
122 Result<int64_t> sfixed64 = decoder.ReadSfixed64();
123 ASSERT_EQ(sfixed64.status(), OkStatus());
124 EXPECT_EQ(sfixed64.value(), -1647993274);
125
126 EXPECT_EQ(decoder.Next(), OkStatus());
127 ASSERT_EQ(decoder.FieldNumber().value(), 9u);
128 Result<float> flt = decoder.ReadFloat();
129 ASSERT_EQ(flt.status(), OkStatus());
130 EXPECT_EQ(flt.value(), 2.718f);
131
132 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
133 }
134
TEST(StreamDecoder,Decode_SkipsUnusedFields)135 TEST(StreamDecoder, Decode_SkipsUnusedFields) {
136 // clang-format off
137 constexpr uint8_t encoded_proto[] = {
138 // type=int32, k=1, v=42
139 0x08, 0x2a,
140 // type=sint32, k=2, v=-13
141 0x10, 0x19,
142 // type=bool, k=3, v=false
143 0x18, 0x00,
144 // type=double, k=4, v=3.14159
145 0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
146 // type=fixed32, k=5, v=0xdeadbeef
147 0x2d, 0xef, 0xbe, 0xad, 0xde,
148 // type=string, k=6, v="Hello world"
149 0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
150 };
151 // clang-format on
152
153 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
154 StreamDecoder decoder(reader);
155
156 // Don't process any fields except for the fourth. Next should still iterate
157 // correctly despite field values not being consumed.
158 EXPECT_EQ(decoder.Next(), OkStatus());
159 EXPECT_EQ(decoder.Next(), OkStatus());
160 EXPECT_EQ(decoder.Next(), OkStatus());
161 EXPECT_EQ(decoder.Next(), OkStatus());
162 ASSERT_EQ(*decoder.FieldNumber(), 4u);
163 EXPECT_EQ(decoder.Next(), OkStatus());
164 EXPECT_EQ(decoder.Next(), OkStatus());
165 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
166 }
167
TEST(StreamDecoder,Decode_NonSeekable_SkipsUnusedFields)168 TEST(StreamDecoder, Decode_NonSeekable_SkipsUnusedFields) {
169 // clang-format off
170 constexpr uint8_t encoded_proto[] = {
171 // type=int32, k=1, v=42
172 0x08, 0x2a,
173 // type=sint32, k=2, v=-13
174 0x10, 0x19,
175 // type=bool, k=3, v=false
176 0x18, 0x00,
177 // type=double, k=4, v=3.14159
178 0x21, 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
179 // type=fixed32, k=5, v=0xdeadbeef
180 0x2d, 0xef, 0xbe, 0xad, 0xde,
181 // type=string, k=6, v="Hello world"
182 0x32, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
183 };
184 // clang-format on
185
186 // Test with a non-seekable memory reader
187 stream::MemoryReader wrapped_reader(as_bytes(span(encoded_proto)));
188 NonSeekableMemoryReader reader(wrapped_reader);
189 StreamDecoder decoder(reader);
190
191 // Don't process any fields except for the fourth. Next should still iterate
192 // correctly despite field values not being consumed.
193 EXPECT_EQ(decoder.Next(), OkStatus());
194 EXPECT_EQ(decoder.Next(), OkStatus());
195 EXPECT_EQ(decoder.Next(), OkStatus());
196 EXPECT_EQ(decoder.Next(), OkStatus());
197 ASSERT_EQ(*decoder.FieldNumber(), 4u);
198 EXPECT_EQ(decoder.Next(), OkStatus());
199 EXPECT_EQ(decoder.Next(), OkStatus());
200 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
201 }
202
TEST(StreamDecoder,Decode_BadData)203 TEST(StreamDecoder, Decode_BadData) {
204 // clang-format off
205 constexpr uint8_t encoded_proto[] = {
206 // type=int32, k=1, v=42
207 0x08, 0x2a,
208 // type=sint32, k=2, value... missing
209 0x10,
210 };
211 // clang-format on
212
213 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
214 StreamDecoder decoder(reader);
215
216 EXPECT_EQ(decoder.Next(), OkStatus());
217 ASSERT_EQ(*decoder.FieldNumber(), 1u);
218 Result<int32_t> int32 = decoder.ReadInt32();
219 ASSERT_EQ(int32.status(), OkStatus());
220 EXPECT_EQ(int32.value(), 42);
221
222 EXPECT_EQ(decoder.Next(), OkStatus());
223 ASSERT_EQ(*decoder.FieldNumber(), 2u);
224 EXPECT_EQ(decoder.ReadSint32().status(), Status::DataLoss());
225
226 EXPECT_EQ(decoder.Next(), Status::DataLoss());
227 }
228
TEST(StreamDecoder,Decode_MissingDelimitedLength)229 TEST(StreamDecoder, Decode_MissingDelimitedLength) {
230 // clang-format off
231 constexpr uint8_t encoded_proto[] = {
232 // type=int32, k=1, v=42
233 0x08, 0x2a,
234 // Submessage (bytes) key=8, length=... missing
235 0x32,
236 };
237 // clang-format on
238
239 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
240 StreamDecoder decoder(reader);
241
242 EXPECT_EQ(decoder.Next(), OkStatus());
243 ASSERT_EQ(*decoder.FieldNumber(), 1u);
244 Result<int32_t> int32 = decoder.ReadInt32();
245 ASSERT_EQ(int32.status(), OkStatus());
246 EXPECT_EQ(int32.value(), 42);
247
248 EXPECT_EQ(decoder.Next(), Status::DataLoss());
249 }
250
TEST(StreamDecoder,Decode_VarintTooBig)251 TEST(StreamDecoder, Decode_VarintTooBig) {
252 // clang-format off
253 constexpr uint8_t encoded_proto[] = {
254 // type=uint32, k=1, v=>uint32_t::max
255 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
256 // type=int32, k=2, v=>int32_t::max
257 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
258 // type=int32, k=3, v<=int32_t::min
259 0x18, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01,
260 // type=sint32, k=4, v=>int32_t::max
261 0x20, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x0f,
262 // type=sint32, k=5, v<=int32_t::max
263 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
264 };
265 // clang-format on
266
267 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
268 StreamDecoder decoder(reader);
269
270 EXPECT_EQ(decoder.Next(), OkStatus());
271 ASSERT_EQ(*decoder.FieldNumber(), 1u);
272 Result<uint32_t> uint32 = decoder.ReadUint32();
273 ASSERT_EQ(uint32.status(), Status::FailedPrecondition());
274
275 EXPECT_EQ(decoder.Next(), OkStatus());
276 ASSERT_EQ(*decoder.FieldNumber(), 2u);
277 Result<int32_t> int32 = decoder.ReadInt32();
278 ASSERT_EQ(int32.status(), Status::FailedPrecondition());
279
280 EXPECT_EQ(decoder.Next(), OkStatus());
281 ASSERT_EQ(*decoder.FieldNumber(), 3u);
282 int32 = decoder.ReadInt32();
283 ASSERT_EQ(int32.status(), Status::FailedPrecondition());
284
285 EXPECT_EQ(decoder.Next(), OkStatus());
286 ASSERT_EQ(*decoder.FieldNumber(), 4u);
287 Result<int32_t> sint32 = decoder.ReadSint32();
288 ASSERT_EQ(sint32.status(), Status::FailedPrecondition());
289
290 EXPECT_EQ(decoder.Next(), OkStatus());
291 ASSERT_EQ(*decoder.FieldNumber(), 5u);
292 sint32 = decoder.ReadSint32();
293 ASSERT_EQ(sint32.status(), Status::FailedPrecondition());
294
295 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
296 }
297
TEST(Decoder,Decode_SkipsBadFieldNumbers)298 TEST(Decoder, Decode_SkipsBadFieldNumbers) {
299 // clang-format off
300 constexpr uint8_t encoded_proto[] = {
301 // type=int32, k=1, v=42
302 0x08, 0x2a,
303 // type=int32, k=19001, v=42 (invalid field number)
304 0xc8, 0xa3, 0x09, 0x2a,
305 // type=bool, k=3, v=false
306 0x18, 0x00,
307 };
308 // clang-format on
309
310 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
311 StreamDecoder decoder(reader);
312
313 EXPECT_EQ(decoder.Next(), OkStatus());
314 EXPECT_EQ(*decoder.FieldNumber(), 1u);
315 Result<int32_t> int32 = decoder.ReadInt32();
316 ASSERT_EQ(int32.status(), OkStatus());
317 EXPECT_EQ(int32.value(), 42);
318
319 // Bad field.
320 EXPECT_EQ(decoder.Next(), Status::DataLoss());
321 EXPECT_EQ(decoder.FieldNumber().status(), Status::FailedPrecondition());
322
323 EXPECT_EQ(decoder.Next(), Status::DataLoss());
324 }
325
TEST(StreamDecoder,Decode_Nested)326 TEST(StreamDecoder, Decode_Nested) {
327 // clang-format off
328 constexpr uint8_t encoded_proto[] = {
329 // type=int32, k=1, v=42
330 0x08, 0x2a,
331
332 // Submessage (bytes) key=8, length=4
333 0x32, 0x04,
334 // type=uint32, k=1, v=2
335 0x08, 0x02,
336 // type=uint32, k=2, v=7
337 0x10, 0x07,
338 // End submessage
339
340 // type=sint32, k=2, v=-13
341 0x10, 0x19,
342 };
343 // clang-format on
344
345 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
346 StreamDecoder decoder(reader);
347
348 EXPECT_EQ(decoder.Next(), OkStatus());
349 ASSERT_EQ(*decoder.FieldNumber(), 1u);
350 Result<int32_t> int32 = decoder.ReadInt32();
351 ASSERT_EQ(int32.status(), OkStatus());
352 EXPECT_EQ(int32.value(), 42);
353
354 EXPECT_EQ(decoder.Next(), OkStatus());
355 ASSERT_EQ(*decoder.FieldNumber(), 6u);
356 {
357 StreamDecoder nested = decoder.GetNestedDecoder();
358
359 EXPECT_EQ(nested.Next(), OkStatus());
360 ASSERT_EQ(*nested.FieldNumber(), 1u);
361 Result<uint32_t> uint32 = nested.ReadUint32();
362 ASSERT_EQ(uint32.status(), OkStatus());
363 EXPECT_EQ(uint32.value(), 2u);
364
365 EXPECT_EQ(nested.Next(), OkStatus());
366 ASSERT_EQ(*nested.FieldNumber(), 2u);
367 uint32 = nested.ReadUint32();
368 ASSERT_EQ(uint32.status(), OkStatus());
369 EXPECT_EQ(uint32.value(), 7u);
370
371 ASSERT_EQ(nested.Next(), Status::OutOfRange());
372 }
373
374 EXPECT_EQ(decoder.Next(), OkStatus());
375 ASSERT_EQ(*decoder.FieldNumber(), 2u);
376 Result<int32_t> sint32 = decoder.ReadSint32();
377 ASSERT_EQ(sint32.status(), OkStatus());
378 EXPECT_EQ(sint32.value(), -13);
379
380 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
381 }
382
TEST(StreamDecoder,Decode_Nested_SeeksToNextFieldOnDestruction)383 TEST(StreamDecoder, Decode_Nested_SeeksToNextFieldOnDestruction) {
384 // clang-format off
385 constexpr uint8_t encoded_proto[] = {
386 // type=int32, k=1, v=42
387 0x08, 0x2a,
388
389 // Submessage (bytes) key=8, length=4
390 0x32, 0x04,
391 // type=uint32, k=1, v=2
392 0x08, 0x02,
393 // type=uint32, k=2, v=7
394 0x10, 0x07,
395 // End submessage
396
397 // type=sint32, k=2, v=-13
398 0x10, 0x19,
399 };
400 // clang-format on
401
402 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
403 StreamDecoder decoder(reader);
404
405 EXPECT_EQ(decoder.Next(), OkStatus());
406 ASSERT_EQ(*decoder.FieldNumber(), 1u);
407
408 // Create a nested encoder for the nested field, but don't use it.
409 EXPECT_EQ(decoder.Next(), OkStatus());
410 ASSERT_EQ(*decoder.FieldNumber(), 6u);
411 { StreamDecoder nested = decoder.GetNestedDecoder(); }
412
413 // The root decoder should still advance to the next field after the nested
414 // decoder is closed.
415 EXPECT_EQ(decoder.Next(), OkStatus());
416 ASSERT_EQ(*decoder.FieldNumber(), 2u);
417
418 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
419 }
420
TEST(StreamDecoder,Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction)421 TEST(StreamDecoder,
422 Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction) {
423 // clang-format off
424 constexpr uint8_t encoded_proto[] = {
425 // type=int32, k=1, v=42
426 0x08, 0x2a,
427
428 // Submessage (bytes) key=8, length=4
429 0x32, 0x04,
430 // type=uint32, k=1, v=2
431 0x08, 0x02,
432 // type=uint32, k=2, v=7
433 0x10, 0x07,
434 // End submessage
435
436 // type=sint32, k=2, v=-13
437 0x10, 0x19,
438 };
439 // clang-format on
440
441 // Test with a non-seekable memory reader
442 stream::MemoryReader wrapped_reader(as_bytes(span(encoded_proto)));
443 NonSeekableMemoryReader reader(wrapped_reader);
444 StreamDecoder decoder(reader);
445
446 EXPECT_EQ(decoder.Next(), OkStatus());
447 ASSERT_EQ(*decoder.FieldNumber(), 1u);
448
449 // Create a nested encoder for the nested field, but don't use it.
450 EXPECT_EQ(decoder.Next(), OkStatus());
451 ASSERT_EQ(*decoder.FieldNumber(), 6u);
452 { StreamDecoder nested = decoder.GetNestedDecoder(); }
453
454 // The root decoder should still advance to the next field after the nested
455 // decoder is closed.
456 EXPECT_EQ(decoder.Next(), OkStatus());
457 ASSERT_EQ(*decoder.FieldNumber(), 2u);
458
459 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
460 }
461
TEST(StreamDecoder,Decode_Nested_LastField)462 TEST(StreamDecoder, Decode_Nested_LastField) {
463 // clang-format off
464 constexpr uint8_t encoded_proto[] = {
465 // type=int32, k=1, v=42
466 0x08, 0x2a,
467
468 // Submessage (bytes) key=8, length=4
469 0x32, 0x04,
470 // type=uint32, k=1, v=2
471 0x08, 0x02,
472 // type=uint32, k=2, v=7
473 0x10, 0x07,
474 // End submessage and proto
475 };
476 // clang-format on
477
478 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
479 StreamDecoder decoder(reader);
480
481 EXPECT_EQ(decoder.Next(), OkStatus());
482 ASSERT_EQ(*decoder.FieldNumber(), 1u);
483
484 // Create a nested encoder for the nested field, which is the last field in
485 // the root proto.
486 EXPECT_EQ(decoder.Next(), OkStatus());
487 ASSERT_EQ(*decoder.FieldNumber(), 6u);
488 { StreamDecoder nested = decoder.GetNestedDecoder(); }
489
490 // Root decoder should correctly terminate after the nested decoder is closed.
491 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
492 }
493
TEST(StreamDecoder,Decode_Nested_MultiLevel)494 TEST(StreamDecoder, Decode_Nested_MultiLevel) {
495 // clang-format off
496 constexpr uint8_t encoded_proto[] = {
497 // Submessage key=1, length=4
498 0x0a, 0x04,
499
500 // Sub-submessage key=1, length=2
501 0x0a, 0x02,
502 // type=uint32, k=2, v=7
503 0x10, 0x07,
504 // End sub-submessage
505
506 // End submessage
507 };
508 // clang-format on
509
510 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
511 StreamDecoder decoder(reader);
512
513 EXPECT_EQ(decoder.Next(), OkStatus());
514 ASSERT_EQ(*decoder.FieldNumber(), 1u);
515 {
516 StreamDecoder nested = decoder.GetNestedDecoder();
517
518 EXPECT_EQ(nested.Next(), OkStatus());
519 ASSERT_EQ(*nested.FieldNumber(), 1u);
520
521 {
522 StreamDecoder double_nested = nested.GetNestedDecoder();
523
524 EXPECT_EQ(double_nested.Next(), OkStatus());
525 ASSERT_EQ(*double_nested.FieldNumber(), 2u);
526 Result<uint32_t> result = double_nested.ReadUint32();
527 ASSERT_EQ(result.status(), OkStatus());
528 EXPECT_EQ(result.value(), 7u);
529
530 EXPECT_EQ(double_nested.Next(), Status::OutOfRange());
531 }
532
533 EXPECT_EQ(nested.Next(), Status::OutOfRange());
534 }
535
536 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
537 }
538
TEST(StreamDecoder,Decode_Nested_InvalidField)539 TEST(StreamDecoder, Decode_Nested_InvalidField) {
540 // clang-format off
541 constexpr uint8_t encoded_proto[] = {
542 // Submessage key=1, length=4
543 0x0a, 0x04,
544
545 // Oops. No data!
546 };
547
548 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
549 StreamDecoder decoder(reader);
550
551 EXPECT_EQ(decoder.Next(), OkStatus());
552 ASSERT_EQ(*decoder.FieldNumber(), 1u);
553 {
554 StreamDecoder nested = decoder.GetNestedDecoder();
555 EXPECT_EQ(nested.Next(), Status::DataLoss());
556 }
557
558 EXPECT_EQ(decoder.Next(), Status::DataLoss());
559 }
560
TEST(StreamDecoder,Decode_Nested_InvalidFieldKey)561 TEST(StreamDecoder, Decode_Nested_InvalidFieldKey) {
562 // clang-format off
563 constexpr uint8_t encoded_proto[] = {
564 // Submessage key=1, length=2
565 0x0a, 0x02,
566 // type=invalid...
567 0xff, 0xff,
568 // End submessage
569
570 // type=sint32, k=2, v=-13
571 0x10, 0x19,
572 };
573 // clang-format on
574
575 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
576 StreamDecoder decoder(reader);
577
578 EXPECT_EQ(decoder.Next(), OkStatus());
579 ASSERT_EQ(*decoder.FieldNumber(), 1u);
580
581 {
582 StreamDecoder nested = decoder.GetNestedDecoder();
583 EXPECT_EQ(nested.Next(), Status::DataLoss());
584
585 // Make sure that the nested decoder didn't run off the end of the
586 // submessage.
587 ASSERT_EQ(reader.Tell(), 4u);
588 }
589 }
590
TEST(StreamDecoder,Decode_Nested_MissingDelimitedLength)591 TEST(StreamDecoder, Decode_Nested_MissingDelimitedLength) {
592 // clang-format off
593 constexpr uint8_t encoded_proto[] = {
594 // Submessage key=1, length=1
595 0x0a, 0x01,
596 // Delimited field (bytes) key=1, length=missing...
597 0x0a,
598 // End submessage
599
600 // type=sint32, k=2, v=-13
601 0x10, 0x19,
602 };
603 // clang-format on
604
605 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
606 StreamDecoder decoder(reader);
607
608 EXPECT_EQ(decoder.Next(), OkStatus());
609 ASSERT_EQ(*decoder.FieldNumber(), 1u);
610
611 {
612 StreamDecoder nested = decoder.GetNestedDecoder();
613 EXPECT_EQ(nested.Next(), Status::DataLoss());
614
615 // Make sure that the nested decoder didn't run off the end of the
616 // submessage.
617 ASSERT_EQ(reader.Tell(), 3u);
618 }
619 }
620
TEST(StreamDecoder,Decode_Nested_InvalidDelimitedLength)621 TEST(StreamDecoder, Decode_Nested_InvalidDelimitedLength) {
622 // clang-format off
623 constexpr uint8_t encoded_proto[] = {
624 // Submessage key=1, length=2
625 0x0a, 0x02,
626 // Delimited field (bytes) key=1, length=invalid...
627 0x0a, 0xff,
628 // End submessage
629
630 // type=sint32, k=2, v=-13
631 0x10, 0x19,
632 };
633 // clang-format on
634
635 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
636 StreamDecoder decoder(reader);
637
638 EXPECT_EQ(decoder.Next(), OkStatus());
639 ASSERT_EQ(*decoder.FieldNumber(), 1u);
640
641 {
642 StreamDecoder nested = decoder.GetNestedDecoder();
643 EXPECT_EQ(nested.Next(), Status::DataLoss());
644
645 // Make sure that the nested decoder didn't run off the end of the
646 // submessage.
647 ASSERT_EQ(reader.Tell(), 4u);
648 }
649 }
650
TEST(StreamDecoder,Decode_Nested_InvalidVarint)651 TEST(StreamDecoder, Decode_Nested_InvalidVarint) {
652 // clang-format off
653 constexpr uint8_t encoded_proto[] = {
654 // Submessage key=1, length=2
655 0x0a, 0x02,
656 // type=uint32 key=1, value=invalid...
657 0x08, 0xff,
658 // End submessage
659
660 // type=sint32, k=2, v=-13
661 0x10, 0x19,
662 };
663 // clang-format on
664
665 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
666 StreamDecoder decoder(reader);
667
668 EXPECT_EQ(decoder.Next(), OkStatus());
669 ASSERT_EQ(*decoder.FieldNumber(), 1u);
670
671 {
672 StreamDecoder nested = decoder.GetNestedDecoder();
673 EXPECT_EQ(nested.Next(), OkStatus());
674 ASSERT_EQ(*nested.FieldNumber(), 1u);
675
676 Result<uint32_t> uint32 = nested.ReadUint32();
677 EXPECT_EQ(uint32.status(), Status::DataLoss());
678
679 // Make sure that the nested decoder didn't run off the end of the
680 // submessage.
681 ASSERT_EQ(reader.Tell(), 4u);
682 }
683 }
684
TEST(StreamDecoder,Decode_Nested_SkipInvalidVarint)685 TEST(StreamDecoder, Decode_Nested_SkipInvalidVarint) {
686 // clang-format off
687 constexpr uint8_t encoded_proto[] = {
688 // Submessage key=1, length=2
689 0x0a, 0x02,
690 // type=uint32 key=1, value=invalid...
691 0x08, 0xff,
692 // End submessage
693
694 // type=sint32, k=2, v=-13
695 0x10, 0x19,
696 };
697 // clang-format on
698
699 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
700 StreamDecoder decoder(reader);
701
702 EXPECT_EQ(decoder.Next(), OkStatus());
703 ASSERT_EQ(*decoder.FieldNumber(), 1u);
704
705 {
706 StreamDecoder nested = decoder.GetNestedDecoder();
707 EXPECT_EQ(nested.Next(), OkStatus());
708 ASSERT_EQ(*nested.FieldNumber(), 1u);
709
710 // Skip without reading.
711 EXPECT_EQ(nested.Next(), Status::DataLoss());
712
713 // Make sure that the nested decoder didn't run off the end of the
714 // submessage.
715 ASSERT_EQ(reader.Tell(), 4u);
716 }
717 }
718
TEST(StreamDecoder,Decode_Nested_TruncatedFixed)719 TEST(StreamDecoder, Decode_Nested_TruncatedFixed) {
720 // clang-format off
721 constexpr uint8_t encoded_proto[] = {
722 // Submessage key=1, length=2
723 0x0a, 0x03,
724 // type=fixed32 key=1, value=truncated...
725 0x0d, 0x42, 0x00,
726 // End submessage
727
728 // type=sint32, k=2, v=-13
729 0x10, 0x19,
730 };
731 // clang-format on
732
733 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
734 StreamDecoder decoder(reader);
735
736 EXPECT_EQ(decoder.Next(), OkStatus());
737 ASSERT_EQ(*decoder.FieldNumber(), 1u);
738
739 {
740 StreamDecoder nested = decoder.GetNestedDecoder();
741 EXPECT_EQ(nested.Next(), OkStatus());
742 ASSERT_EQ(*nested.FieldNumber(), 1u);
743
744 Result<uint32_t> uint32 = nested.ReadFixed32();
745 EXPECT_EQ(uint32.status(), Status::DataLoss());
746
747 // Make sure that the nested decoder didn't run off the end of the
748 // submessage. Note that this will not read the data at all in this case.
749 ASSERT_EQ(reader.Tell(), 3u);
750 }
751 }
752
TEST(StreamDecoder,Decode_Nested_SkipTruncatedFixed)753 TEST(StreamDecoder, Decode_Nested_SkipTruncatedFixed) {
754 // clang-format off
755 constexpr uint8_t encoded_proto[] = {
756 // Submessage key=1, length=2
757 0x0a, 0x03,
758 // type=fixed32 key=1, value=truncated...
759 0x0d, 0x42, 0x00,
760 // End submessage
761
762 // type=sint32, k=2, v=-13
763 0x10, 0x19,
764 };
765 // clang-format on
766
767 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
768 StreamDecoder decoder(reader);
769
770 EXPECT_EQ(decoder.Next(), OkStatus());
771 ASSERT_EQ(*decoder.FieldNumber(), 1u);
772
773 {
774 StreamDecoder nested = decoder.GetNestedDecoder();
775 EXPECT_EQ(nested.Next(), OkStatus());
776 ASSERT_EQ(*nested.FieldNumber(), 1u);
777
778 // Skip without reading.
779 EXPECT_EQ(nested.Next(), Status::DataLoss());
780
781 // Make sure that the nested decoder didn't run off the end of the
782 // submessage. Note that this will be unable to skip the field without
783 // exceeding the range of the nested decoder, so it won't move the cursor.
784 ASSERT_EQ(reader.Tell(), 3u);
785 }
786 }
787
TEST(StreamDecoder,Decode_BytesReader)788 TEST(StreamDecoder, Decode_BytesReader) {
789 // clang-format off
790 constexpr uint8_t encoded_proto[] = {
791 // bytes key=1, length=14
792 0x0a, 0x0e,
793
794 0x00, 0x01, 0x02, 0x03,
795 0x04, 0x05, 0x06, 0x07,
796 0x08, 0x09, 0x0a, 0x0b,
797 0x0c, 0x0d,
798 };
799 // clang-format on
800
801 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
802 StreamDecoder decoder(reader);
803
804 EXPECT_EQ(decoder.Next(), OkStatus());
805 EXPECT_EQ(*decoder.FieldNumber(), 1u);
806 {
807 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
808 EXPECT_EQ(bytes.field_size(), 14u);
809
810 std::byte buffer[7];
811 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
812 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
813
814 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
815 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 9, sizeof(buffer)), 0);
816
817 EXPECT_EQ(bytes.Read(buffer).status(), Status::OutOfRange());
818 }
819
820 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
821 }
822
TEST(StreamDecoder,Decode_BytesReader_Seek)823 TEST(StreamDecoder, Decode_BytesReader_Seek) {
824 // clang-format off
825 constexpr uint8_t encoded_proto[] = {
826 // bytes key=1, length=14
827 0x0a, 0x0e,
828
829 0x00, 0x01, 0x02, 0x03,
830 0x04, 0x05, 0x06, 0x07,
831 0x08, 0x09, 0x0a, 0x0b,
832 0x0c, 0x0d,
833 };
834 // clang-format on
835
836 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
837 StreamDecoder decoder(reader);
838
839 EXPECT_EQ(decoder.Next(), OkStatus());
840 EXPECT_EQ(*decoder.FieldNumber(), 1u);
841 {
842 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
843
844 std::byte buffer[2];
845
846 ASSERT_EQ(bytes.Seek(3), OkStatus());
847
848 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
849 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 5, sizeof(buffer)), 0);
850
851 // Bad seek offset (absolute).
852 ASSERT_EQ(bytes.Seek(15), Status::OutOfRange());
853
854 // Seek back from current position.
855 ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), OkStatus());
856
857 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
858 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 3, sizeof(buffer)), 0);
859
860 // Bad seek offset (relative).
861 ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), Status::OutOfRange());
862
863 // Seek from the end of the bytes field.
864 ASSERT_EQ(bytes.Seek(-2, stream::Stream::kEnd), OkStatus());
865
866 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
867 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 14, sizeof(buffer)), 0);
868
869 // Bad seek offset (end).
870 ASSERT_EQ(bytes.Seek(-15, stream::Stream::kEnd), Status::OutOfRange());
871 }
872
873 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
874 }
875
TEST(StreamDecoder,Decode_BytesReader_Close)876 TEST(StreamDecoder, Decode_BytesReader_Close) {
877 // clang-format off
878 constexpr uint8_t encoded_proto[] = {
879 // bytes key=1, length=14
880 0x0a, 0x0e,
881
882 0x00, 0x01, 0x02, 0x03,
883 0x04, 0x05, 0x06, 0x07,
884 0x08, 0x09, 0x0a, 0x0b,
885 0x0c, 0x0d,
886 // End bytes
887
888 // type=sint32, k=2, v=-13
889 0x10, 0x19,
890 };
891 // clang-format on
892
893 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
894 StreamDecoder decoder(reader);
895
896 EXPECT_EQ(decoder.Next(), OkStatus());
897 EXPECT_EQ(*decoder.FieldNumber(), 1u);
898 {
899 // Partially consume the bytes field.
900 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
901
902 std::byte buffer[2];
903 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
904 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
905 }
906
907 // Continue reading the top-level message.
908 EXPECT_EQ(decoder.Next(), OkStatus());
909 EXPECT_EQ(*decoder.FieldNumber(), 2u);
910
911 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
912 }
913
TEST(StreamDecoder,Decode_BytesReader_NonSeekable_Close)914 TEST(StreamDecoder, Decode_BytesReader_NonSeekable_Close) {
915 // clang-format off
916 constexpr uint8_t encoded_proto[] = {
917 // bytes key=1, length=14
918 0x0a, 0x0e,
919
920 0x00, 0x01, 0x02, 0x03,
921 0x04, 0x05, 0x06, 0x07,
922 0x08, 0x09, 0x0a, 0x0b,
923 0x0c, 0x0d,
924 // End bytes
925
926 // type=sint32, k=2, v=-13
927 0x10, 0x19,
928 };
929 // clang-format on
930
931 // Test with a non-seekable memory reader
932 stream::MemoryReader wrapped_reader(as_bytes(span(encoded_proto)));
933 NonSeekableMemoryReader reader(wrapped_reader);
934 StreamDecoder decoder(reader);
935
936 EXPECT_EQ(decoder.Next(), OkStatus());
937 EXPECT_EQ(*decoder.FieldNumber(), 1u);
938 {
939 // Partially consume the bytes field.
940 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
941
942 std::byte buffer[2];
943 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
944 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
945 }
946
947 // Continue reading the top-level message.
948 EXPECT_EQ(decoder.Next(), OkStatus());
949 EXPECT_EQ(*decoder.FieldNumber(), 2u);
950
951 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
952 }
953
TEST(StreamDecoder,Decode_BytesReader_InvalidField)954 TEST(StreamDecoder, Decode_BytesReader_InvalidField) {
955 // clang-format off
956 constexpr uint8_t encoded_proto[] = {
957 // bytes key=1, length=4
958 0x0a, 0x04,
959
960 // Oops. No data!
961 };
962
963 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
964 StreamDecoder decoder(reader);
965
966 EXPECT_EQ(decoder.Next(), OkStatus());
967 ASSERT_EQ(*decoder.FieldNumber(), 1u);
968 {
969 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
970 EXPECT_EQ(bytes.Seek(0), Status::DataLoss());
971
972 std::byte buffer[2];
973 EXPECT_EQ(bytes.Read(buffer).status(), Status::DataLoss());
974 }
975
976 EXPECT_EQ(decoder.Next(), Status::DataLoss());
977 }
978
TEST(StreamDecoder,GetLengthDelimitedPayloadBounds)979 TEST(StreamDecoder, GetLengthDelimitedPayloadBounds) {
980 // clang-format off
981 constexpr uint8_t encoded_proto[] = {
982 // bytes key=1, length=14
983 0x0a, 0x0e,
984
985 0x00, 0x01, 0x02, 0x03,
986 0x04, 0x05, 0x06, 0x07,
987 0x08, 0x09, 0x0a, 0x0b,
988 0x0c, 0x0d,
989 // End bytes
990
991 // type=sint32, k=2, v=-13
992 0x10, 0x19,
993 };
994 // clang-format on
995
996 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
997 StreamDecoder decoder(reader);
998
999 ASSERT_EQ(OkStatus(), decoder.Next());
1000 Result<StreamDecoder::Bounds> field_bound =
1001 decoder.GetLengthDelimitedPayloadBounds();
1002 ASSERT_EQ(OkStatus(), field_bound.status());
1003 ASSERT_EQ(field_bound.value().low, 2ULL);
1004 ASSERT_EQ(field_bound.value().high, 16ULL);
1005
1006 ASSERT_EQ(OkStatus(), decoder.Next());
1007 ASSERT_EQ(Status::NotFound(),
1008 decoder.GetLengthDelimitedPayloadBounds().status());
1009 }
1010
TEST(StreamDecoder,ReadDelimitedField_DoesntOverConsume)1011 TEST(StreamDecoder, ReadDelimitedField_DoesntOverConsume) {
1012 // clang-format off
1013 constexpr uint8_t encoded_proto[] = {
1014 // type=string, k=1, v="Hello world"
1015 0x0a, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
1016 // type=int32, k=2, v=42
1017 0x10, 0x2a,
1018 };
1019 // clang-format on
1020
1021 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1022 StreamDecoder decoder(reader);
1023
1024 ASSERT_EQ(OkStatus(), decoder.Next());
1025
1026 // This buffer is much larger than the string.
1027 char buffer[128];
1028 const StatusWithSize size = decoder.ReadString(buffer);
1029 EXPECT_EQ(size.status(), OkStatus());
1030 EXPECT_EQ(size.size(), 11u);
1031
1032 // Make sure we can still read the next field.
1033 ASSERT_EQ(OkStatus(), decoder.Next());
1034 const pw::Result<int32_t> result = decoder.ReadInt32();
1035 EXPECT_EQ(result.status(), OkStatus());
1036 EXPECT_EQ(result.value(), 42);
1037 }
1038
TEST(StreamDecoder,Decode_WithLength)1039 TEST(StreamDecoder, Decode_WithLength) {
1040 // clang-format off
1041 constexpr uint8_t encoded_proto[] = {
1042 // type=int32, k=1, v=42
1043 0x08, 0x2a,
1044 // This field is beyond the range of the protobuf:
1045 // type=sint32, k=2, v=-13
1046 0x10, 0x19,
1047 };
1048 // clang-format on
1049
1050 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1051 StreamDecoder decoder(reader, /*length=*/2u);
1052
1053 EXPECT_EQ(decoder.Next(), OkStatus());
1054 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1055 Result<int32_t> int32 = decoder.ReadInt32();
1056 ASSERT_EQ(int32.status(), OkStatus());
1057 EXPECT_EQ(int32.value(), 42);
1058
1059 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1060 }
1061
TEST(StreamDecoder,Decode_WithLength_SkipsToEnd)1062 TEST(StreamDecoder, Decode_WithLength_SkipsToEnd) {
1063 // clang-format off
1064 constexpr uint8_t encoded_proto[] = {
1065 // type=string, k=1, v="Hello world"
1066 0x08, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
1067 // This field is beyond the range of the protobuf:
1068 // type=sint32, k=2, v=-13
1069 0x10, 0x19,
1070 };
1071 // clang-format on
1072
1073 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1074 {
1075 StreamDecoder decoder(reader, /*length=*/13u);
1076
1077 EXPECT_EQ(decoder.Next(), OkStatus());
1078 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1079 // Don't read the value out, or advance further. Destructing the object
1080 // should advance to the end of the length given.
1081 }
1082
1083 EXPECT_EQ(reader.Tell(), 13u);
1084 }
1085
TEST(StreamDecoder,RepeatedField)1086 TEST(StreamDecoder, RepeatedField) {
1087 // clang-format off
1088 constexpr uint8_t encoded_proto[] = {
1089 // type=uint32, k=1, v=0
1090 0x08, 0x00,
1091 // type=uint32, k=1, v=50
1092 0x08, 0x32,
1093 // type=uint32, k=1, v=100
1094 0x08, 0x64,
1095 // type=uint32, k=1, v=150
1096 0x08, 0x96, 0x01,
1097 // type=uint32, k=1, v=200
1098 0x08, 0xc8, 0x01
1099 };
1100 // clang-format on
1101
1102 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1103 StreamDecoder decoder(reader);
1104
1105 EXPECT_EQ(decoder.Next(), OkStatus());
1106 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1107 Result<uint32_t> uint32 = decoder.ReadUint32();
1108 ASSERT_EQ(uint32.status(), OkStatus());
1109 EXPECT_EQ(uint32.value(), 0u);
1110
1111 EXPECT_EQ(decoder.Next(), OkStatus());
1112 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1113 uint32 = decoder.ReadUint32();
1114 ASSERT_EQ(uint32.status(), OkStatus());
1115 EXPECT_EQ(uint32.value(), 50u);
1116
1117 EXPECT_EQ(decoder.Next(), OkStatus());
1118 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1119 uint32 = decoder.ReadUint32();
1120 ASSERT_EQ(uint32.status(), OkStatus());
1121 EXPECT_EQ(uint32.value(), 100u);
1122
1123 EXPECT_EQ(decoder.Next(), OkStatus());
1124 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1125 uint32 = decoder.ReadUint32();
1126 ASSERT_EQ(uint32.status(), OkStatus());
1127 EXPECT_EQ(uint32.value(), 150u);
1128
1129 EXPECT_EQ(decoder.Next(), OkStatus());
1130 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1131 uint32 = decoder.ReadUint32();
1132 ASSERT_EQ(uint32.status(), OkStatus());
1133 EXPECT_EQ(uint32.value(), 200u);
1134
1135 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1136 }
1137
TEST(StreamDecoder,RepeatedFieldVector)1138 TEST(StreamDecoder, RepeatedFieldVector) {
1139 // clang-format off
1140 constexpr uint8_t encoded_proto[] = {
1141 // type=uint32, k=1, v=0
1142 0x08, 0x00,
1143 // type=uint32, k=1, v=50
1144 0x08, 0x32,
1145 // type=uint32, k=1, v=100
1146 0x08, 0x64,
1147 // type=uint32, k=1, v=150
1148 0x08, 0x96, 0x01,
1149 // type=uint32, k=1, v=200
1150 0x08, 0xc8, 0x01
1151 };
1152 // clang-format on
1153
1154 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1155 StreamDecoder decoder(reader);
1156
1157 pw::Vector<uint32_t, 8> uint32{};
1158
1159 EXPECT_EQ(decoder.Next(), OkStatus());
1160 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1161 Status status = decoder.ReadRepeatedUint32(uint32);
1162 ASSERT_EQ(status, OkStatus());
1163 EXPECT_EQ(uint32.size(), 1u);
1164 EXPECT_EQ(uint32[0], 0u);
1165
1166 EXPECT_EQ(decoder.Next(), OkStatus());
1167 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1168 status = decoder.ReadRepeatedUint32(uint32);
1169 ASSERT_EQ(status, OkStatus());
1170 EXPECT_EQ(uint32.size(), 2u);
1171 EXPECT_EQ(uint32[1], 50u);
1172
1173 EXPECT_EQ(decoder.Next(), OkStatus());
1174 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1175 status = decoder.ReadRepeatedUint32(uint32);
1176 ASSERT_EQ(status, OkStatus());
1177 EXPECT_EQ(uint32.size(), 3u);
1178 EXPECT_EQ(uint32[2], 100u);
1179
1180 EXPECT_EQ(decoder.Next(), OkStatus());
1181 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1182 status = decoder.ReadRepeatedUint32(uint32);
1183 ASSERT_EQ(status, OkStatus());
1184 EXPECT_EQ(uint32.size(), 4u);
1185 EXPECT_EQ(uint32[3], 150u);
1186
1187 EXPECT_EQ(decoder.Next(), OkStatus());
1188 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1189 status = decoder.ReadRepeatedUint32(uint32);
1190 ASSERT_EQ(status, OkStatus());
1191 EXPECT_EQ(uint32.size(), 5u);
1192 EXPECT_EQ(uint32[4], 200u);
1193
1194 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1195 }
1196
TEST(StreamDecoder,RepeatedFieldVectorFull)1197 TEST(StreamDecoder, RepeatedFieldVectorFull) {
1198 // clang-format off
1199 constexpr uint8_t encoded_proto[] = {
1200 // type=uint32, k=1, v=0
1201 0x08, 0x00,
1202 // type=uint32, k=1, v=50
1203 0x08, 0x32,
1204 // type=uint32, k=1, v=100
1205 0x08, 0x64,
1206 // type=uint32, k=1, v=150
1207 0x08, 0x96, 0x01,
1208 // type=uint32, k=1, v=200
1209 0x08, 0xc8, 0x01
1210 };
1211 // clang-format on
1212
1213 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1214 StreamDecoder decoder(reader);
1215
1216 pw::Vector<uint32_t, 2> uint32{};
1217
1218 EXPECT_EQ(decoder.Next(), OkStatus());
1219 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1220 Status status = decoder.ReadRepeatedUint32(uint32);
1221 ASSERT_EQ(status, OkStatus());
1222 EXPECT_EQ(uint32.size(), 1u);
1223 EXPECT_EQ(uint32[0], 0u);
1224
1225 EXPECT_EQ(decoder.Next(), OkStatus());
1226 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1227 status = decoder.ReadRepeatedUint32(uint32);
1228 ASSERT_EQ(status, OkStatus());
1229 EXPECT_EQ(uint32.size(), 2u);
1230 EXPECT_EQ(uint32[1], 50u);
1231
1232 EXPECT_EQ(decoder.Next(), OkStatus());
1233 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1234 status = decoder.ReadRepeatedUint32(uint32);
1235 ASSERT_EQ(status, Status::ResourceExhausted());
1236 EXPECT_EQ(uint32.size(), 2u);
1237 }
1238
TEST(StreamDecoder,PackedVarint)1239 TEST(StreamDecoder, PackedVarint) {
1240 // clang-format off
1241 constexpr uint8_t encoded_proto[] = {
1242 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1243 0x0a, 0x07,
1244 0x00,
1245 0x32,
1246 0x64,
1247 0x96, 0x01,
1248 0xc8, 0x01
1249 };
1250 // clang-format on
1251
1252 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1253 StreamDecoder decoder(reader);
1254
1255 EXPECT_EQ(decoder.Next(), OkStatus());
1256 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1257 std::array<uint32_t, 8> uint32{};
1258 StatusWithSize size = decoder.ReadPackedUint32(uint32);
1259 ASSERT_EQ(size.status(), OkStatus());
1260 EXPECT_EQ(size.size(), 5u);
1261
1262 EXPECT_EQ(uint32[0], 0u);
1263 EXPECT_EQ(uint32[1], 50u);
1264 EXPECT_EQ(uint32[2], 100u);
1265 EXPECT_EQ(uint32[3], 150u);
1266 EXPECT_EQ(uint32[4], 200u);
1267 }
1268
TEST(StreamDecoder,PackedVarintInsufficientSpace)1269 TEST(StreamDecoder, PackedVarintInsufficientSpace) {
1270 // clang-format off
1271 constexpr uint8_t encoded_proto[] = {
1272 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1273 0x0a, 0x07,
1274 0x00,
1275 0x32,
1276 0x64,
1277 0x96, 0x01,
1278 0xc8, 0x01
1279 };
1280 // clang-format on
1281
1282 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1283 StreamDecoder decoder(reader);
1284
1285 EXPECT_EQ(decoder.Next(), OkStatus());
1286 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1287 std::array<uint32_t, 2> uint32{};
1288 StatusWithSize size = decoder.ReadPackedUint32(uint32);
1289 ASSERT_EQ(size.status(), Status::ResourceExhausted());
1290 EXPECT_EQ(size.size(), 2u);
1291
1292 // Still returns values in case of error.
1293 EXPECT_EQ(uint32[0], 0u);
1294 EXPECT_EQ(uint32[1], 50u);
1295 }
1296
TEST(StreamDecoder,PackedVarintVector)1297 TEST(StreamDecoder, PackedVarintVector) {
1298 // clang-format off
1299 constexpr uint8_t encoded_proto[] = {
1300 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1301 0x0a, 0x07,
1302 0x00,
1303 0x32,
1304 0x64,
1305 0x96, 0x01,
1306 0xc8, 0x01
1307 };
1308 // clang-format on
1309
1310 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1311 StreamDecoder decoder(reader);
1312
1313 EXPECT_EQ(decoder.Next(), OkStatus());
1314 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1315 pw::Vector<uint32_t, 8> uint32{};
1316 Status status = decoder.ReadRepeatedUint32(uint32);
1317 ASSERT_EQ(status, OkStatus());
1318 EXPECT_EQ(uint32.size(), 5u);
1319
1320 EXPECT_EQ(uint32[0], 0u);
1321 EXPECT_EQ(uint32[1], 50u);
1322 EXPECT_EQ(uint32[2], 100u);
1323 EXPECT_EQ(uint32[3], 150u);
1324 EXPECT_EQ(uint32[4], 200u);
1325 }
1326
TEST(StreamDecoder,PackedVarintVectorFull)1327 TEST(StreamDecoder, PackedVarintVectorFull) {
1328 // clang-format off
1329 constexpr uint8_t encoded_proto[] = {
1330 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1331 0x0a, 0x07,
1332 0x00,
1333 0x32,
1334 0x64,
1335 0x96, 0x01,
1336 0xc8, 0x01
1337 };
1338 // clang-format on
1339
1340 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1341 StreamDecoder decoder(reader);
1342
1343 EXPECT_EQ(decoder.Next(), OkStatus());
1344 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1345 pw::Vector<uint32_t, 2> uint32{};
1346 Status status = decoder.ReadRepeatedUint32(uint32);
1347 ASSERT_EQ(status, Status::ResourceExhausted());
1348 EXPECT_EQ(uint32.size(), 2u);
1349
1350 // Still returns values in case of error.
1351 EXPECT_EQ(uint32[0], 0u);
1352 EXPECT_EQ(uint32[1], 50u);
1353 }
1354
TEST(StreamDecoder,PackedZigZag)1355 TEST(StreamDecoder, PackedZigZag) {
1356 // clang-format off
1357 constexpr uint8_t encoded_proto[] = {
1358 // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1359 0x0a, 0x09,
1360 0xc7, 0x01,
1361 0x31,
1362 0x01,
1363 0x00,
1364 0x02,
1365 0x32,
1366 0xc8, 0x01
1367 };
1368 // clang-format on
1369
1370 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1371 StreamDecoder decoder(reader);
1372
1373 EXPECT_EQ(decoder.Next(), OkStatus());
1374 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1375 std::array<int32_t, 8> sint32{};
1376 StatusWithSize size = decoder.ReadPackedSint32(sint32);
1377 ASSERT_EQ(size.status(), OkStatus());
1378 EXPECT_EQ(size.size(), 7u);
1379
1380 EXPECT_EQ(sint32[0], -100);
1381 EXPECT_EQ(sint32[1], -25);
1382 EXPECT_EQ(sint32[2], -1);
1383 EXPECT_EQ(sint32[3], 0);
1384 EXPECT_EQ(sint32[4], 1);
1385 EXPECT_EQ(sint32[5], 25);
1386 EXPECT_EQ(sint32[6], 100);
1387 }
1388
TEST(StreamDecoder,PackedZigZagVector)1389 TEST(StreamDecoder, PackedZigZagVector) {
1390 // clang-format off
1391 constexpr uint8_t encoded_proto[] = {
1392 // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1393 0x0a, 0x09,
1394 0xc7, 0x01,
1395 0x31,
1396 0x01,
1397 0x00,
1398 0x02,
1399 0x32,
1400 0xc8, 0x01
1401 };
1402 // clang-format on
1403
1404 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1405 StreamDecoder decoder(reader);
1406
1407 EXPECT_EQ(decoder.Next(), OkStatus());
1408 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1409 pw::Vector<int32_t, 8> sint32{};
1410 Status status = decoder.ReadRepeatedSint32(sint32);
1411 ASSERT_EQ(status, OkStatus());
1412 EXPECT_EQ(sint32.size(), 7u);
1413
1414 EXPECT_EQ(sint32[0], -100);
1415 EXPECT_EQ(sint32[1], -25);
1416 EXPECT_EQ(sint32[2], -1);
1417 EXPECT_EQ(sint32[3], 0);
1418 EXPECT_EQ(sint32[4], 1);
1419 EXPECT_EQ(sint32[5], 25);
1420 EXPECT_EQ(sint32[6], 100);
1421 }
1422
TEST(StreamDecoder,PackedFixed)1423 TEST(StreamDecoder, PackedFixed) {
1424 // clang-format off
1425 constexpr uint8_t encoded_proto[] = {
1426 // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1427 0x0a, 0x14,
1428 0x00, 0x00, 0x00, 0x00,
1429 0x32, 0x00, 0x00, 0x00,
1430 0x64, 0x00, 0x00, 0x00,
1431 0x96, 0x00, 0x00, 0x00,
1432 0xc8, 0x00, 0x00, 0x00,
1433 // type=fixed64[], v=2, v={0x0102030405060708}
1434 0x12, 0x08,
1435 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
1436 // type=sfixed32[], k=3, v={0, -50, 100, -150, 200}
1437 0x1a, 0x14,
1438 0x00, 0x00, 0x00, 0x00,
1439 0xce, 0xff, 0xff, 0xff,
1440 0x64, 0x00, 0x00, 0x00,
1441 0x6a, 0xff, 0xff, 0xff,
1442 0xc8, 0x00, 0x00, 0x00,
1443 // type=sfixed64[], v=4, v={-1647993274}
1444 0x22, 0x08,
1445 0x46, 0x9e, 0xc5, 0x9d, 0xff, 0xff, 0xff, 0xff,
1446 // type=double[], k=5, v=3.14159
1447 0x2a, 0x08,
1448 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
1449 // type=float[], k=6, v=2.718
1450 0x32, 0x04,
1451 0xb6, 0xf3, 0x2d, 0x40,
1452 };
1453 // clang-format on
1454
1455 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1456 StreamDecoder decoder(reader);
1457
1458 EXPECT_EQ(decoder.Next(), OkStatus());
1459 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1460 std::array<uint32_t, 8> fixed32{};
1461 StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1462 ASSERT_EQ(size.status(), OkStatus());
1463 EXPECT_EQ(size.size(), 5u);
1464
1465 EXPECT_EQ(fixed32[0], 0u);
1466 EXPECT_EQ(fixed32[1], 50u);
1467 EXPECT_EQ(fixed32[2], 100u);
1468 EXPECT_EQ(fixed32[3], 150u);
1469 EXPECT_EQ(fixed32[4], 200u);
1470
1471 EXPECT_EQ(decoder.Next(), OkStatus());
1472 ASSERT_EQ(decoder.FieldNumber().value(), 2u);
1473 std::array<uint64_t, 8> fixed64{};
1474 size = decoder.ReadPackedFixed64(fixed64);
1475 ASSERT_EQ(size.status(), OkStatus());
1476 EXPECT_EQ(size.size(), 1u);
1477
1478 EXPECT_EQ(fixed64[0], 0x0102030405060708u);
1479
1480 EXPECT_EQ(decoder.Next(), OkStatus());
1481 ASSERT_EQ(decoder.FieldNumber().value(), 3u);
1482 std::array<int32_t, 8> sfixed32{};
1483 size = decoder.ReadPackedSfixed32(sfixed32);
1484 ASSERT_EQ(size.status(), OkStatus());
1485 EXPECT_EQ(size.size(), 5u);
1486
1487 EXPECT_EQ(sfixed32[0], 0);
1488 EXPECT_EQ(sfixed32[1], -50);
1489 EXPECT_EQ(sfixed32[2], 100);
1490 EXPECT_EQ(sfixed32[3], -150);
1491 EXPECT_EQ(sfixed32[4], 200);
1492
1493 EXPECT_EQ(decoder.Next(), OkStatus());
1494 ASSERT_EQ(decoder.FieldNumber().value(), 4u);
1495 std::array<int64_t, 8> sfixed64{};
1496 size = decoder.ReadPackedSfixed64(sfixed64);
1497 ASSERT_EQ(size.status(), OkStatus());
1498 EXPECT_EQ(size.size(), 1u);
1499
1500 EXPECT_EQ(sfixed64[0], -1647993274);
1501
1502 EXPECT_EQ(decoder.Next(), OkStatus());
1503 ASSERT_EQ(decoder.FieldNumber().value(), 5u);
1504 std::array<double, 8> dbl{};
1505 size = decoder.ReadPackedDouble(dbl);
1506 ASSERT_EQ(size.status(), OkStatus());
1507 EXPECT_EQ(size.size(), 1u);
1508
1509 EXPECT_EQ(dbl[0], 3.14159);
1510
1511 EXPECT_EQ(decoder.Next(), OkStatus());
1512 ASSERT_EQ(decoder.FieldNumber().value(), 6u);
1513 std::array<float, 8> flt{};
1514 size = decoder.ReadPackedFloat(flt);
1515 ASSERT_EQ(size.status(), OkStatus());
1516 EXPECT_EQ(size.size(), 1u);
1517
1518 EXPECT_EQ(flt[0], 2.718f);
1519
1520 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1521 }
1522
TEST(StreamDecoder,PackedFixedInsufficientSpace)1523 TEST(StreamDecoder, PackedFixedInsufficientSpace) {
1524 // clang-format off
1525 constexpr uint8_t encoded_proto[] = {
1526 // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1527 0x0a, 0x14,
1528 0x00, 0x00, 0x00, 0x00,
1529 0x32, 0x00, 0x00, 0x00,
1530 0x64, 0x00, 0x00, 0x00,
1531 0x96, 0x00, 0x00, 0x00,
1532 0xc8, 0x00, 0x00, 0x00,
1533 };
1534 // clang-format on
1535
1536 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1537 StreamDecoder decoder(reader);
1538
1539 EXPECT_EQ(decoder.Next(), OkStatus());
1540 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1541 std::array<uint32_t, 2> fixed32{};
1542 StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1543 ASSERT_EQ(size.status(), Status::ResourceExhausted());
1544 }
1545
TEST(StreamDecoder,PackedFixedVector)1546 TEST(StreamDecoder, PackedFixedVector) {
1547 // clang-format off
1548 constexpr uint8_t encoded_proto[] = {
1549 // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1550 0x0a, 0x14,
1551 0x00, 0x00, 0x00, 0x00,
1552 0xce, 0xff, 0xff, 0xff,
1553 0x64, 0x00, 0x00, 0x00,
1554 0x6a, 0xff, 0xff, 0xff,
1555 0xc8, 0x00, 0x00, 0x00,
1556 };
1557 // clang-format on
1558
1559 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1560 StreamDecoder decoder(reader);
1561
1562 EXPECT_EQ(decoder.Next(), OkStatus());
1563 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1564 pw::Vector<int32_t, 8> sfixed32{};
1565 Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1566 ASSERT_EQ(status, OkStatus());
1567 EXPECT_EQ(sfixed32.size(), 5u);
1568
1569 EXPECT_EQ(sfixed32[0], 0);
1570 EXPECT_EQ(sfixed32[1], -50);
1571 EXPECT_EQ(sfixed32[2], 100);
1572 EXPECT_EQ(sfixed32[3], -150);
1573 EXPECT_EQ(sfixed32[4], 200);
1574
1575 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1576 }
1577
TEST(StreamDecoder,PackedFixedVectorFull)1578 TEST(StreamDecoder, PackedFixedVectorFull) {
1579 // clang-format off
1580 constexpr uint8_t encoded_proto[] = {
1581 // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1582 0x0a, 0x14,
1583 0x00, 0x00, 0x00, 0x00,
1584 0xce, 0xff, 0xff, 0xff,
1585 0x64, 0x00, 0x00, 0x00,
1586 0x6a, 0xff, 0xff, 0xff,
1587 0xc8, 0x00, 0x00, 0x00,
1588 };
1589 // clang-format on
1590
1591 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1592 StreamDecoder decoder(reader);
1593
1594 EXPECT_EQ(decoder.Next(), OkStatus());
1595 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1596 pw::Vector<int32_t, 2> sfixed32{};
1597 Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1598 ASSERT_EQ(status, Status::ResourceExhausted());
1599 EXPECT_EQ(sfixed32.size(), 0u);
1600 }
1601
1602 } // namespace
1603 } // namespace pw::protobuf
1604