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 "pw_status/status.h"
20 #include "pw_status/status_with_size.h"
21 #include "pw_stream/memory_stream.h"
22 #include "pw_stream/stream.h"
23 #include "pw_unit_test/framework.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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 static constexpr const 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 {
412 StreamDecoder nested = decoder.GetNestedDecoder();
413 }
414
415 // The root decoder should still advance to the next field after the nested
416 // decoder is closed.
417 EXPECT_EQ(decoder.Next(), OkStatus());
418 ASSERT_EQ(*decoder.FieldNumber(), 2u);
419
420 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
421 }
422
TEST(StreamDecoder,Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction)423 TEST(StreamDecoder,
424 Decode_Nested_NonSeekable_AdvancesToNextFieldOnDestruction) {
425 // clang-format off
426 static constexpr const uint8_t encoded_proto[] = {
427 // type=int32, k=1, v=42
428 0x08, 0x2a,
429
430 // Submessage (bytes) key=8, length=4
431 0x32, 0x04,
432 // type=uint32, k=1, v=2
433 0x08, 0x02,
434 // type=uint32, k=2, v=7
435 0x10, 0x07,
436 // End submessage
437
438 // type=sint32, k=2, v=-13
439 0x10, 0x19,
440 };
441 // clang-format on
442
443 // Test with a non-seekable memory reader
444 stream::MemoryReader wrapped_reader(as_bytes(span(encoded_proto)));
445 NonSeekableMemoryReader reader(wrapped_reader);
446 StreamDecoder decoder(reader);
447
448 EXPECT_EQ(decoder.Next(), OkStatus());
449 ASSERT_EQ(*decoder.FieldNumber(), 1u);
450
451 // Create a nested encoder for the nested field, but don't use it.
452 EXPECT_EQ(decoder.Next(), OkStatus());
453 ASSERT_EQ(*decoder.FieldNumber(), 6u);
454 {
455 StreamDecoder nested = decoder.GetNestedDecoder();
456 }
457
458 // The root decoder should still advance to the next field after the nested
459 // decoder is closed.
460 EXPECT_EQ(decoder.Next(), OkStatus());
461 ASSERT_EQ(*decoder.FieldNumber(), 2u);
462
463 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
464 }
465
TEST(StreamDecoder,Decode_Nested_LastField)466 TEST(StreamDecoder, Decode_Nested_LastField) {
467 // clang-format off
468 static constexpr const uint8_t encoded_proto[] = {
469 // type=int32, k=1, v=42
470 0x08, 0x2a,
471
472 // Submessage (bytes) key=8, length=4
473 0x32, 0x04,
474 // type=uint32, k=1, v=2
475 0x08, 0x02,
476 // type=uint32, k=2, v=7
477 0x10, 0x07,
478 // End submessage and proto
479 };
480 // clang-format on
481
482 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
483 StreamDecoder decoder(reader);
484
485 EXPECT_EQ(decoder.Next(), OkStatus());
486 ASSERT_EQ(*decoder.FieldNumber(), 1u);
487
488 // Create a nested encoder for the nested field, which is the last field in
489 // the root proto.
490 EXPECT_EQ(decoder.Next(), OkStatus());
491 ASSERT_EQ(*decoder.FieldNumber(), 6u);
492 {
493 StreamDecoder nested = decoder.GetNestedDecoder();
494 }
495
496 // Root decoder should correctly terminate after the nested decoder is closed.
497 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
498 }
499
TEST(StreamDecoder,Decode_Nested_MultiLevel)500 TEST(StreamDecoder, Decode_Nested_MultiLevel) {
501 // clang-format off
502 static constexpr const uint8_t encoded_proto[] = {
503 // Submessage key=1, length=4
504 0x0a, 0x04,
505
506 // Sub-submessage key=1, length=2
507 0x0a, 0x02,
508 // type=uint32, k=2, v=7
509 0x10, 0x07,
510 // End sub-submessage
511
512 // End submessage
513 };
514 // clang-format on
515
516 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
517 StreamDecoder decoder(reader);
518
519 EXPECT_EQ(decoder.Next(), OkStatus());
520 ASSERT_EQ(*decoder.FieldNumber(), 1u);
521 {
522 StreamDecoder nested = decoder.GetNestedDecoder();
523
524 EXPECT_EQ(nested.Next(), OkStatus());
525 ASSERT_EQ(*nested.FieldNumber(), 1u);
526
527 {
528 StreamDecoder double_nested = nested.GetNestedDecoder();
529
530 EXPECT_EQ(double_nested.Next(), OkStatus());
531 ASSERT_EQ(*double_nested.FieldNumber(), 2u);
532 Result<uint32_t> result = double_nested.ReadUint32();
533 ASSERT_EQ(result.status(), OkStatus());
534 EXPECT_EQ(result.value(), 7u);
535
536 EXPECT_EQ(double_nested.Next(), Status::OutOfRange());
537 }
538
539 EXPECT_EQ(nested.Next(), Status::OutOfRange());
540 }
541
542 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
543 }
544
TEST(StreamDecoder,Decode_Nested_InvalidField)545 TEST(StreamDecoder, Decode_Nested_InvalidField) {
546 // clang-format off
547 static constexpr const uint8_t encoded_proto[] = {
548 // Submessage key=1, length=4
549 0x0a, 0x04,
550
551 // Oops. No data!
552 };
553
554 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
555 StreamDecoder decoder(reader);
556
557 EXPECT_EQ(decoder.Next(), OkStatus());
558 ASSERT_EQ(*decoder.FieldNumber(), 1u);
559 {
560 StreamDecoder nested = decoder.GetNestedDecoder();
561 EXPECT_EQ(nested.Next(), Status::DataLoss());
562 }
563
564 EXPECT_EQ(decoder.Next(), Status::DataLoss());
565 }
566
TEST(StreamDecoder,Decode_Nested_InvalidFieldKey)567 TEST(StreamDecoder, Decode_Nested_InvalidFieldKey) {
568 // clang-format off
569 static constexpr const uint8_t encoded_proto[] = {
570 // Submessage key=1, length=2
571 0x0a, 0x02,
572 // type=invalid...
573 0xff, 0xff,
574 // End submessage
575
576 // type=sint32, k=2, v=-13
577 0x10, 0x19,
578 };
579 // clang-format on
580
581 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
582 StreamDecoder decoder(reader);
583
584 EXPECT_EQ(decoder.Next(), OkStatus());
585 ASSERT_EQ(*decoder.FieldNumber(), 1u);
586
587 {
588 StreamDecoder nested = decoder.GetNestedDecoder();
589 EXPECT_EQ(nested.Next(), Status::DataLoss());
590
591 // Make sure that the nested decoder didn't run off the end of the
592 // submessage.
593 ASSERT_EQ(reader.Tell(), 4u);
594 }
595 }
596
TEST(StreamDecoder,Decode_Nested_MissingDelimitedLength)597 TEST(StreamDecoder, Decode_Nested_MissingDelimitedLength) {
598 // clang-format off
599 static constexpr const uint8_t encoded_proto[] = {
600 // Submessage key=1, length=1
601 0x0a, 0x01,
602 // Delimited field (bytes) key=1, length=missing...
603 0x0a,
604 // End submessage
605
606 // type=sint32, k=2, v=-13
607 0x10, 0x19,
608 };
609 // clang-format on
610
611 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
612 StreamDecoder decoder(reader);
613
614 EXPECT_EQ(decoder.Next(), OkStatus());
615 ASSERT_EQ(*decoder.FieldNumber(), 1u);
616
617 {
618 StreamDecoder nested = decoder.GetNestedDecoder();
619 EXPECT_EQ(nested.Next(), Status::DataLoss());
620
621 // Make sure that the nested decoder didn't run off the end of the
622 // submessage.
623 ASSERT_EQ(reader.Tell(), 3u);
624 }
625 }
626
TEST(StreamDecoder,Decode_Nested_InvalidDelimitedLength)627 TEST(StreamDecoder, Decode_Nested_InvalidDelimitedLength) {
628 // clang-format off
629 static constexpr const uint8_t encoded_proto[] = {
630 // Submessage key=1, length=2
631 0x0a, 0x02,
632 // Delimited field (bytes) key=1, length=invalid...
633 0x0a, 0xff,
634 // End submessage
635
636 // type=sint32, k=2, v=-13
637 0x10, 0x19,
638 };
639 // clang-format on
640
641 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
642 StreamDecoder decoder(reader);
643
644 EXPECT_EQ(decoder.Next(), OkStatus());
645 ASSERT_EQ(*decoder.FieldNumber(), 1u);
646
647 {
648 StreamDecoder nested = decoder.GetNestedDecoder();
649 EXPECT_EQ(nested.Next(), Status::DataLoss());
650
651 // Make sure that the nested decoder didn't run off the end of the
652 // submessage.
653 ASSERT_EQ(reader.Tell(), 4u);
654 }
655 }
656
TEST(StreamDecoder,Decode_Nested_InvalidVarint)657 TEST(StreamDecoder, Decode_Nested_InvalidVarint) {
658 // clang-format off
659 static constexpr const uint8_t encoded_proto[] = {
660 // Submessage key=1, length=2
661 0x0a, 0x02,
662 // type=uint32 key=1, value=invalid...
663 0x08, 0xff,
664 // End submessage
665
666 // type=sint32, k=2, v=-13
667 0x10, 0x19,
668 };
669 // clang-format on
670
671 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
672 StreamDecoder decoder(reader);
673
674 EXPECT_EQ(decoder.Next(), OkStatus());
675 ASSERT_EQ(*decoder.FieldNumber(), 1u);
676
677 {
678 StreamDecoder nested = decoder.GetNestedDecoder();
679 EXPECT_EQ(nested.Next(), OkStatus());
680 ASSERT_EQ(*nested.FieldNumber(), 1u);
681
682 Result<uint32_t> uint32 = nested.ReadUint32();
683 EXPECT_EQ(uint32.status(), Status::DataLoss());
684
685 // Make sure that the nested decoder didn't run off the end of the
686 // submessage.
687 ASSERT_EQ(reader.Tell(), 4u);
688 }
689 }
690
TEST(StreamDecoder,Decode_Nested_SkipInvalidVarint)691 TEST(StreamDecoder, Decode_Nested_SkipInvalidVarint) {
692 // clang-format off
693 static constexpr const uint8_t encoded_proto[] = {
694 // Submessage key=1, length=2
695 0x0a, 0x02,
696 // type=uint32 key=1, value=invalid...
697 0x08, 0xff,
698 // End submessage
699
700 // type=sint32, k=2, v=-13
701 0x10, 0x19,
702 };
703 // clang-format on
704
705 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
706 StreamDecoder decoder(reader);
707
708 EXPECT_EQ(decoder.Next(), OkStatus());
709 ASSERT_EQ(*decoder.FieldNumber(), 1u);
710
711 {
712 StreamDecoder nested = decoder.GetNestedDecoder();
713 EXPECT_EQ(nested.Next(), OkStatus());
714 ASSERT_EQ(*nested.FieldNumber(), 1u);
715
716 // Skip without reading.
717 EXPECT_EQ(nested.Next(), Status::DataLoss());
718
719 // Make sure that the nested decoder didn't run off the end of the
720 // submessage.
721 ASSERT_EQ(reader.Tell(), 4u);
722 }
723 }
724
TEST(StreamDecoder,Decode_Nested_TruncatedFixed)725 TEST(StreamDecoder, Decode_Nested_TruncatedFixed) {
726 // clang-format off
727 static constexpr const uint8_t encoded_proto[] = {
728 // Submessage key=1, length=2
729 0x0a, 0x03,
730 // type=fixed32 key=1, value=truncated...
731 0x0d, 0x42, 0x00,
732 // End submessage
733
734 // type=sint32, k=2, v=-13
735 0x10, 0x19,
736 };
737 // clang-format on
738
739 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
740 StreamDecoder decoder(reader);
741
742 EXPECT_EQ(decoder.Next(), OkStatus());
743 ASSERT_EQ(*decoder.FieldNumber(), 1u);
744
745 {
746 StreamDecoder nested = decoder.GetNestedDecoder();
747 EXPECT_EQ(nested.Next(), OkStatus());
748 ASSERT_EQ(*nested.FieldNumber(), 1u);
749
750 Result<uint32_t> uint32 = nested.ReadFixed32();
751 EXPECT_EQ(uint32.status(), Status::DataLoss());
752
753 // Make sure that the nested decoder didn't run off the end of the
754 // submessage. Note that this will not read the data at all in this case.
755 ASSERT_EQ(reader.Tell(), 3u);
756 }
757 }
758
TEST(StreamDecoder,Decode_Nested_SkipTruncatedFixed)759 TEST(StreamDecoder, Decode_Nested_SkipTruncatedFixed) {
760 // clang-format off
761 static constexpr const uint8_t encoded_proto[] = {
762 // Submessage key=1, length=2
763 0x0a, 0x03,
764 // type=fixed32 key=1, value=truncated...
765 0x0d, 0x42, 0x00,
766 // End submessage
767
768 // type=sint32, k=2, v=-13
769 0x10, 0x19,
770 };
771 // clang-format on
772
773 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
774 StreamDecoder decoder(reader);
775
776 EXPECT_EQ(decoder.Next(), OkStatus());
777 ASSERT_EQ(*decoder.FieldNumber(), 1u);
778
779 {
780 StreamDecoder nested = decoder.GetNestedDecoder();
781 EXPECT_EQ(nested.Next(), OkStatus());
782 ASSERT_EQ(*nested.FieldNumber(), 1u);
783
784 // Skip without reading.
785 EXPECT_EQ(nested.Next(), Status::DataLoss());
786
787 // Make sure that the nested decoder didn't run off the end of the
788 // submessage. Note that this will be unable to skip the field without
789 // exceeding the range of the nested decoder, so it won't move the cursor.
790 ASSERT_EQ(reader.Tell(), 3u);
791 }
792 }
793
TEST(StreamDecoder,Decode_BytesReader)794 TEST(StreamDecoder, Decode_BytesReader) {
795 // clang-format off
796 constexpr uint8_t encoded_proto[] = {
797 // bytes key=1, length=14
798 0x0a, 0x0e,
799
800 0x00, 0x01, 0x02, 0x03,
801 0x04, 0x05, 0x06, 0x07,
802 0x08, 0x09, 0x0a, 0x0b,
803 0x0c, 0x0d,
804 };
805 // clang-format on
806
807 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
808 StreamDecoder decoder(reader);
809
810 EXPECT_EQ(decoder.Next(), OkStatus());
811 EXPECT_EQ(*decoder.FieldNumber(), 1u);
812 {
813 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
814 EXPECT_EQ(bytes.field_size(), 14u);
815
816 std::byte buffer[7];
817 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
818 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
819
820 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
821 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 9, sizeof(buffer)), 0);
822
823 EXPECT_EQ(bytes.Read(buffer).status(), Status::OutOfRange());
824 }
825
826 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
827 }
828
TEST(StreamDecoder,Decode_BytesReader_Seek)829 TEST(StreamDecoder, Decode_BytesReader_Seek) {
830 // clang-format off
831 constexpr uint8_t encoded_proto[] = {
832 // bytes key=1, length=14
833 0x0a, 0x0e,
834
835 0x00, 0x01, 0x02, 0x03,
836 0x04, 0x05, 0x06, 0x07,
837 0x08, 0x09, 0x0a, 0x0b,
838 0x0c, 0x0d,
839 };
840 // clang-format on
841
842 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
843 StreamDecoder decoder(reader);
844
845 EXPECT_EQ(decoder.Next(), OkStatus());
846 EXPECT_EQ(*decoder.FieldNumber(), 1u);
847 {
848 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
849
850 std::byte buffer[2];
851
852 ASSERT_EQ(bytes.Seek(3), OkStatus());
853
854 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
855 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 5, sizeof(buffer)), 0);
856
857 // Bad seek offset (absolute).
858 ASSERT_EQ(bytes.Seek(15), Status::OutOfRange());
859
860 // Seek back from current position.
861 ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), OkStatus());
862
863 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
864 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 3, sizeof(buffer)), 0);
865
866 // Bad seek offset (relative).
867 ASSERT_EQ(bytes.Seek(-4, stream::Stream::kCurrent), Status::OutOfRange());
868
869 // Seek from the end of the bytes field.
870 ASSERT_EQ(bytes.Seek(-2, stream::Stream::kEnd), OkStatus());
871
872 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
873 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 14, sizeof(buffer)), 0);
874
875 // Bad seek offset (end).
876 ASSERT_EQ(bytes.Seek(-15, stream::Stream::kEnd), Status::OutOfRange());
877 }
878
879 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
880 }
881
TEST(StreamDecoder,Decode_BytesReader_Close)882 TEST(StreamDecoder, Decode_BytesReader_Close) {
883 // clang-format off
884 constexpr uint8_t encoded_proto[] = {
885 // bytes key=1, length=14
886 0x0a, 0x0e,
887
888 0x00, 0x01, 0x02, 0x03,
889 0x04, 0x05, 0x06, 0x07,
890 0x08, 0x09, 0x0a, 0x0b,
891 0x0c, 0x0d,
892 // End bytes
893
894 // type=sint32, k=2, v=-13
895 0x10, 0x19,
896 };
897 // clang-format on
898
899 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
900 StreamDecoder decoder(reader);
901
902 EXPECT_EQ(decoder.Next(), OkStatus());
903 EXPECT_EQ(*decoder.FieldNumber(), 1u);
904 {
905 // Partially consume the bytes field.
906 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
907
908 std::byte buffer[2];
909 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
910 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
911 }
912
913 // Continue reading the top-level message.
914 EXPECT_EQ(decoder.Next(), OkStatus());
915 EXPECT_EQ(*decoder.FieldNumber(), 2u);
916
917 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
918 }
919
TEST(StreamDecoder,Decode_BytesReader_NonSeekable_Close)920 TEST(StreamDecoder, Decode_BytesReader_NonSeekable_Close) {
921 // clang-format off
922 constexpr uint8_t encoded_proto[] = {
923 // bytes key=1, length=14
924 0x0a, 0x0e,
925
926 0x00, 0x01, 0x02, 0x03,
927 0x04, 0x05, 0x06, 0x07,
928 0x08, 0x09, 0x0a, 0x0b,
929 0x0c, 0x0d,
930 // End bytes
931
932 // type=sint32, k=2, v=-13
933 0x10, 0x19,
934 };
935 // clang-format on
936
937 // Test with a non-seekable memory reader
938 stream::MemoryReader wrapped_reader(as_bytes(span(encoded_proto)));
939 NonSeekableMemoryReader reader(wrapped_reader);
940 StreamDecoder decoder(reader);
941
942 EXPECT_EQ(decoder.Next(), OkStatus());
943 EXPECT_EQ(*decoder.FieldNumber(), 1u);
944 {
945 // Partially consume the bytes field.
946 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
947
948 std::byte buffer[2];
949 EXPECT_EQ(bytes.Read(buffer).status(), OkStatus());
950 EXPECT_EQ(std::memcmp(buffer, encoded_proto + 2, sizeof(buffer)), 0);
951 }
952
953 // Continue reading the top-level message.
954 EXPECT_EQ(decoder.Next(), OkStatus());
955 EXPECT_EQ(*decoder.FieldNumber(), 2u);
956
957 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
958 }
959
TEST(StreamDecoder,Decode_BytesReader_InvalidField)960 TEST(StreamDecoder, Decode_BytesReader_InvalidField) {
961 // clang-format off
962 constexpr uint8_t encoded_proto[] = {
963 // bytes key=1, length=4
964 0x0a, 0x04,
965
966 // Oops. No data!
967 };
968
969 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
970 StreamDecoder decoder(reader);
971
972 EXPECT_EQ(decoder.Next(), OkStatus());
973 ASSERT_EQ(*decoder.FieldNumber(), 1u);
974 {
975 StreamDecoder::BytesReader bytes = decoder.GetBytesReader();
976 EXPECT_EQ(bytes.Seek(0), Status::DataLoss());
977
978 std::byte buffer[2];
979 EXPECT_EQ(bytes.Read(buffer).status(), Status::DataLoss());
980 }
981
982 EXPECT_EQ(decoder.Next(), Status::DataLoss());
983 }
984
TEST(StreamDecoder,GetLengthDelimitedPayloadBounds)985 TEST(StreamDecoder, GetLengthDelimitedPayloadBounds) {
986 // clang-format off
987 constexpr uint8_t encoded_proto[] = {
988 // bytes key=1, length=14
989 0x0a, 0x0e,
990
991 0x00, 0x01, 0x02, 0x03,
992 0x04, 0x05, 0x06, 0x07,
993 0x08, 0x09, 0x0a, 0x0b,
994 0x0c, 0x0d,
995 // End bytes
996
997 // type=sint32, k=2, v=-13
998 0x10, 0x19,
999 };
1000 // clang-format on
1001
1002 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1003 StreamDecoder decoder(reader);
1004
1005 ASSERT_EQ(OkStatus(), decoder.Next());
1006 Result<StreamDecoder::Bounds> field_bound =
1007 decoder.GetLengthDelimitedPayloadBounds();
1008 ASSERT_EQ(OkStatus(), field_bound.status());
1009 ASSERT_EQ(field_bound.value().low, 2ULL);
1010 ASSERT_EQ(field_bound.value().high, 16ULL);
1011
1012 ASSERT_EQ(OkStatus(), decoder.Next());
1013 ASSERT_EQ(Status::NotFound(),
1014 decoder.GetLengthDelimitedPayloadBounds().status());
1015 }
1016
TEST(StreamDecoder,ReadDelimitedField_DoesntOverConsume)1017 TEST(StreamDecoder, ReadDelimitedField_DoesntOverConsume) {
1018 // clang-format off
1019 constexpr uint8_t encoded_proto[] = {
1020 // type=string, k=1, v="Hello world"
1021 0x0a, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
1022 // type=int32, k=2, v=42
1023 0x10, 0x2a,
1024 };
1025 // clang-format on
1026
1027 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1028 StreamDecoder decoder(reader);
1029
1030 ASSERT_EQ(OkStatus(), decoder.Next());
1031
1032 // This buffer is much larger than the string.
1033 char buffer[128];
1034 const StatusWithSize size = decoder.ReadString(buffer);
1035 EXPECT_EQ(size.status(), OkStatus());
1036 EXPECT_EQ(size.size(), 11u);
1037
1038 // Make sure we can still read the next field.
1039 ASSERT_EQ(OkStatus(), decoder.Next());
1040 const pw::Result<int32_t> result = decoder.ReadInt32();
1041 EXPECT_EQ(result.status(), OkStatus());
1042 EXPECT_EQ(result.value(), 42);
1043 }
1044
TEST(StreamDecoder,Decode_WithLength)1045 TEST(StreamDecoder, Decode_WithLength) {
1046 // clang-format off
1047 constexpr uint8_t encoded_proto[] = {
1048 // type=int32, k=1, v=42
1049 0x08, 0x2a,
1050 // This field is beyond the range of the protobuf:
1051 // type=sint32, k=2, v=-13
1052 0x10, 0x19,
1053 };
1054 // clang-format on
1055
1056 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1057 StreamDecoder decoder(reader, /*length=*/2u);
1058
1059 EXPECT_EQ(decoder.Next(), OkStatus());
1060 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1061 Result<int32_t> int32 = decoder.ReadInt32();
1062 ASSERT_EQ(int32.status(), OkStatus());
1063 EXPECT_EQ(int32.value(), 42);
1064
1065 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1066 }
1067
TEST(StreamDecoder,Decode_WithLength_SkipsToEnd)1068 TEST(StreamDecoder, Decode_WithLength_SkipsToEnd) {
1069 // clang-format off
1070 constexpr uint8_t encoded_proto[] = {
1071 // type=string, k=1, v="Hello world"
1072 0x08, 0x0b, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd',
1073 // This field is beyond the range of the protobuf:
1074 // type=sint32, k=2, v=-13
1075 0x10, 0x19,
1076 };
1077 // clang-format on
1078
1079 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1080 {
1081 StreamDecoder decoder(reader, /*length=*/13u);
1082
1083 EXPECT_EQ(decoder.Next(), OkStatus());
1084 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1085 // Don't read the value out, or advance further. Destructing the object
1086 // should advance to the end of the length given.
1087 }
1088
1089 EXPECT_EQ(reader.Tell(), 13u);
1090 }
1091
TEST(StreamDecoder,RepeatedField)1092 TEST(StreamDecoder, RepeatedField) {
1093 // clang-format off
1094 constexpr uint8_t encoded_proto[] = {
1095 // type=uint32, k=1, v=0
1096 0x08, 0x00,
1097 // type=uint32, k=1, v=50
1098 0x08, 0x32,
1099 // type=uint32, k=1, v=100
1100 0x08, 0x64,
1101 // type=uint32, k=1, v=150
1102 0x08, 0x96, 0x01,
1103 // type=uint32, k=1, v=200
1104 0x08, 0xc8, 0x01
1105 };
1106 // clang-format on
1107
1108 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1109 StreamDecoder decoder(reader);
1110
1111 EXPECT_EQ(decoder.Next(), OkStatus());
1112 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1113 Result<uint32_t> uint32 = decoder.ReadUint32();
1114 ASSERT_EQ(uint32.status(), OkStatus());
1115 EXPECT_EQ(uint32.value(), 0u);
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(), 50u);
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(), 100u);
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(), 150u);
1134
1135 EXPECT_EQ(decoder.Next(), OkStatus());
1136 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1137 uint32 = decoder.ReadUint32();
1138 ASSERT_EQ(uint32.status(), OkStatus());
1139 EXPECT_EQ(uint32.value(), 200u);
1140
1141 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1142 }
1143
TEST(StreamDecoder,RepeatedFieldVector)1144 TEST(StreamDecoder, RepeatedFieldVector) {
1145 // clang-format off
1146 constexpr uint8_t encoded_proto[] = {
1147 // type=uint32, k=1, v=0
1148 0x08, 0x00,
1149 // type=uint32, k=1, v=50
1150 0x08, 0x32,
1151 // type=uint32, k=1, v=100
1152 0x08, 0x64,
1153 // type=uint32, k=1, v=150
1154 0x08, 0x96, 0x01,
1155 // type=uint32, k=1, v=200
1156 0x08, 0xc8, 0x01
1157 };
1158 // clang-format on
1159
1160 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1161 StreamDecoder decoder(reader);
1162
1163 pw::Vector<uint32_t, 8> uint32{};
1164
1165 EXPECT_EQ(decoder.Next(), OkStatus());
1166 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1167 Status status = decoder.ReadRepeatedUint32(uint32);
1168 ASSERT_EQ(status, OkStatus());
1169 EXPECT_EQ(uint32.size(), 1u);
1170 EXPECT_EQ(uint32[0], 0u);
1171
1172 EXPECT_EQ(decoder.Next(), OkStatus());
1173 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1174 status = decoder.ReadRepeatedUint32(uint32);
1175 ASSERT_EQ(status, OkStatus());
1176 EXPECT_EQ(uint32.size(), 2u);
1177 EXPECT_EQ(uint32[1], 50u);
1178
1179 EXPECT_EQ(decoder.Next(), OkStatus());
1180 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1181 status = decoder.ReadRepeatedUint32(uint32);
1182 ASSERT_EQ(status, OkStatus());
1183 EXPECT_EQ(uint32.size(), 3u);
1184 EXPECT_EQ(uint32[2], 100u);
1185
1186 EXPECT_EQ(decoder.Next(), OkStatus());
1187 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1188 status = decoder.ReadRepeatedUint32(uint32);
1189 ASSERT_EQ(status, OkStatus());
1190 EXPECT_EQ(uint32.size(), 4u);
1191 EXPECT_EQ(uint32[3], 150u);
1192
1193 EXPECT_EQ(decoder.Next(), OkStatus());
1194 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1195 status = decoder.ReadRepeatedUint32(uint32);
1196 ASSERT_EQ(status, OkStatus());
1197 EXPECT_EQ(uint32.size(), 5u);
1198 EXPECT_EQ(uint32[4], 200u);
1199
1200 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1201 }
1202
TEST(StreamDecoder,RepeatedFieldVectorFull)1203 TEST(StreamDecoder, RepeatedFieldVectorFull) {
1204 // clang-format off
1205 constexpr uint8_t encoded_proto[] = {
1206 // type=uint32, k=1, v=0
1207 0x08, 0x00,
1208 // type=uint32, k=1, v=50
1209 0x08, 0x32,
1210 // type=uint32, k=1, v=100
1211 0x08, 0x64,
1212 // type=uint32, k=1, v=150
1213 0x08, 0x96, 0x01,
1214 // type=uint32, k=1, v=200
1215 0x08, 0xc8, 0x01
1216 };
1217 // clang-format on
1218
1219 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1220 StreamDecoder decoder(reader);
1221
1222 pw::Vector<uint32_t, 2> uint32{};
1223
1224 EXPECT_EQ(decoder.Next(), OkStatus());
1225 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1226 Status status = decoder.ReadRepeatedUint32(uint32);
1227 ASSERT_EQ(status, OkStatus());
1228 EXPECT_EQ(uint32.size(), 1u);
1229 EXPECT_EQ(uint32[0], 0u);
1230
1231 EXPECT_EQ(decoder.Next(), OkStatus());
1232 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1233 status = decoder.ReadRepeatedUint32(uint32);
1234 ASSERT_EQ(status, OkStatus());
1235 EXPECT_EQ(uint32.size(), 2u);
1236 EXPECT_EQ(uint32[1], 50u);
1237
1238 EXPECT_EQ(decoder.Next(), OkStatus());
1239 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1240 status = decoder.ReadRepeatedUint32(uint32);
1241 ASSERT_EQ(status, Status::ResourceExhausted());
1242 EXPECT_EQ(uint32.size(), 2u);
1243 }
1244
TEST(StreamDecoder,PackedVarint)1245 TEST(StreamDecoder, PackedVarint) {
1246 // clang-format off
1247 constexpr uint8_t encoded_proto[] = {
1248 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1249 0x0a, 0x07,
1250 0x00,
1251 0x32,
1252 0x64,
1253 0x96, 0x01,
1254 0xc8, 0x01
1255 };
1256 // clang-format on
1257
1258 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1259 StreamDecoder decoder(reader);
1260
1261 EXPECT_EQ(decoder.Next(), OkStatus());
1262 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1263 std::array<uint32_t, 8> uint32{};
1264 StatusWithSize size = decoder.ReadPackedUint32(uint32);
1265 ASSERT_EQ(size.status(), OkStatus());
1266 EXPECT_EQ(size.size(), 5u);
1267
1268 EXPECT_EQ(uint32[0], 0u);
1269 EXPECT_EQ(uint32[1], 50u);
1270 EXPECT_EQ(uint32[2], 100u);
1271 EXPECT_EQ(uint32[3], 150u);
1272 EXPECT_EQ(uint32[4], 200u);
1273 }
1274
TEST(StreamDecoder,PackedVarintInsufficientSpace)1275 TEST(StreamDecoder, PackedVarintInsufficientSpace) {
1276 // clang-format off
1277 constexpr uint8_t encoded_proto[] = {
1278 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1279 0x0a, 0x07,
1280 0x00,
1281 0x32,
1282 0x64,
1283 0x96, 0x01,
1284 0xc8, 0x01
1285 };
1286 // clang-format on
1287
1288 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1289 StreamDecoder decoder(reader);
1290
1291 EXPECT_EQ(decoder.Next(), OkStatus());
1292 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1293 std::array<uint32_t, 2> uint32{};
1294 StatusWithSize size = decoder.ReadPackedUint32(uint32);
1295 ASSERT_EQ(size.status(), Status::ResourceExhausted());
1296 EXPECT_EQ(size.size(), 2u);
1297
1298 // Still returns values in case of error.
1299 EXPECT_EQ(uint32[0], 0u);
1300 EXPECT_EQ(uint32[1], 50u);
1301 }
1302
TEST(StreamDecoder,PackedVarintVector)1303 TEST(StreamDecoder, PackedVarintVector) {
1304 // clang-format off
1305 constexpr uint8_t encoded_proto[] = {
1306 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1307 0x0a, 0x07,
1308 0x00,
1309 0x32,
1310 0x64,
1311 0x96, 0x01,
1312 0xc8, 0x01
1313 };
1314 // clang-format on
1315
1316 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1317 StreamDecoder decoder(reader);
1318
1319 EXPECT_EQ(decoder.Next(), OkStatus());
1320 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1321 pw::Vector<uint32_t, 8> uint32{};
1322 Status status = decoder.ReadRepeatedUint32(uint32);
1323 ASSERT_EQ(status, OkStatus());
1324 EXPECT_EQ(uint32.size(), 5u);
1325
1326 EXPECT_EQ(uint32[0], 0u);
1327 EXPECT_EQ(uint32[1], 50u);
1328 EXPECT_EQ(uint32[2], 100u);
1329 EXPECT_EQ(uint32[3], 150u);
1330 EXPECT_EQ(uint32[4], 200u);
1331 }
1332
TEST(StreamDecoder,PackedVarintVectorFull)1333 TEST(StreamDecoder, PackedVarintVectorFull) {
1334 // clang-format off
1335 constexpr uint8_t encoded_proto[] = {
1336 // type=uint32[], k=1, v={0, 50, 100, 150, 200}
1337 0x0a, 0x07,
1338 0x00,
1339 0x32,
1340 0x64,
1341 0x96, 0x01,
1342 0xc8, 0x01
1343 };
1344 // clang-format on
1345
1346 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1347 StreamDecoder decoder(reader);
1348
1349 EXPECT_EQ(decoder.Next(), OkStatus());
1350 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1351 pw::Vector<uint32_t, 2> uint32{};
1352 Status status = decoder.ReadRepeatedUint32(uint32);
1353 ASSERT_EQ(status, Status::ResourceExhausted());
1354 EXPECT_EQ(uint32.size(), 2u);
1355
1356 // Still returns values in case of error.
1357 EXPECT_EQ(uint32[0], 0u);
1358 EXPECT_EQ(uint32[1], 50u);
1359 }
1360
TEST(StreamDecoder,PackedZigZag)1361 TEST(StreamDecoder, PackedZigZag) {
1362 // clang-format off
1363 constexpr uint8_t encoded_proto[] = {
1364 // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1365 0x0a, 0x09,
1366 0xc7, 0x01,
1367 0x31,
1368 0x01,
1369 0x00,
1370 0x02,
1371 0x32,
1372 0xc8, 0x01
1373 };
1374 // clang-format on
1375
1376 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1377 StreamDecoder decoder(reader);
1378
1379 EXPECT_EQ(decoder.Next(), OkStatus());
1380 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1381 std::array<int32_t, 8> sint32{};
1382 StatusWithSize size = decoder.ReadPackedSint32(sint32);
1383 ASSERT_EQ(size.status(), OkStatus());
1384 EXPECT_EQ(size.size(), 7u);
1385
1386 EXPECT_EQ(sint32[0], -100);
1387 EXPECT_EQ(sint32[1], -25);
1388 EXPECT_EQ(sint32[2], -1);
1389 EXPECT_EQ(sint32[3], 0);
1390 EXPECT_EQ(sint32[4], 1);
1391 EXPECT_EQ(sint32[5], 25);
1392 EXPECT_EQ(sint32[6], 100);
1393 }
1394
TEST(StreamDecoder,PackedZigZagVector)1395 TEST(StreamDecoder, PackedZigZagVector) {
1396 // clang-format off
1397 static constexpr const uint8_t encoded_proto[] = {
1398 // type=sint32[], k=1, v={-100, -25, -1, 0, 1, 25, 100}
1399 0x0a, 0x09,
1400 0xc7, 0x01,
1401 0x31,
1402 0x01,
1403 0x00,
1404 0x02,
1405 0x32,
1406 0xc8, 0x01
1407 };
1408 // clang-format on
1409
1410 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1411 StreamDecoder decoder(reader);
1412
1413 EXPECT_EQ(decoder.Next(), OkStatus());
1414 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1415 pw::Vector<int32_t, 8> sint32{};
1416 Status status = decoder.ReadRepeatedSint32(sint32);
1417 ASSERT_EQ(status, OkStatus());
1418 EXPECT_EQ(sint32.size(), 7u);
1419
1420 EXPECT_EQ(sint32[0], -100);
1421 EXPECT_EQ(sint32[1], -25);
1422 EXPECT_EQ(sint32[2], -1);
1423 EXPECT_EQ(sint32[3], 0);
1424 EXPECT_EQ(sint32[4], 1);
1425 EXPECT_EQ(sint32[5], 25);
1426 EXPECT_EQ(sint32[6], 100);
1427 }
1428
TEST(StreamDecoder,PackedFixed)1429 TEST(StreamDecoder, PackedFixed) {
1430 // clang-format off
1431 static constexpr const uint8_t encoded_proto[] = {
1432 // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1433 0x0a, 0x14,
1434 0x00, 0x00, 0x00, 0x00,
1435 0x32, 0x00, 0x00, 0x00,
1436 0x64, 0x00, 0x00, 0x00,
1437 0x96, 0x00, 0x00, 0x00,
1438 0xc8, 0x00, 0x00, 0x00,
1439 // type=fixed64[], v=2, v={0x0102030405060708}
1440 0x12, 0x08,
1441 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
1442 // type=sfixed32[], k=3, v={0, -50, 100, -150, 200}
1443 0x1a, 0x14,
1444 0x00, 0x00, 0x00, 0x00,
1445 0xce, 0xff, 0xff, 0xff,
1446 0x64, 0x00, 0x00, 0x00,
1447 0x6a, 0xff, 0xff, 0xff,
1448 0xc8, 0x00, 0x00, 0x00,
1449 // type=sfixed64[], v=4, v={-1647993274}
1450 0x22, 0x08,
1451 0x46, 0x9e, 0xc5, 0x9d, 0xff, 0xff, 0xff, 0xff,
1452 // type=double[], k=5, v=3.14159
1453 0x2a, 0x08,
1454 0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40,
1455 // type=float[], k=6, v=2.718
1456 0x32, 0x04,
1457 0xb6, 0xf3, 0x2d, 0x40,
1458 };
1459 // clang-format on
1460
1461 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1462 StreamDecoder decoder(reader);
1463
1464 EXPECT_EQ(decoder.Next(), OkStatus());
1465 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1466 std::array<uint32_t, 8> fixed32{};
1467 StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1468 ASSERT_EQ(size.status(), OkStatus());
1469 EXPECT_EQ(size.size(), 5u);
1470
1471 EXPECT_EQ(fixed32[0], 0u);
1472 EXPECT_EQ(fixed32[1], 50u);
1473 EXPECT_EQ(fixed32[2], 100u);
1474 EXPECT_EQ(fixed32[3], 150u);
1475 EXPECT_EQ(fixed32[4], 200u);
1476
1477 EXPECT_EQ(decoder.Next(), OkStatus());
1478 ASSERT_EQ(decoder.FieldNumber().value(), 2u);
1479 std::array<uint64_t, 8> fixed64{};
1480 size = decoder.ReadPackedFixed64(fixed64);
1481 ASSERT_EQ(size.status(), OkStatus());
1482 EXPECT_EQ(size.size(), 1u);
1483
1484 EXPECT_EQ(fixed64[0], 0x0102030405060708u);
1485
1486 EXPECT_EQ(decoder.Next(), OkStatus());
1487 ASSERT_EQ(decoder.FieldNumber().value(), 3u);
1488 std::array<int32_t, 8> sfixed32{};
1489 size = decoder.ReadPackedSfixed32(sfixed32);
1490 ASSERT_EQ(size.status(), OkStatus());
1491 EXPECT_EQ(size.size(), 5u);
1492
1493 EXPECT_EQ(sfixed32[0], 0);
1494 EXPECT_EQ(sfixed32[1], -50);
1495 EXPECT_EQ(sfixed32[2], 100);
1496 EXPECT_EQ(sfixed32[3], -150);
1497 EXPECT_EQ(sfixed32[4], 200);
1498
1499 EXPECT_EQ(decoder.Next(), OkStatus());
1500 ASSERT_EQ(decoder.FieldNumber().value(), 4u);
1501 std::array<int64_t, 8> sfixed64{};
1502 size = decoder.ReadPackedSfixed64(sfixed64);
1503 ASSERT_EQ(size.status(), OkStatus());
1504 EXPECT_EQ(size.size(), 1u);
1505
1506 EXPECT_EQ(sfixed64[0], -1647993274);
1507
1508 EXPECT_EQ(decoder.Next(), OkStatus());
1509 ASSERT_EQ(decoder.FieldNumber().value(), 5u);
1510 std::array<double, 8> dbl{};
1511 size = decoder.ReadPackedDouble(dbl);
1512 ASSERT_EQ(size.status(), OkStatus());
1513 EXPECT_EQ(size.size(), 1u);
1514
1515 EXPECT_EQ(dbl[0], 3.14159);
1516
1517 EXPECT_EQ(decoder.Next(), OkStatus());
1518 ASSERT_EQ(decoder.FieldNumber().value(), 6u);
1519 std::array<float, 8> flt{};
1520 size = decoder.ReadPackedFloat(flt);
1521 ASSERT_EQ(size.status(), OkStatus());
1522 EXPECT_EQ(size.size(), 1u);
1523
1524 EXPECT_EQ(flt[0], 2.718f);
1525
1526 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1527 }
1528
TEST(StreamDecoder,PackedFixedInsufficientSpace)1529 TEST(StreamDecoder, PackedFixedInsufficientSpace) {
1530 // clang-format off
1531 static constexpr const uint8_t encoded_proto[] = {
1532 // type=fixed32[], k=1, v={0, 50, 100, 150, 200}
1533 0x0a, 0x14,
1534 0x00, 0x00, 0x00, 0x00,
1535 0x32, 0x00, 0x00, 0x00,
1536 0x64, 0x00, 0x00, 0x00,
1537 0x96, 0x00, 0x00, 0x00,
1538 0xc8, 0x00, 0x00, 0x00,
1539 };
1540 // clang-format on
1541
1542 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1543 StreamDecoder decoder(reader);
1544
1545 EXPECT_EQ(decoder.Next(), OkStatus());
1546 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1547 std::array<uint32_t, 2> fixed32{};
1548 StatusWithSize size = decoder.ReadPackedFixed32(fixed32);
1549 ASSERT_EQ(size.status(), Status::ResourceExhausted());
1550 }
1551
TEST(StreamDecoder,PackedFixedVector)1552 TEST(StreamDecoder, PackedFixedVector) {
1553 // clang-format off
1554 static constexpr const uint8_t encoded_proto[] = {
1555 // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1556 0x0a, 0x14,
1557 0x00, 0x00, 0x00, 0x00,
1558 0xce, 0xff, 0xff, 0xff,
1559 0x64, 0x00, 0x00, 0x00,
1560 0x6a, 0xff, 0xff, 0xff,
1561 0xc8, 0x00, 0x00, 0x00,
1562 };
1563 // clang-format on
1564
1565 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1566 StreamDecoder decoder(reader);
1567
1568 EXPECT_EQ(decoder.Next(), OkStatus());
1569 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1570 pw::Vector<int32_t, 8> sfixed32{};
1571 Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1572 ASSERT_EQ(status, OkStatus());
1573 EXPECT_EQ(sfixed32.size(), 5u);
1574
1575 EXPECT_EQ(sfixed32[0], 0);
1576 EXPECT_EQ(sfixed32[1], -50);
1577 EXPECT_EQ(sfixed32[2], 100);
1578 EXPECT_EQ(sfixed32[3], -150);
1579 EXPECT_EQ(sfixed32[4], 200);
1580
1581 EXPECT_EQ(decoder.Next(), Status::OutOfRange());
1582 }
1583
TEST(StreamDecoder,PackedFixedVectorFull)1584 TEST(StreamDecoder, PackedFixedVectorFull) {
1585 // clang-format off
1586 static constexpr const uint8_t encoded_proto[] = {
1587 // type=sfixed32[], k=1, v={0, -50, 100, -150, 200}
1588 0x0a, 0x14,
1589 0x00, 0x00, 0x00, 0x00,
1590 0xce, 0xff, 0xff, 0xff,
1591 0x64, 0x00, 0x00, 0x00,
1592 0x6a, 0xff, 0xff, 0xff,
1593 0xc8, 0x00, 0x00, 0x00,
1594 };
1595 // clang-format on
1596
1597 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1598 StreamDecoder decoder(reader);
1599
1600 EXPECT_EQ(decoder.Next(), OkStatus());
1601 ASSERT_EQ(decoder.FieldNumber().value(), 1u);
1602 pw::Vector<int32_t, 2> sfixed32{};
1603 Status status = decoder.ReadRepeatedSfixed32(sfixed32);
1604 ASSERT_EQ(status, Status::ResourceExhausted());
1605 EXPECT_EQ(sfixed32.size(), 0u);
1606 }
1607
1608 // See b/314803709.
TEST(StreamDecoder,NestedIncompleteVarint)1609 TEST(StreamDecoder, NestedIncompleteVarint) {
1610 // clang-format off
1611 static constexpr const uint8_t encoded_proto[] = {
1612 0x4a, 0x02, 0x20, 0xff,
1613 };
1614 // clang-format on
1615
1616 stream::MemoryReader reader(as_bytes(span(encoded_proto)));
1617 StreamDecoder decoder(reader);
1618
1619 EXPECT_EQ(decoder.Next(), OkStatus());
1620 StreamDecoder nested_decoder = decoder.GetNestedDecoder();
1621
1622 EXPECT_EQ(nested_decoder.Next(), OkStatus());
1623 EXPECT_EQ(nested_decoder.ReadInt32().status(), Status::DataLoss());
1624 }
1625
1626 } // namespace
1627 } // namespace pw::protobuf
1628