1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <limits>
6 #include <utility>
7 
8 #include "components/cbor/reader.h"
9 
10 #include "base/containers/span.h"
11 #include "base/stl_util.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 /* Leveraging RFC 7049 examples from
16    https://github.com/cbor/test-vectors/blob/master/appendix_a.json. */
17 namespace cbor {
18 
19 namespace {
20 
WithExtraneousData(base::span<const uint8_t> original)21 std::vector<uint8_t> WithExtraneousData(base::span<const uint8_t> original) {
22   std::vector<uint8_t> ret(original.begin(), original.end());
23   // Add a valid one byte long CBOR data item, namely, an unsigned integer
24   // with value "1".
25   ret.push_back(0x01);
26   return ret;
27 }
28 
29 }  // namespace
30 
TEST(CBORReaderTest,TestReadUint)31 TEST(CBORReaderTest, TestReadUint) {
32   struct UintTestCase {
33     const int64_t value;
34     const std::vector<uint8_t> cbor_data;
35   };
36 
37   static const UintTestCase kUintTestCases[] = {
38       {0, {0x00}},
39       {1, {0x01}},
40       {23, {0x17}},
41       {24, {0x18, 0x18}},
42       {std::numeric_limits<uint8_t>::max(), {0x18, 0xff}},
43       {1LL << 8, {0x19, 0x01, 0x00}},
44       {std::numeric_limits<uint16_t>::max(), {0x19, 0xff, 0xff}},
45       {1LL << 16, {0x1a, 0x00, 0x01, 0x00, 0x00}},
46       {std::numeric_limits<uint32_t>::max(), {0x1a, 0xff, 0xff, 0xff, 0xff}},
47       {1LL << 32, {0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
48       {std::numeric_limits<int64_t>::max(),
49        {0x1b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
50   };
51 
52   for (const UintTestCase& test_case : kUintTestCases) {
53     SCOPED_TRACE(testing::Message() << "testing uint: " << test_case.value);
54 
55     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
56     ASSERT_TRUE(cbor.has_value());
57     ASSERT_EQ(cbor.value().type(), Value::Type::UNSIGNED);
58     EXPECT_EQ(cbor.value().GetInteger(), test_case.value);
59 
60     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
61     Reader::DecoderError error_code;
62     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
63     EXPECT_FALSE(cbor.has_value());
64     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
65 
66     size_t num_bytes_consumed;
67     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
68                         &error_code);
69     ASSERT_TRUE(cbor.has_value());
70     ASSERT_EQ(cbor.value().type(), Value::Type::UNSIGNED);
71     EXPECT_EQ(cbor.value().GetInteger(), test_case.value);
72     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
73     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
74   }
75 }
76 
TEST(CBORReaderTest,TestUintEncodedWithNonMinimumByteLength)77 TEST(CBORReaderTest, TestUintEncodedWithNonMinimumByteLength) {
78   static const std::vector<uint8_t> non_minimal_uint_encodings[] = {
79       // Uint 23 encoded with 1 byte.
80       {0x18, 0x17},
81       // Uint 255 encoded with 2 bytes.
82       {0x19, 0x00, 0xff},
83       // Uint 65535 encoded with 4 byte.
84       {0x1a, 0x00, 0x00, 0xff, 0xff},
85       // Uint 4294967295 encoded with 8 byte.
86       {0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
87 
88       // When decoding byte has more than one syntax error, the first syntax
89       // error encountered during deserialization is returned as the error code.
90       {
91           0xa2,        // map with non-minimally encoded key
92           0x17,        // key 24
93           0x61, 0x42,  // value :"B"
94 
95           0x18, 0x17,  // key 23 encoded with extra byte
96           0x61, 0x45   // value "E"
97       },
98       {
99           0xa2,        // map with out of order and non-minimally encoded key
100           0x18, 0x17,  // key 23 encoded with extra byte
101           0x61, 0x45,  // value "E"
102           0x17,        // key 23
103           0x61, 0x42   // value :"B"
104       },
105       {
106           0xa2,        // map with duplicate non-minimally encoded key
107           0x18, 0x17,  // key 23 encoded with extra byte
108           0x61, 0x45,  // value "E"
109           0x18, 0x17,  // key 23 encoded with extra byte
110           0x61, 0x42   // value :"B"
111       },
112   };
113 
114   int test_case_index = 0;
115   Reader::DecoderError error_code;
116   for (const auto& non_minimal_uint : non_minimal_uint_encodings) {
117     SCOPED_TRACE(testing::Message()
118                  << "testing element at index : " << test_case_index++);
119 
120     base::Optional<Value> cbor = Reader::Read(non_minimal_uint, &error_code);
121     EXPECT_FALSE(cbor.has_value());
122     EXPECT_EQ(error_code, Reader::DecoderError::NON_MINIMAL_CBOR_ENCODING);
123   }
124 }
125 
TEST(CBORReaderTest,TestReadNegativeInt)126 TEST(CBORReaderTest, TestReadNegativeInt) {
127   struct NegativeIntTestCase {
128     const int64_t negative_int;
129     const std::vector<uint8_t> cbor_data;
130   };
131 
132   static const NegativeIntTestCase kNegativeIntTestCases[] = {
133       {-1LL, {0x20}},
134       {-24LL, {0x37}},
135       {-25LL, {0x38, 0x18}},
136       {-256LL, {0x38, 0xff}},
137       {-1000LL, {0x39, 0x03, 0xe7}},
138       {-1000000LL, {0x3a, 0x00, 0x0f, 0x42, 0x3f}},
139       {-4294967296LL, {0x3a, 0xff, 0xff, 0xff, 0xff}},
140       {std::numeric_limits<int64_t>::min(),
141        {0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}};
142 
143   for (const NegativeIntTestCase& test_case : kNegativeIntTestCases) {
144     SCOPED_TRACE(testing::Message()
145                  << "testing negative int : " << test_case.negative_int);
146 
147     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
148     ASSERT_TRUE(cbor.has_value());
149     ASSERT_EQ(cbor.value().type(), Value::Type::NEGATIVE);
150     EXPECT_EQ(cbor.value().GetInteger(), test_case.negative_int);
151 
152     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
153     Reader::DecoderError error_code;
154     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
155     EXPECT_FALSE(cbor.has_value());
156     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
157 
158     size_t num_bytes_consumed;
159     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
160                         &error_code);
161     ASSERT_TRUE(cbor.has_value());
162     ASSERT_EQ(cbor.value().type(), Value::Type::NEGATIVE);
163     EXPECT_EQ(cbor.value().GetInteger(), test_case.negative_int);
164     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
165     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
166   }
167 }
168 
TEST(CBORReaderTest,TestReadBytes)169 TEST(CBORReaderTest, TestReadBytes) {
170   struct ByteTestCase {
171     const std::vector<uint8_t> value;
172     const std::vector<uint8_t> cbor_data;
173   };
174 
175   static const ByteTestCase kByteStringTestCases[] = {
176       // clang-format off
177       {{}, {0x40}},
178       {{0x01, 0x02, 0x03, 0x04}, {0x44, 0x01, 0x02, 0x03, 0x04}},
179       // clang-format on
180   };
181 
182   int element_index = 0;
183   for (const ByteTestCase& test_case : kByteStringTestCases) {
184     SCOPED_TRACE(testing::Message()
185                  << "testing string test case at : " << element_index++);
186 
187     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
188     ASSERT_TRUE(cbor.has_value());
189     ASSERT_EQ(cbor.value().type(), Value::Type::BYTE_STRING);
190     EXPECT_EQ(cbor.value().GetBytestring(), test_case.value);
191 
192     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
193     Reader::DecoderError error_code;
194     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
195     EXPECT_FALSE(cbor.has_value());
196     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
197 
198     size_t num_bytes_consumed;
199     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
200                         &error_code);
201     ASSERT_TRUE(cbor.has_value());
202     ASSERT_EQ(cbor.value().type(), Value::Type::BYTE_STRING);
203     EXPECT_EQ(cbor.value().GetBytestring(), test_case.value);
204     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
205     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
206   }
207 }
208 
TEST(CBORReaderTest,TestReadString)209 TEST(CBORReaderTest, TestReadString) {
210   struct StringTestCase {
211     const std::string value;
212     const std::vector<uint8_t> cbor_data;
213   };
214 
215   static const StringTestCase kStringTestCases[] = {
216       {"", {0x60}},
217       {"a", {0x61, 0x61}},
218       {"IETF", {0x64, 0x49, 0x45, 0x54, 0x46}},
219       {"\"\\", {0x62, 0x22, 0x5c}},
220       {"\xc3\xbc", {0x62, 0xc3, 0xbc}},
221       {"\xe6\xb0\xb4", {0x63, 0xe6, 0xb0, 0xb4}},
222       {"\xf0\x90\x85\x91", {0x64, 0xf0, 0x90, 0x85, 0x91}},
223   };
224 
225   for (const StringTestCase& test_case : kStringTestCases) {
226     SCOPED_TRACE(testing::Message()
227                  << "testing string value : " << test_case.value);
228 
229     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
230     ASSERT_TRUE(cbor.has_value());
231     ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
232     EXPECT_EQ(cbor.value().GetString(), test_case.value);
233 
234     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
235     Reader::DecoderError error_code;
236     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
237     EXPECT_FALSE(cbor.has_value());
238     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
239 
240     size_t num_bytes_consumed;
241     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
242                         &error_code);
243     ASSERT_TRUE(cbor.has_value());
244     ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
245     EXPECT_EQ(cbor.value().GetString(), test_case.value);
246     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
247     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
248   }
249 }
250 
TEST(CBORReaderTest,TestReadStringWithNUL)251 TEST(CBORReaderTest, TestReadStringWithNUL) {
252   static const struct {
253     const std::string value;
254     const std::vector<uint8_t> cbor_data;
255   } kStringTestCases[] = {
256       {std::string("string_without_nul"),
257        {0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68,
258         0x6F, 0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C}},
259       {std::string("nul_terminated_string\0", 22),
260        {0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61,
261         0x74, 0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00}},
262       {std::string("embedded\0nul", 12),
263        {0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75,
264         0x6C}},
265       {std::string("trailing_nuls\0\0", 15),
266        {0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75,
267         0x6C, 0x73, 0x00, 0x00}},
268   };
269 
270   for (const auto& test_case : kStringTestCases) {
271     SCOPED_TRACE(testing::Message()
272                  << "testing string with nul bytes :" << test_case.value);
273 
274     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
275     ASSERT_TRUE(cbor.has_value());
276     ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
277     EXPECT_EQ(cbor.value().GetString(), test_case.value);
278 
279     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
280     Reader::DecoderError error_code;
281     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
282     EXPECT_FALSE(cbor.has_value());
283     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
284 
285     size_t num_bytes_consumed;
286     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
287                         &error_code);
288     ASSERT_TRUE(cbor.has_value());
289     ASSERT_EQ(cbor.value().type(), Value::Type::STRING);
290     EXPECT_EQ(cbor.value().GetString(), test_case.value);
291     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
292     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
293   }
294 }
295 
TEST(CBORReaderTest,TestReadStringWithInvalidByteSequenceAfterNUL)296 TEST(CBORReaderTest, TestReadStringWithInvalidByteSequenceAfterNUL) {
297   // UTF-8 validation should not stop at the first NUL character in the string.
298   // That is, a string with an invalid byte sequence should fail UTF-8
299   // validation even if the invalid character is located after one or more NUL
300   // characters. Here, 0xA6 is an unexpected continuation byte.
301   static const std::vector<uint8_t> string_with_invalid_continuation_byte = {
302       0x63, 0x00, 0x00, 0xA6};
303   Reader::DecoderError error_code;
304   base::Optional<Value> cbor =
305       Reader::Read(string_with_invalid_continuation_byte, &error_code);
306   EXPECT_FALSE(cbor.has_value());
307   EXPECT_EQ(error_code, Reader::DecoderError::INVALID_UTF8);
308 }
309 
TEST(CBORReaderTest,TestReadArray)310 TEST(CBORReaderTest, TestReadArray) {
311   static const std::vector<uint8_t> kArrayTestCaseCbor = {
312       // clang-format off
313       0x98, 0x19,  // array of 25 elements
314         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
315         0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
316         0x18, 0x18, 0x19,
317       // clang-format on
318   };
319 
320   base::Optional<Value> cbor = Reader::Read(kArrayTestCaseCbor);
321   ASSERT_TRUE(cbor.has_value());
322   const Value cbor_array = std::move(cbor.value());
323   ASSERT_EQ(cbor_array.type(), Value::Type::ARRAY);
324   ASSERT_THAT(cbor_array.GetArray(), testing::SizeIs(25));
325 
326   std::vector<Value> array;
327   for (int i = 0; i < 25; i++) {
328     SCOPED_TRACE(testing::Message() << "testing array element at index " << i);
329 
330     ASSERT_EQ(cbor_array.GetArray()[i].type(), Value::Type::UNSIGNED);
331     EXPECT_EQ(cbor_array.GetArray()[i].GetInteger(),
332               static_cast<int64_t>(i + 1));
333   }
334 
335   auto cbor_data_with_extra_byte = WithExtraneousData(kArrayTestCaseCbor);
336   Reader::DecoderError error_code;
337   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
338   EXPECT_FALSE(cbor.has_value());
339   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
340 
341   size_t num_bytes_consumed;
342   cbor =
343       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
344   ASSERT_TRUE(cbor.has_value());
345   ASSERT_EQ(cbor_array.type(), Value::Type::ARRAY);
346   ASSERT_THAT(cbor_array.GetArray(), testing::SizeIs(25));
347   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
348   EXPECT_EQ(num_bytes_consumed, kArrayTestCaseCbor.size());
349 }
350 
TEST(CBORReaderTest,TestReadMapWithMapValue)351 TEST(CBORReaderTest, TestReadMapWithMapValue) {
352   static const std::vector<uint8_t> kMapTestCaseCbor = {
353       // clang-format off
354       0xa4,  // map with 4 key value pairs:
355         0x18, 0x18,  // 24
356         0x63, 0x61, 0x62, 0x63,  // "abc"
357 
358         0x60,  // ""
359         0x61, 0x2e,  // "."
360 
361         0x61, 0x62,  // "b"
362         0x61, 0x42,  // "B"
363 
364         0x62, 0x61, 0x61,  // "aa"
365         0x62, 0x41, 0x41,  // "AA"
366       // clang-format on
367   };
368 
369   base::Optional<Value> cbor = Reader::Read(kMapTestCaseCbor);
370   ASSERT_TRUE(cbor.has_value());
371   const Value cbor_val = std::move(cbor.value());
372   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
373   ASSERT_EQ(cbor_val.GetMap().size(), 4u);
374 
375   const Value key_uint(24);
376   ASSERT_EQ(cbor_val.GetMap().count(key_uint), 1u);
377   ASSERT_EQ(cbor_val.GetMap().find(key_uint)->second.type(),
378             Value::Type::STRING);
379   EXPECT_EQ(cbor_val.GetMap().find(key_uint)->second.GetString(), "abc");
380 
381   const Value key_empty_string("");
382   ASSERT_EQ(cbor_val.GetMap().count(key_empty_string), 1u);
383   ASSERT_EQ(cbor_val.GetMap().find(key_empty_string)->second.type(),
384             Value::Type::STRING);
385   EXPECT_EQ(cbor_val.GetMap().find(key_empty_string)->second.GetString(), ".");
386 
387   const Value key_b("b");
388   ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
389   ASSERT_EQ(cbor_val.GetMap().find(key_b)->second.type(), Value::Type::STRING);
390   EXPECT_EQ(cbor_val.GetMap().find(key_b)->second.GetString(), "B");
391 
392   const Value key_aa("aa");
393   ASSERT_EQ(cbor_val.GetMap().count(key_aa), 1u);
394   ASSERT_EQ(cbor_val.GetMap().find(key_aa)->second.type(), Value::Type::STRING);
395   EXPECT_EQ(cbor_val.GetMap().find(key_aa)->second.GetString(), "AA");
396 
397   auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCaseCbor);
398   Reader::DecoderError error_code;
399   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
400   EXPECT_FALSE(cbor.has_value());
401   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
402 
403   size_t num_bytes_consumed;
404   cbor =
405       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
406   ASSERT_TRUE(cbor.has_value());
407   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
408   ASSERT_EQ(cbor_val.GetMap().size(), 4u);
409   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
410   EXPECT_EQ(num_bytes_consumed, kMapTestCaseCbor.size());
411 }
412 
TEST(CBORReaderTest,TestReadMapWithIntegerKeys)413 TEST(CBORReaderTest, TestReadMapWithIntegerKeys) {
414   static const std::vector<uint8_t> kMapWithIntegerKeyCbor = {
415       // clang-format off
416       0xA4,                 // map with 4 key value pairs
417          0x01,              // key : 1
418          0x61, 0x61,        // value : "a"
419 
420          0x09,              // key : 9
421          0x61, 0x62,        // value : "b"
422 
423          0x19, 0x03, 0xE7,  // key : 999
424          0x61, 0x63,        // value "c"
425 
426          0x19, 0x04, 0x57,  // key : 1111
427          0x61, 0x64,        // value : "d"
428       // clang-format on
429   };
430 
431   base::Optional<Value> cbor = Reader::Read(kMapWithIntegerKeyCbor);
432   ASSERT_TRUE(cbor.has_value());
433   const Value cbor_val = std::move(cbor.value());
434   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
435   ASSERT_EQ(cbor_val.GetMap().size(), 4u);
436 
437   const Value key_1(1);
438   ASSERT_EQ(cbor_val.GetMap().count(key_1), 1u);
439   ASSERT_EQ(cbor_val.GetMap().find(key_1)->second.type(), Value::Type::STRING);
440   EXPECT_EQ(cbor_val.GetMap().find(key_1)->second.GetString(), "a");
441 
442   const Value key_9(9);
443   ASSERT_EQ(cbor_val.GetMap().count(key_9), 1u);
444   ASSERT_EQ(cbor_val.GetMap().find(key_9)->second.type(), Value::Type::STRING);
445   EXPECT_EQ(cbor_val.GetMap().find(key_9)->second.GetString(), "b");
446 
447   const Value key_999(999);
448   ASSERT_EQ(cbor_val.GetMap().count(key_999), 1u);
449   ASSERT_EQ(cbor_val.GetMap().find(key_999)->second.type(),
450             Value::Type::STRING);
451   EXPECT_EQ(cbor_val.GetMap().find(key_999)->second.GetString(), "c");
452 
453   const Value key_1111(1111);
454   ASSERT_EQ(cbor_val.GetMap().count(key_1111), 1u);
455   ASSERT_EQ(cbor_val.GetMap().find(key_1111)->second.type(),
456             Value::Type::STRING);
457   EXPECT_EQ(cbor_val.GetMap().find(key_1111)->second.GetString(), "d");
458 
459   auto cbor_data_with_extra_byte = WithExtraneousData(kMapWithIntegerKeyCbor);
460   Reader::DecoderError error_code;
461   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
462   EXPECT_FALSE(cbor.has_value());
463   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
464 
465   size_t num_bytes_consumed;
466   cbor =
467       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
468   ASSERT_TRUE(cbor.has_value());
469   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
470   ASSERT_EQ(cbor_val.GetMap().size(), 4u);
471   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
472   EXPECT_EQ(num_bytes_consumed, kMapWithIntegerKeyCbor.size());
473 }
474 
TEST(CBORReaderTest,TestReadMapWithNegativeIntegersKeys)475 TEST(CBORReaderTest, TestReadMapWithNegativeIntegersKeys) {
476   static const std::vector<uint8_t> kMapWithIntegerKeyCbor = {
477       // clang-format off
478       0xA3,                 // map with 3 key value pairs
479          0x20,              // key : -1
480          0x01,
481 
482          0x21,              // key : -2
483          0x02,
484 
485          0x38, 0x63,        // key : -100
486          0x03,
487       // clang-format on
488   };
489 
490   base::Optional<Value> cbor = Reader::Read(kMapWithIntegerKeyCbor);
491   ASSERT_TRUE(cbor.has_value());
492   const Value cbor_val = std::move(cbor.value());
493   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
494   ASSERT_EQ(cbor_val.GetMap().size(), 3u);
495 
496   const Value key_1(-1);
497   ASSERT_EQ(cbor_val.GetMap().count(key_1), 1u);
498   ASSERT_EQ(cbor_val.GetMap().find(key_1)->second.type(),
499             Value::Type::UNSIGNED);
500   EXPECT_EQ(cbor_val.GetMap().find(key_1)->second.GetInteger(), 1);
501 
502   const Value key_2(-2);
503   ASSERT_EQ(cbor_val.GetMap().count(key_2), 1u);
504   ASSERT_EQ(cbor_val.GetMap().find(key_2)->second.type(),
505             Value::Type::UNSIGNED);
506   EXPECT_EQ(cbor_val.GetMap().find(key_2)->second.GetInteger(), 2);
507 
508   const Value key_100(-100);
509   ASSERT_EQ(cbor_val.GetMap().count(key_100), 1u);
510   ASSERT_EQ(cbor_val.GetMap().find(key_100)->second.type(),
511             Value::Type::UNSIGNED);
512   EXPECT_EQ(cbor_val.GetMap().find(key_100)->second.GetInteger(), 3);
513 
514   auto cbor_data_with_extra_byte = WithExtraneousData(kMapWithIntegerKeyCbor);
515   Reader::DecoderError error_code;
516   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
517   EXPECT_FALSE(cbor.has_value());
518   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
519 
520   size_t num_bytes_consumed;
521   cbor =
522       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
523   ASSERT_TRUE(cbor.has_value());
524   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
525   ASSERT_EQ(cbor_val.GetMap().size(), 3u);
526   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
527   EXPECT_EQ(num_bytes_consumed, kMapWithIntegerKeyCbor.size());
528 }
529 
TEST(CBORReaderTest,TestReadMapWithArray)530 TEST(CBORReaderTest, TestReadMapWithArray) {
531   static const std::vector<uint8_t> kMapArrayTestCaseCbor = {
532       // clang-format off
533       0xa2,  // map of 2 pairs
534         0x61, 0x61,  // "a"
535         0x01,
536 
537         0x61, 0x62,  // "b"
538         0x82,        // array with 2 elements
539           0x02,
540           0x03,
541       // clang-format on
542   };
543 
544   base::Optional<Value> cbor = Reader::Read(kMapArrayTestCaseCbor);
545   ASSERT_TRUE(cbor.has_value());
546   const Value cbor_val = std::move(cbor.value());
547   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
548   ASSERT_EQ(cbor_val.GetMap().size(), 2u);
549 
550   const Value key_a("a");
551   ASSERT_EQ(cbor_val.GetMap().count(key_a), 1u);
552   ASSERT_EQ(cbor_val.GetMap().find(key_a)->second.type(),
553             Value::Type::UNSIGNED);
554   EXPECT_EQ(cbor_val.GetMap().find(key_a)->second.GetInteger(), 1u);
555 
556   const Value key_b("b");
557   ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
558   ASSERT_EQ(cbor_val.GetMap().find(key_b)->second.type(), Value::Type::ARRAY);
559 
560   const Value nested_array = cbor_val.GetMap().find(key_b)->second.Clone();
561   ASSERT_EQ(nested_array.GetArray().size(), 2u);
562   for (int i = 0; i < 2; i++) {
563     ASSERT_THAT(nested_array.GetArray()[i].type(), Value::Type::UNSIGNED);
564     EXPECT_EQ(nested_array.GetArray()[i].GetInteger(),
565               static_cast<int64_t>(i + 2));
566   }
567 
568   auto cbor_data_with_extra_byte = WithExtraneousData(kMapArrayTestCaseCbor);
569   Reader::DecoderError error_code;
570   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
571   EXPECT_FALSE(cbor.has_value());
572   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
573 
574   size_t num_bytes_consumed;
575   cbor =
576       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
577   ASSERT_TRUE(cbor.has_value());
578   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
579   ASSERT_EQ(cbor_val.GetMap().size(), 2u);
580   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
581   EXPECT_EQ(num_bytes_consumed, kMapArrayTestCaseCbor.size());
582 }
583 
TEST(CBORReaderTest,TestReadMapWithTextStringKeys)584 TEST(CBORReaderTest, TestReadMapWithTextStringKeys) {
585   static const std::vector<uint8_t> kMapTestCase{
586       // clang-format off
587       0xa2,  // map of 2 pairs
588         0x61, 'k', // text string "k"
589         0x61, 'v',
590 
591         0x63, 'f', 'o', 'o', // text string "foo"
592         0x63, 'b', 'a', 'r',
593       // clang-format on
594   };
595 
596   Reader::DecoderError error_code;
597   base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
598   ASSERT_TRUE(cbor.has_value());
599   ASSERT_EQ(cbor->type(), Value::Type::MAP);
600   ASSERT_EQ(cbor->GetMap().size(), 2u);
601 
602   const Value key_k("k");
603   ASSERT_EQ(cbor->GetMap().count(key_k), 1u);
604   ASSERT_EQ(cbor->GetMap().find(key_k)->second.type(), Value::Type::STRING);
605   EXPECT_EQ(cbor->GetMap().find(key_k)->second.GetString(), "v");
606 
607   const Value key_foo("foo");
608   ASSERT_EQ(cbor->GetMap().count(key_foo), 1u);
609   ASSERT_EQ(cbor->GetMap().find(key_foo)->second.type(), Value::Type::STRING);
610   EXPECT_EQ(cbor->GetMap().find(key_foo)->second.GetString(), "bar");
611 
612   auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
613   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
614   EXPECT_FALSE(cbor.has_value());
615   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
616 
617   size_t num_bytes_consumed;
618   cbor =
619       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
620   ASSERT_TRUE(cbor.has_value());
621   ASSERT_EQ(cbor->type(), Value::Type::MAP);
622   ASSERT_EQ(cbor->GetMap().size(), 2u);
623   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
624   EXPECT_EQ(num_bytes_consumed, kMapTestCase.size());
625 }
626 
TEST(CBORReaderTest,TestReadMapWithByteStringKeys)627 TEST(CBORReaderTest, TestReadMapWithByteStringKeys) {
628   static const std::vector<uint8_t> kMapTestCase{
629       // clang-format off
630       0xa2,  // map of 2 pairs
631         0x41, 'k', // byte string "k"
632         0x41, 'v',
633 
634         0x43, 'f', 'o', 'o', // byte string "foo"
635         0x43, 'b', 'a', 'r',
636       // clang-format on
637   };
638 
639   Reader::DecoderError error_code;
640   base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
641   ASSERT_TRUE(cbor.has_value());
642   ASSERT_EQ(cbor->type(), Value::Type::MAP);
643   ASSERT_EQ(cbor->GetMap().size(), 2u);
644 
645   const Value key_k(std::vector<uint8_t>{'k'});
646   ASSERT_EQ(cbor->GetMap().count(key_k), 1u);
647   ASSERT_EQ(cbor->GetMap().find(key_k)->second.type(),
648             Value::Type::BYTE_STRING);
649   EXPECT_EQ(cbor->GetMap().find(key_k)->second.GetBytestring(),
650             std::vector<uint8_t>{'v'});
651 
652   const Value key_foo(std::vector<uint8_t>{'f', 'o', 'o'});
653   ASSERT_EQ(cbor->GetMap().count(key_foo), 1u);
654   ASSERT_EQ(cbor->GetMap().find(key_foo)->second.type(),
655             Value::Type::BYTE_STRING);
656   static const std::vector<uint8_t> kBarBytes{'b', 'a', 'r'};
657   EXPECT_EQ(cbor->GetMap().find(key_foo)->second.GetBytestring(), kBarBytes);
658 
659   auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
660   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
661   EXPECT_FALSE(cbor.has_value());
662   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
663 
664   size_t num_bytes_consumed;
665   cbor =
666       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
667   ASSERT_TRUE(cbor.has_value());
668   ASSERT_EQ(cbor->type(), Value::Type::MAP);
669   ASSERT_EQ(cbor->GetMap().size(), 2u);
670   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
671   EXPECT_EQ(num_bytes_consumed, kMapTestCase.size());
672 }
673 
TEST(CBORReaderTest,TestReadMapWithMixedKeys)674 TEST(CBORReaderTest, TestReadMapWithMixedKeys) {
675   // Example adopted from:
676   // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
677   static const uint8_t kMapTestCase[] = {
678       // clang-format off
679       0xa6, // map of 6 pairs
680         0x0a, // 10
681         0x00,
682 
683         0x18, 0x64, // 100
684         0x01,
685 
686         0x20, // -1
687         0x02,
688 
689         // This entry is not in the example, but added to test byte string key
690         0x42, 'x', 'y', // byte string "xy"
691         0x03,
692 
693         0x61, 'z', // text string "z"
694         0x04,
695 
696         0x62, 'a', 'a', // text string "aa"
697         0x05,
698 
699       /*
700         0x81, 0x18, 0x64, // [100] (array as map key is not yet supported)
701         0x06,
702 
703         0x81, 0x20,  // [-1] (array as map key is not yet supported)
704         0x07,
705 
706         0xf4, // false (boolean  as map key is not yet supported)
707         0x08,
708       */
709       // clang-format on
710   };
711 
712   Reader::DecoderError error_code;
713   base::Optional<Value> cbor = Reader::Read(kMapTestCase, &error_code);
714   ASSERT_TRUE(cbor.has_value());
715   ASSERT_EQ(cbor->type(), Value::Type::MAP);
716   ASSERT_EQ(cbor->GetMap().size(), 6u);
717 
718   std::vector<Value> keys;
719   keys.emplace_back(10);
720   keys.emplace_back(100);
721   keys.emplace_back(-1);
722   keys.emplace_back(Value::BinaryValue{'x', 'y'});
723   keys.emplace_back("z");
724   keys.emplace_back("aa");
725   for (size_t i = 0; i < keys.size(); ++i) {
726     SCOPED_TRACE(testing::Message() << "testing key at index: " << i);
727     ASSERT_EQ(cbor->GetMap().count(keys[i]), 1u);
728     ASSERT_EQ(cbor->GetMap().find(keys[i])->second.type(),
729               Value::Type::UNSIGNED);
730     EXPECT_EQ(cbor->GetMap().find(keys[i])->second.GetInteger(),
731               static_cast<int>(i));
732   }
733 
734   auto cbor_data_with_extra_byte = WithExtraneousData(kMapTestCase);
735   cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
736   EXPECT_FALSE(cbor.has_value());
737   EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
738 
739   size_t num_bytes_consumed;
740   cbor =
741       Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed, &error_code);
742   ASSERT_TRUE(cbor.has_value());
743   ASSERT_EQ(cbor->type(), Value::Type::MAP);
744   ASSERT_EQ(cbor->GetMap().size(), 6u);
745   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
746   EXPECT_EQ(num_bytes_consumed, base::size(kMapTestCase));
747 }
748 
TEST(CBORReaderTest,TestReadNestedMap)749 TEST(CBORReaderTest, TestReadNestedMap) {
750   static const std::vector<uint8_t> kNestedMapTestCase = {
751       // clang-format off
752       0xa2,  // map of 2 pairs
753         0x61, 0x61,  // "a"
754         0x01,
755 
756         0x61, 0x62,  // "b"
757         0xa2,        // map of 2 pairs
758           0x61, 0x63,  // "c"
759           0x02,
760 
761           0x61, 0x64,  // "d"
762           0x03,
763       // clang-format on
764   };
765 
766   base::Optional<Value> cbor = Reader::Read(kNestedMapTestCase);
767   ASSERT_TRUE(cbor.has_value());
768   const Value cbor_val = std::move(cbor.value());
769   ASSERT_EQ(cbor_val.type(), Value::Type::MAP);
770   ASSERT_EQ(cbor_val.GetMap().size(), 2u);
771 
772   const Value key_a("a");
773   ASSERT_EQ(cbor_val.GetMap().count(key_a), 1u);
774   ASSERT_EQ(cbor_val.GetMap().find(key_a)->second.type(),
775             Value::Type::UNSIGNED);
776   EXPECT_EQ(cbor_val.GetMap().find(key_a)->second.GetInteger(), 1u);
777 
778   const Value key_b("b");
779   ASSERT_EQ(cbor_val.GetMap().count(key_b), 1u);
780   const Value nested_map = cbor_val.GetMap().find(key_b)->second.Clone();
781   ASSERT_EQ(nested_map.type(), Value::Type::MAP);
782   ASSERT_EQ(nested_map.GetMap().size(), 2u);
783 
784   const Value key_c("c");
785   ASSERT_EQ(nested_map.GetMap().count(key_c), 1u);
786   ASSERT_EQ(nested_map.GetMap().find(key_c)->second.type(),
787             Value::Type::UNSIGNED);
788   EXPECT_EQ(nested_map.GetMap().find(key_c)->second.GetInteger(), 2u);
789 
790   const Value key_d("d");
791   ASSERT_EQ(nested_map.GetMap().count(key_d), 1u);
792   ASSERT_EQ(nested_map.GetMap().find(key_d)->second.type(),
793             Value::Type::UNSIGNED);
794   EXPECT_EQ(nested_map.GetMap().find(key_d)->second.GetInteger(), 3u);
795 }
796 
TEST(CBORReaderTest,TestIntegerRange)797 TEST(CBORReaderTest, TestIntegerRange) {
798   static const std::vector<uint8_t> kMaxPositiveInt = {
799       0x1b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
800   static const std::vector<uint8_t> kMinNegativeInt = {
801       0x3b, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
802 
803   base::Optional<Value> max_positive_int = Reader::Read(kMaxPositiveInt);
804   ASSERT_TRUE(max_positive_int.has_value());
805   EXPECT_EQ(max_positive_int.value().GetInteger(), INT64_MAX);
806 
807   base::Optional<Value> min_negative_int = Reader::Read(kMinNegativeInt);
808   ASSERT_TRUE(min_negative_int.has_value());
809   EXPECT_EQ(min_negative_int.value().GetInteger(), INT64_MIN);
810 }
811 
TEST(CBORReaderTest,TestIntegerOutOfRangeError)812 TEST(CBORReaderTest, TestIntegerOutOfRangeError) {
813   static const std::vector<uint8_t> kOutOfRangePositiveInt = {
814       0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
815 
816   static const std::vector<uint8_t> kOutOfRangeNegativeInt = {
817       0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
818 
819   Reader::DecoderError error_code;
820   base::Optional<Value> positive_int_out_of_range_cbor =
821       Reader::Read(kOutOfRangePositiveInt, &error_code);
822   EXPECT_FALSE(positive_int_out_of_range_cbor.has_value());
823   EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_RANGE_INTEGER_VALUE);
824 
825   base::Optional<Value> negative_int_out_of_range_cbor =
826       Reader::Read(kOutOfRangeNegativeInt, &error_code);
827   EXPECT_FALSE(negative_int_out_of_range_cbor.has_value());
828   EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_RANGE_INTEGER_VALUE);
829 }
830 
TEST(CBORReaderTest,TestReadSimpleValue)831 TEST(CBORReaderTest, TestReadSimpleValue) {
832   static const struct {
833     const Value::SimpleValue value;
834     const std::vector<uint8_t> cbor_data;
835   } kSimpleValueTestCases[] = {
836       {Value::SimpleValue::FALSE_VALUE, {0xf4}},
837       {Value::SimpleValue::TRUE_VALUE, {0xf5}},
838       {Value::SimpleValue::NULL_VALUE, {0xf6}},
839       {Value::SimpleValue::UNDEFINED, {0xf7}},
840   };
841 
842   int test_element_index = 0;
843   for (const auto& test_case : kSimpleValueTestCases) {
844     SCOPED_TRACE(testing::Message()
845                  << "testing simple value at index : " << test_element_index++);
846 
847     base::Optional<Value> cbor = Reader::Read(test_case.cbor_data);
848     ASSERT_TRUE(cbor.has_value());
849     ASSERT_EQ(cbor.value().type(), Value::Type::SIMPLE_VALUE);
850     EXPECT_EQ(cbor.value().GetSimpleValue(), test_case.value);
851 
852     auto cbor_data_with_extra_byte = WithExtraneousData(test_case.cbor_data);
853     Reader::DecoderError error_code;
854     cbor = Reader::Read(cbor_data_with_extra_byte, &error_code);
855     EXPECT_FALSE(cbor.has_value());
856     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
857 
858     size_t num_bytes_consumed;
859     cbor = Reader::Read(cbor_data_with_extra_byte, &num_bytes_consumed,
860                         &error_code);
861     ASSERT_TRUE(cbor.has_value());
862     ASSERT_EQ(cbor.value().type(), Value::Type::SIMPLE_VALUE);
863     EXPECT_EQ(cbor.value().GetSimpleValue(), test_case.value);
864     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
865     EXPECT_EQ(num_bytes_consumed, test_case.cbor_data.size());
866   }
867 }
868 
TEST(CBORReaderTest,TestReadUnsupportedFloatingPointNumbers)869 TEST(CBORReaderTest, TestReadUnsupportedFloatingPointNumbers) {
870   static const std::vector<uint8_t> floating_point_cbors[] = {
871       // 16 bit floating point value.
872       {0xf9, 0x10, 0x00},
873       // 32 bit floating point value.
874       {0xfa, 0x10, 0x00, 0x00, 0x00},
875       // 64 bit floating point value.
876       {0xfb, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
877 
878   for (const auto& unsupported_floating_point : floating_point_cbors) {
879     SCOPED_TRACE(testing::Message()
880                  << "testing unsupported floating point : "
881                  << testing::PrintToString(unsupported_floating_point));
882     Reader::DecoderError error_code;
883     base::Optional<Value> cbor =
884         Reader::Read(unsupported_floating_point, &error_code);
885     EXPECT_FALSE(cbor.has_value());
886     EXPECT_EQ(error_code,
887               Reader::DecoderError::UNSUPPORTED_FLOATING_POINT_VALUE);
888   }
889 }
890 
TEST(CBORReaderTest,TestIncompleteCBORDataError)891 TEST(CBORReaderTest, TestIncompleteCBORDataError) {
892   static const std::vector<uint8_t> incomplete_cbor_list[] = {
893       // Additional info byte corresponds to unsigned int that corresponds
894       // to 2 additional bytes. But actual data encoded  in one byte.
895       {0x19, 0x03},
896       // CBOR bytestring of length 3 encoded with additional info of length 4.
897       {0x44, 0x01, 0x02, 0x03},
898       // CBOR string data "IETF" of length 4 encoded with additional info of
899       // length 5.
900       {0x65, 0x49, 0x45, 0x54, 0x46},
901       // CBOR array of length 1 encoded with additional info of length 2.
902       {0x82, 0x02},
903       // CBOR map with single key value pair encoded with additional info of
904       // length 2.
905       {0xa2, 0x61, 0x61, 0x01},
906       {0x18},  // unsigned with pending 1 byte of numeric value.
907       {0x99},  // array with pending 2 byte of numeric value (length).
908       {0xba},  // map with pending 4 byte of numeric value (length).
909       {0x5b},  // byte string with pending 4 byte of numeric value (length).
910       {0x3b},  // negative integer with pending 8 byte of numeric value.
911       {0x99, 0x01},  // array with pending 2 byte of numeric value (length),
912                      // with only 1 byte of additional data.
913       {0xba, 0x01, 0x02, 0x03},  // map with pending 4 byte of numeric value
914                                  // (length), with only 3 bytes of additional
915                                  // data.
916       {0x3b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
917        0x07},  // negative integer with pending 8 byte of
918                // numeric value, with only 7 bytes of
919                // additional data.
920   };
921 
922   int test_element_index = 0;
923   for (const auto& incomplete_data : incomplete_cbor_list) {
924     SCOPED_TRACE(testing::Message() << "testing incomplete data at index : "
925                                     << test_element_index++);
926 
927     Reader::DecoderError error_code;
928     base::Optional<Value> cbor = Reader::Read(incomplete_data, &error_code);
929     EXPECT_FALSE(cbor.has_value());
930     EXPECT_EQ(error_code, Reader::DecoderError::INCOMPLETE_CBOR_DATA);
931   }
932 }
933 
934 // While RFC 7049 allows CBOR map keys with all types, current decoder only
935 // supports unsigned integer and string keys.
TEST(CBORReaderTest,TestUnsupportedMapKeyFormatError)936 TEST(CBORReaderTest, TestUnsupportedMapKeyFormatError) {
937   static const std::vector<uint8_t> kMapWithUintKey = {
938       // clang-format off
939       0xa2,        // map of 2 pairs
940 
941         0x82, 0x01, 0x02,  // invalid key : [1, 2]
942         0x02,              // value : 2
943 
944         0x61, 0x64,  // key : "d"
945         0x03,        // value : 3
946       // clang-format on
947   };
948 
949   Reader::DecoderError error_code;
950   base::Optional<Value> cbor = Reader::Read(kMapWithUintKey, &error_code);
951   EXPECT_FALSE(cbor.has_value());
952   EXPECT_EQ(error_code, Reader::DecoderError::INCORRECT_MAP_KEY_TYPE);
953 }
954 
TEST(CBORReaderTest,TestUnknownAdditionalInfoError)955 TEST(CBORReaderTest, TestUnknownAdditionalInfoError) {
956   static const std::vector<uint8_t> kUnknownAdditionalInfoList[] = {
957       // "IETF" encoded with major type 3 and additional info of 28.
958       {0x7C, 0x49, 0x45, 0x54, 0x46},
959       // "\"\\" encoded with major type 3 and additional info of 29.
960       {0x7D, 0x22, 0x5c},
961       // "\xc3\xbc" encoded with major type 3 and additional info of 30.
962       {0x7E, 0xc3, 0xbc},
963       // "\xe6\xb0\xb4" encoded with major type 3 and additional info of 31.
964       {0x7F, 0xe6, 0xb0, 0xb4},
965       // Major type 7, additional information 28: unassigned.
966       {0xFC},
967       // Major type 7, additional information 29: unassigned.
968       {0xFD},
969       // Major type 7, additional information 30: unassigned.
970       {0xFE},
971       // Major type 7, additional information 31: "break" stop code for
972       // indefinite-length items.
973       {0xFF},
974   };
975 
976   int test_element_index = 0;
977   for (const auto& incorrect_cbor : kUnknownAdditionalInfoList) {
978     SCOPED_TRACE(testing::Message()
979                  << "testing data at index : " << test_element_index++);
980 
981     Reader::DecoderError error_code;
982     base::Optional<Value> cbor = Reader::Read(incorrect_cbor, &error_code);
983     EXPECT_FALSE(cbor.has_value());
984     EXPECT_EQ(error_code, Reader::DecoderError::UNKNOWN_ADDITIONAL_INFO);
985   }
986 }
987 
TEST(CBORReaderTest,TestTooMuchNestingError)988 TEST(CBORReaderTest, TestTooMuchNestingError) {
989   static const std::vector<uint8_t> kZeroDepthCBORList[] = {
990       // Unsigned int with value 100.
991       {0x18, 0x64},
992       // CBOR bytestring of length 4.
993       {0x44, 0x01, 0x02, 0x03, 0x04},
994       // CBOR string of corresponding to "IETF.
995       {0x64, 0x49, 0x45, 0x54, 0x46},
996       // Empty CBOR array.
997       {0x80},
998       // Empty CBOR Map
999       {0xa0},
1000   };
1001 
1002   int test_element_index = 0;
1003   for (const auto& zero_depth_data : kZeroDepthCBORList) {
1004     SCOPED_TRACE(testing::Message()
1005                  << "testing zero nested data : " << test_element_index++);
1006     Reader::DecoderError error_code;
1007     base::Optional<Value> cbor = Reader::Read(zero_depth_data, &error_code, 0);
1008     EXPECT_TRUE(cbor.has_value());
1009     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
1010   }
1011 
1012   // Corresponds to a CBOR structure with a nesting depth of 2:
1013   //      {"a": 1,
1014   //       "b": [2, 3]}
1015   static const std::vector<uint8_t> kNestedCBORData = {
1016       // clang-format off
1017       0xa2,  // map of 2 pairs
1018         0x61, 0x61,  // "a"
1019         0x01,
1020 
1021         0x61, 0x62,  // "b"
1022         0x82,        // array with 2 elements
1023           0x02,
1024           0x03,
1025       // clang-format on
1026   };
1027 
1028   Reader::DecoderError error_code;
1029   base::Optional<Value> cbor_single_layer_max =
1030       Reader::Read(kNestedCBORData, &error_code, 1);
1031   EXPECT_FALSE(cbor_single_layer_max.has_value());
1032   EXPECT_EQ(error_code, Reader::DecoderError::TOO_MUCH_NESTING);
1033 
1034   base::Optional<Value> cbor_double_layer_max =
1035       Reader::Read(kNestedCBORData, &error_code, 2);
1036   EXPECT_TRUE(cbor_double_layer_max.has_value());
1037   EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
1038 }
1039 
TEST(CBORReaderTest,TestOutOfOrderKeyError)1040 TEST(CBORReaderTest, TestOutOfOrderKeyError) {
1041   static const std::vector<uint8_t> kMapsWithUnsortedKeys[] = {
1042       // clang-format off
1043       {0xa2,  // map with 2 keys with same major type and length
1044          0x61, 0x62,  // key "b"
1045          0x61, 0x42,  // value "B"
1046 
1047          0x61, 0x61,  // key "a" (out of order byte-wise lexically)
1048          0x61, 0x45   // value "E"
1049       },
1050       {0xa2,  // map with 2 keys with different major type
1051          0x61, 0x62,        // key "b"
1052          0x02,              // value 2
1053 
1054          // key 1000 (out of order since lower major type sorts first)
1055          0x19, 0x03, 0xe8,
1056          0x61, 0x61,        // value a
1057       },
1058       {0xa2,  // map with 2 keys with same major type
1059          0x19, 0x03, 0xe8,  // key 1000  (out of order due to longer length)
1060          0x61, 0x61,        //value "a"
1061 
1062          0x0a,              // key 10
1063          0x61, 0x62},       // value "b"
1064       {0xa2,  // map with 2 text string keys
1065          0x62, 'a', 'a', // key text string "aa"
1066                          // (out of order due to longer length)
1067          0x02,
1068 
1069          0x61, 'b',   // key "b"
1070          0x01,
1071       },
1072       {0xa2,  // map with 2 byte string keys
1073          0x42, 'x', 'x', // key byte string "xx"
1074                          // (out of order due to longer length)
1075          0x02,
1076 
1077          0x41, 'y',  // key byte string "y"
1078          0x01,
1079       },
1080       //clang-format on
1081   };
1082 
1083   int test_element_index = 0;
1084   Reader::DecoderError error_code;
1085   for (const auto& unsorted_map : kMapsWithUnsortedKeys) {
1086     testing::Message scope_message;
1087     scope_message << "testing unsorted map : " << test_element_index++;
1088     SCOPED_TRACE(scope_message);
1089 
1090     base::Optional<Value> cbor =
1091         Reader::Read(unsorted_map, &error_code);
1092     EXPECT_FALSE(cbor.has_value());
1093     EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_ORDER_KEY);
1094   }
1095 }
1096 
TEST(CBORReaderTest,TestDuplicateKeyError)1097 TEST(CBORReaderTest, TestDuplicateKeyError) {
1098   static const std::vector<uint8_t> kMapWithDuplicateKey = {
1099       // clang-format off
1100       0xa6,  // map of 6 pairs:
1101         0x60,  // ""
1102         0x61, 0x2e,  // "."
1103 
1104         0x61, 0x62,  // "b"
1105         0x61, 0x42,  // "B"
1106 
1107         0x61, 0x62,  // "b" (Duplicate key)
1108         0x61, 0x43,  // "C"
1109 
1110         0x61, 0x64,  // "d"
1111         0x61, 0x44,  // "D"
1112 
1113         0x61, 0x65,  // "e"
1114         0x61, 0x44,  // "D"
1115 
1116         0x62, 0x61, 0x61,  // "aa"
1117         0x62, 0x41, 0x41,  // "AA"
1118       // clang-format on
1119   };
1120 
1121   Reader::DecoderError error_code;
1122 
1123   base::Optional<Value> cbor = Reader::Read(kMapWithDuplicateKey, &error_code);
1124   EXPECT_FALSE(cbor.has_value());
1125   EXPECT_EQ(error_code, Reader::DecoderError::OUT_OF_ORDER_KEY);
1126 }
1127 
1128 // Leveraging Markus Kuhn’s UTF-8 decoder stress test. See
1129 // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt for details.
TEST(CBORReaderTest,TestIncorrectStringEncodingError)1130 TEST(CBORReaderTest, TestIncorrectStringEncodingError) {
1131   static const std::vector<uint8_t> utf8_character_encodings[] = {
1132       // Corresponds to utf8 encoding of "퟿" (section 2.3.1 of stress test).
1133       {0x63, 0xED, 0x9F, 0xBF},
1134       // Corresponds to utf8 encoding of "" (section 2.3.2 of stress test).
1135       {0x63, 0xEE, 0x80, 0x80},
1136       // Corresponds to utf8 encoding of "�"  (section 2.3.3 of stress test).
1137       {0x63, 0xEF, 0xBF, 0xBD},
1138   };
1139 
1140   int test_element_index = 0;
1141   Reader::DecoderError error_code;
1142   for (const auto& cbor_byte : utf8_character_encodings) {
1143     SCOPED_TRACE(testing::Message() << "testing cbor data utf8 encoding : "
1144                                     << test_element_index++);
1145 
1146     base::Optional<Value> correctly_encoded_cbor =
1147         Reader::Read(cbor_byte, &error_code);
1148     EXPECT_TRUE(correctly_encoded_cbor.has_value());
1149     EXPECT_EQ(error_code, Reader::DecoderError::CBOR_NO_ERROR);
1150   }
1151 
1152   // Incorrect UTF8 encoding referenced by section 3.5.3 of the stress test.
1153   std::vector<uint8_t> impossible_utf_byte{0x64, 0xfe, 0xfe, 0xff, 0xff};
1154   base::Optional<Value> incorrectly_encoded_cbor =
1155       Reader::Read(impossible_utf_byte, &error_code);
1156   EXPECT_FALSE(incorrectly_encoded_cbor.has_value());
1157   EXPECT_EQ(error_code, Reader::DecoderError::INVALID_UTF8);
1158 }
1159 
TEST(CBORReaderTest,TestExtraneousCBORDataError)1160 TEST(CBORReaderTest, TestExtraneousCBORDataError) {
1161   static const std::vector<uint8_t> zero_padded_cbor_list[] = {
1162       // 1 extra byte after a 2-byte unsigned int.
1163       {0x19, 0x03, 0x05, 0x00},
1164       // 1 extra byte after a 4-byte cbor byte array.
1165       {0x44, 0x01, 0x02, 0x03, 0x04, 0x00},
1166       // 1 extra byte after a 4-byte string.
1167       {0x64, 0x49, 0x45, 0x54, 0x46, 0x00},
1168       // 1 extra byte after CBOR array of length 2.
1169       {0x82, 0x01, 0x02, 0x00},
1170       // 1 extra key value pair after CBOR map of size 2.
1171       {0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03},
1172   };
1173 
1174   int test_element_index = 0;
1175   for (const auto& extraneous_cbor_data : zero_padded_cbor_list) {
1176     SCOPED_TRACE(testing::Message()
1177                  << "testing cbor extraneous data : " << test_element_index++);
1178 
1179     Reader::DecoderError error_code;
1180     base::Optional<Value> cbor =
1181         Reader::Read(extraneous_cbor_data, &error_code);
1182     EXPECT_FALSE(cbor.has_value());
1183     EXPECT_EQ(error_code, Reader::DecoderError::EXTRANEOUS_DATA);
1184   }
1185 }
1186 
TEST(CBORReaderTest,TestUnsupportedSimpleValue)1187 TEST(CBORReaderTest, TestUnsupportedSimpleValue) {
1188   static const std::vector<uint8_t> unsupported_simple_values[] = {
1189       // Simple value (0, unassigned)
1190       {0xE0},
1191       // Simple value (19, unassigned)
1192       {0xF3},
1193       // Simple value (24, reserved)
1194       {0xF8, 0x18},
1195       // Simple value (28, reserved)
1196       {0xF8, 0x1C},
1197       // Simple value (29, reserved)
1198       {0xF8, 0x1D},
1199       // Simple value (30, reserved)
1200       {0xF8, 0x1E},
1201       // Simple value (31, reserved)
1202       {0xF8, 0x1F},
1203       // Simple value (32, unassigned)
1204       {0xF8, 0x20},
1205       // Simple value (255, unassigned)
1206       {0xF8, 0xFF},
1207   };
1208 
1209   for (const auto& unsupported_simple_val : unsupported_simple_values) {
1210     SCOPED_TRACE(testing::Message()
1211                  << "testing unsupported cbor simple value  : "
1212                  << ::testing::PrintToString(unsupported_simple_val));
1213 
1214     Reader::DecoderError error_code;
1215     base::Optional<Value> cbor =
1216         Reader::Read(unsupported_simple_val, &error_code);
1217     EXPECT_FALSE(cbor.has_value());
1218     EXPECT_EQ(error_code, Reader::DecoderError::UNSUPPORTED_SIMPLE_VALUE);
1219   }
1220 }
1221 
TEST(CBORReaderTest,TestSuperLongContentDontCrash)1222 TEST(CBORReaderTest, TestSuperLongContentDontCrash) {
1223   static const std::vector<uint8_t> kTestCases[] = {
1224       // CBOR array of 0xffffffff length.
1225       {0x9b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
1226       // CBOR map of 0xffffffff pairs.
1227       {0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
1228   };
1229   for (const auto& test_case : kTestCases) {
1230     Reader::DecoderError error_code;
1231     base::Optional<Value> cbor = Reader::Read(test_case, &error_code);
1232     EXPECT_FALSE(cbor.has_value());
1233     EXPECT_EQ(error_code, Reader::DecoderError::INCOMPLETE_CBOR_DATA);
1234   }
1235 }
1236 
TEST(CBORReaderTest,AllowInvalidUTF8)1237 TEST(CBORReaderTest, AllowInvalidUTF8) {
1238   static const uint8_t kInvalidUTF8[] = {
1239       // clang-format off
1240       0xa1,                    // map of length 1
1241         0x61, 'x',             // "x"
1242         0x81,                  // array of length 1
1243           0xa2,                // map of length 2
1244             0x61, 'y',         // "y"
1245             0x62, 0xe2, 0x80,  // invalid UTF-8 value
1246             0x61, 'z',         // "z"
1247             0x61, '.',         // "."
1248       // clang-format on
1249   };
1250 
1251   Reader::DecoderError error;
1252   Reader::Config config;
1253   config.error_code_out = &error;
1254 
1255   base::Optional<Value> cbor = Reader::Read(kInvalidUTF8, config);
1256   EXPECT_FALSE(cbor);
1257   EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);
1258 
1259   cbor = Reader::Read(kInvalidUTF8, config);
1260   EXPECT_FALSE(cbor);
1261   EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);
1262 
1263   config.allow_invalid_utf8 = true;
1264 
1265   cbor = Reader::Read(kInvalidUTF8, config);
1266   EXPECT_TRUE(cbor);
1267   EXPECT_EQ(Reader::DecoderError::CBOR_NO_ERROR, error);
1268   const cbor::Value& invalid_value = cbor->GetMap()
1269                                          .find(Value("x"))
1270                                          ->second.GetArray()[0]
1271                                          .GetMap()
1272                                          .find(Value("y"))
1273                                          ->second;
1274   ASSERT_TRUE(invalid_value.is_invalid_utf8());
1275   EXPECT_EQ(std::vector<uint8_t>({0xe2, 0x80}), invalid_value.GetInvalidUTF8());
1276 
1277   static const uint8_t kInvalidUTF8InMapKey[] = {
1278       // clang-format off
1279       0xa1,                    // map of length 1
1280         0x62, 0xe2, 0x80,      // invalid UTF-8 map key
1281         0x61, '.',             // "."
1282       // clang-format on
1283   };
1284 
1285   EXPECT_TRUE(config.allow_invalid_utf8);
1286   cbor = Reader::Read(kInvalidUTF8InMapKey, config);
1287   EXPECT_FALSE(cbor);
1288   EXPECT_EQ(Reader::DecoderError::INVALID_UTF8, error);
1289 }
1290 
1291 }  // namespace cbor
1292