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