• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 "encoding.h"
6 
7 #include <array>
8 #include <clocale>
9 #include <cmath>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iomanip>
13 #include <iostream>
14 #include <sstream>
15 #include <string>
16 
17 #include "encoding_test_helper.h"
18 
19 using testing::ElementsAreArray;
20 
21 namespace v8_inspector_protocol_encoding {
22 
23 class TestPlatform : public json::Platform {
StrToD(const char * str,double * result) const24   bool StrToD(const char* str, double* result) const override {
25     // This is not thread-safe
26     // (see https://en.cppreference.com/w/cpp/locale/setlocale)
27     // but good enough for a unittest.
28     const char* saved_locale = std::setlocale(LC_NUMERIC, nullptr);
29     char* end;
30     *result = std::strtod(str, &end);
31     std::setlocale(LC_NUMERIC, saved_locale);
32     if (errno == ERANGE) {
33       // errno must be reset, e.g. see the example here:
34       // https://en.cppreference.com/w/cpp/string/byte/strtof
35       errno = 0;
36       return false;
37     }
38     return end == str + strlen(str);
39   }
40 
DToStr(double value) const41   std::unique_ptr<char[]> DToStr(double value) const override {
42     std::stringstream ss;
43     ss.imbue(std::locale("C"));
44     ss << value;
45     std::string str = ss.str();
46     std::unique_ptr<char[]> result(new char[str.size() + 1]);
47     memcpy(result.get(), str.c_str(), str.size() + 1);
48     return result;
49   }
50 };
51 
GetTestPlatform()52 const json::Platform& GetTestPlatform() {
53   static TestPlatform* platform = new TestPlatform;
54   return *platform;
55 }
56 
57 // =============================================================================
58 // span - sequence of bytes
59 // =============================================================================
60 
61 template <typename T>
62 class SpanTest : public ::testing::Test {};
63 
64 using TestTypes = ::testing::Types<uint8_t, uint16_t>;
65 TYPED_TEST_SUITE(SpanTest, TestTypes);
66 
TYPED_TEST(SpanTest,Empty)67 TYPED_TEST(SpanTest, Empty) {
68   span<TypeParam> empty;
69   EXPECT_TRUE(empty.empty());
70   EXPECT_EQ(0u, empty.size());
71   EXPECT_EQ(0u, empty.size_bytes());
72   EXPECT_EQ(empty.begin(), empty.end());
73 }
74 
TYPED_TEST(SpanTest,SingleItem)75 TYPED_TEST(SpanTest, SingleItem) {
76   TypeParam single_item = 42;
77   span<TypeParam> singular(&single_item, 1);
78   EXPECT_FALSE(singular.empty());
79   EXPECT_EQ(1u, singular.size());
80   EXPECT_EQ(sizeof(TypeParam), singular.size_bytes());
81   EXPECT_EQ(singular.begin() + 1, singular.end());
82   EXPECT_EQ(42, singular[0]);
83 }
84 
TYPED_TEST(SpanTest,FiveItems)85 TYPED_TEST(SpanTest, FiveItems) {
86   std::vector<TypeParam> test_input = {31, 32, 33, 34, 35};
87   span<TypeParam> five_items(test_input.data(), 5);
88   EXPECT_FALSE(five_items.empty());
89   EXPECT_EQ(5u, five_items.size());
90   EXPECT_EQ(sizeof(TypeParam) * 5, five_items.size_bytes());
91   EXPECT_EQ(five_items.begin() + 5, five_items.end());
92   EXPECT_EQ(31, five_items[0]);
93   EXPECT_EQ(32, five_items[1]);
94   EXPECT_EQ(33, five_items[2]);
95   EXPECT_EQ(34, five_items[3]);
96   EXPECT_EQ(35, five_items[4]);
97   span<TypeParam> three_items = five_items.subspan(2);
98   EXPECT_EQ(3u, three_items.size());
99   EXPECT_EQ(33, three_items[0]);
100   EXPECT_EQ(34, three_items[1]);
101   EXPECT_EQ(35, three_items[2]);
102   span<TypeParam> two_items = five_items.subspan(2, 2);
103   EXPECT_EQ(2u, two_items.size());
104   EXPECT_EQ(33, two_items[0]);
105   EXPECT_EQ(34, two_items[1]);
106 }
107 
TEST(SpanFromTest,FromConstCharAndLiteral)108 TEST(SpanFromTest, FromConstCharAndLiteral) {
109   // Testing this is useful because strlen(nullptr) is undefined.
110   EXPECT_EQ(nullptr, SpanFrom(nullptr).data());
111   EXPECT_EQ(0u, SpanFrom(nullptr).size());
112 
113   const char* kEmpty = "";
114   EXPECT_EQ(kEmpty, reinterpret_cast<const char*>(SpanFrom(kEmpty).data()));
115   EXPECT_EQ(0u, SpanFrom(kEmpty).size());
116 
117   const char* kFoo = "foo";
118   EXPECT_EQ(kFoo, reinterpret_cast<const char*>(SpanFrom(kFoo).data()));
119   EXPECT_EQ(3u, SpanFrom(kFoo).size());
120 
121   EXPECT_EQ(3u, SpanFrom("foo").size());
122 }
123 
124 // =============================================================================
125 // Status and Error codes
126 // =============================================================================
127 
TEST(StatusTest,StatusToASCIIString)128 TEST(StatusTest, StatusToASCIIString) {
129   Status ok_status;
130   EXPECT_EQ("OK", ok_status.ToASCIIString());
131   Status json_error(Error::JSON_PARSER_COLON_EXPECTED, 42);
132   EXPECT_EQ("JSON: colon expected at position 42", json_error.ToASCIIString());
133   Status cbor_error(Error::CBOR_TRAILING_JUNK, 21);
134   EXPECT_EQ("CBOR: trailing junk at position 21", cbor_error.ToASCIIString());
135 }
136 
137 namespace cbor {
138 
139 // =============================================================================
140 // Detecting CBOR content
141 // =============================================================================
142 
TEST(IsCBORMessage,SomeSmokeTests)143 TEST(IsCBORMessage, SomeSmokeTests) {
144   std::vector<uint8_t> empty;
145   EXPECT_FALSE(IsCBORMessage(SpanFrom(empty)));
146   std::vector<uint8_t> hello = {'H', 'e', 'l', 'o', ' ', 't',
147                                 'h', 'e', 'r', 'e', '!'};
148   EXPECT_FALSE(IsCBORMessage(SpanFrom(hello)));
149   std::vector<uint8_t> example = {0xd8, 0x5a, 0, 0, 0, 0};
150   EXPECT_TRUE(IsCBORMessage(SpanFrom(example)));
151   std::vector<uint8_t> one = {0xd8, 0x5a, 0, 0, 0, 1, 1};
152   EXPECT_TRUE(IsCBORMessage(SpanFrom(one)));
153 }
154 
155 // =============================================================================
156 // Encoding individual CBOR items
157 // cbor::CBORTokenizer - for parsing individual CBOR items
158 // =============================================================================
159 
160 //
161 // EncodeInt32 / CBORTokenTag::INT32
162 //
TEST(EncodeDecodeInt32Test,Roundtrips23)163 TEST(EncodeDecodeInt32Test, Roundtrips23) {
164   // This roundtrips the int32_t value 23 through the pair of EncodeInt32 /
165   // CBORTokenizer; this is interesting since 23 is encoded as a single byte.
166   std::vector<uint8_t> encoded;
167   EncodeInt32(23, &encoded);
168   // first three bits: major type = 0; remaining five bits: additional info =
169   // value 23.
170   EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{23}}));
171 
172   // Reverse direction: decode with CBORTokenizer.
173   CBORTokenizer tokenizer(SpanFrom(encoded));
174   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
175   EXPECT_EQ(23, tokenizer.GetInt32());
176   tokenizer.Next();
177   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
178 }
179 
TEST(EncodeDecodeInt32Test,RoundtripsUint8)180 TEST(EncodeDecodeInt32Test, RoundtripsUint8) {
181   // This roundtrips the int32_t value 42 through the pair of EncodeInt32 /
182   // CBORTokenizer. This is different from Roundtrip23 because 42 is encoded
183   // in an extra byte after the initial one.
184   std::vector<uint8_t> encoded;
185   EncodeInt32(42, &encoded);
186   // first three bits: major type = 0;
187   // remaining five bits: additional info = 24, indicating payload is uint8.
188   EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 2>{{24, 42}}));
189 
190   // Reverse direction: decode with CBORTokenizer.
191   CBORTokenizer tokenizer(SpanFrom(encoded));
192   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
193   EXPECT_EQ(42, tokenizer.GetInt32());
194   tokenizer.Next();
195   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
196 }
197 
TEST(EncodeDecodeInt32Test,RoundtripsUint16)198 TEST(EncodeDecodeInt32Test, RoundtripsUint16) {
199   // 500 is encoded as a uint16 after the initial byte.
200   std::vector<uint8_t> encoded;
201   EncodeInt32(500, &encoded);
202   // 1 for initial byte, 2 for uint16.
203   EXPECT_EQ(3u, encoded.size());
204   // first three bits: major type = 0;
205   // remaining five bits: additional info = 25, indicating payload is uint16.
206   EXPECT_EQ(25, encoded[0]);
207   EXPECT_EQ(0x01, encoded[1]);
208   EXPECT_EQ(0xf4, encoded[2]);
209 
210   // Reverse direction: decode with CBORTokenizer.
211   CBORTokenizer tokenizer(SpanFrom(encoded));
212   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
213   EXPECT_EQ(500, tokenizer.GetInt32());
214   tokenizer.Next();
215   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
216 }
217 
TEST(EncodeDecodeInt32Test,RoundtripsInt32Max)218 TEST(EncodeDecodeInt32Test, RoundtripsInt32Max) {
219   // std::numeric_limits<int32_t> is encoded as a uint32 after the initial byte.
220   std::vector<uint8_t> encoded;
221   EncodeInt32(std::numeric_limits<int32_t>::max(), &encoded);
222   // 1 for initial byte, 4 for the uint32.
223   // first three bits: major type = 0;
224   // remaining five bits: additional info = 26, indicating payload is uint32.
225   EXPECT_THAT(
226       encoded,
227       ElementsAreArray(std::array<uint8_t, 5>{{26, 0x7f, 0xff, 0xff, 0xff}}));
228 
229   // Reverse direction: decode with CBORTokenizer.
230   CBORTokenizer tokenizer(SpanFrom(encoded));
231   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
232   EXPECT_EQ(std::numeric_limits<int32_t>::max(), tokenizer.GetInt32());
233   tokenizer.Next();
234   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
235 }
236 
TEST(EncodeDecodeInt32Test,RoundtripsInt32Min)237 TEST(EncodeDecodeInt32Test, RoundtripsInt32Min) {
238   // std::numeric_limits<int32_t> is encoded as a uint32 (4 unsigned bytes)
239   // after the initial byte, which effectively carries the sign by
240   // designating the token as NEGATIVE.
241   std::vector<uint8_t> encoded;
242   EncodeInt32(std::numeric_limits<int32_t>::min(), &encoded);
243   // 1 for initial byte, 4 for the uint32.
244   // first three bits: major type = 1;
245   // remaining five bits: additional info = 26, indicating payload is uint32.
246   EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 5>{
247                            {1 << 5 | 26, 0x7f, 0xff, 0xff, 0xff}}));
248 
249   // Reverse direction: decode with CBORTokenizer.
250   CBORTokenizer tokenizer(SpanFrom(encoded));
251   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
252   EXPECT_EQ(std::numeric_limits<int32_t>::min(), tokenizer.GetInt32());
253   // It's nice to see how the min int32 value reads in hex:
254   // That is, -1 minus the unsigned payload (0x7fffffff, see above).
255   int32_t expected = -1 - 0x7fffffff;
256   EXPECT_EQ(expected, tokenizer.GetInt32());
257   tokenizer.Next();
258   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
259 }
260 
TEST(EncodeDecodeInt32Test,CantRoundtripUint32)261 TEST(EncodeDecodeInt32Test, CantRoundtripUint32) {
262   // 0xdeadbeef is a value which does not fit below
263   // std::numerical_limits<int32_t>::max(), so we can't encode
264   // it with EncodeInt32. However, CBOR does support this, so we
265   // encode it here manually with the internal routine, just to observe
266   // that it's considered an invalid int32 by CBORTokenizer.
267   std::vector<uint8_t> encoded;
268   internals::WriteTokenStart(MajorType::UNSIGNED, 0xdeadbeef, &encoded);
269   // 1 for initial byte, 4 for the uint32.
270   // first three bits: major type = 0;
271   // remaining five bits: additional info = 26, indicating payload is uint32.
272   EXPECT_THAT(
273       encoded,
274       ElementsAreArray(std::array<uint8_t, 5>{{26, 0xde, 0xad, 0xbe, 0xef}}));
275 
276   // Now try to decode; we treat this as an invalid INT32.
277   CBORTokenizer tokenizer(SpanFrom(encoded));
278   // 0xdeadbeef is > std::numerical_limits<int32_t>::max().
279   EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
280   EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error);
281 }
282 
TEST(EncodeDecodeInt32Test,DecodeErrorCases)283 TEST(EncodeDecodeInt32Test, DecodeErrorCases) {
284   struct TestCase {
285     std::vector<uint8_t> data;
286     std::string msg;
287   };
288   std::vector<TestCase> tests{{
289       TestCase{
290           {24},
291           "additional info = 24 would require 1 byte of payload (but it's 0)"},
292       TestCase{{27, 0xaa, 0xbb, 0xcc},
293                "additional info = 27 would require 8 bytes of payload (but "
294                "it's 3)"},
295       TestCase{{29}, "additional info = 29 isn't recognized"},
296       TestCase{{1 << 5 | 27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
297                "Max UINT64 payload is outside the allowed range"},
298       TestCase{{1 << 5 | 26, 0xff, 0xff, 0xff, 0xff},
299                "Max UINT32 payload is outside the allowed range"},
300       TestCase{{1 << 5 | 26, 0x80, 0x00, 0x00, 0x00},
301                "UINT32 payload w/ high bit set is outside the allowed range"},
302   }};
303   for (const TestCase& test : tests) {
304     SCOPED_TRACE(test.msg);
305     CBORTokenizer tokenizer(SpanFrom(test.data));
306     EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
307     EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error);
308   }
309 }
310 
TEST(EncodeDecodeInt32Test,RoundtripsMinus24)311 TEST(EncodeDecodeInt32Test, RoundtripsMinus24) {
312   // This roundtrips the int32_t value -24 through the pair of EncodeInt32 /
313   // CBORTokenizer; this is interesting since -24 is encoded as
314   // a single byte as NEGATIVE, and it tests the specific encoding
315   // (note how for unsigned the single byte covers values up to 23).
316   // Additional examples are covered in RoundtripsAdditionalExamples.
317   std::vector<uint8_t> encoded;
318   EncodeInt32(-24, &encoded);
319   // first three bits: major type = 1; remaining five bits: additional info =
320   // value 23.
321   EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{1 << 5 | 23}}));
322 
323   // Reverse direction: decode with CBORTokenizer.
324   CBORTokenizer tokenizer(SpanFrom(encoded));
325   EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
326   EXPECT_EQ(-24, tokenizer.GetInt32());
327   tokenizer.Next();
328   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
329 }
330 
TEST(EncodeDecodeInt32Test,RoundtripsAdditionalNegativeExamples)331 TEST(EncodeDecodeInt32Test, RoundtripsAdditionalNegativeExamples) {
332   std::vector<int32_t> examples = {-1,
333                                    -10,
334                                    -24,
335                                    -25,
336                                    -300,
337                                    -30000,
338                                    -300 * 1000,
339                                    -1000 * 1000,
340                                    -1000 * 1000 * 1000,
341                                    std::numeric_limits<int32_t>::min()};
342   for (int32_t example : examples) {
343     SCOPED_TRACE(std::string("example ") + std::to_string(example));
344     std::vector<uint8_t> encoded;
345     EncodeInt32(example, &encoded);
346     CBORTokenizer tokenizer(SpanFrom(encoded));
347     EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
348     EXPECT_EQ(example, tokenizer.GetInt32());
349     tokenizer.Next();
350     EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
351   }
352 }
353 
354 //
355 // EncodeString16 / CBORTokenTag::STRING16
356 //
TEST(EncodeDecodeString16Test,RoundtripsEmpty)357 TEST(EncodeDecodeString16Test, RoundtripsEmpty) {
358   // This roundtrips the empty utf16 string through the pair of EncodeString16 /
359   // CBORTokenizer.
360   std::vector<uint8_t> encoded;
361   EncodeString16(span<uint16_t>(), &encoded);
362   EXPECT_EQ(1u, encoded.size());
363   // first three bits: major type = 2; remaining five bits: additional info =
364   // size 0.
365   EXPECT_EQ(2 << 5, encoded[0]);
366 
367   // Reverse direction: decode with CBORTokenizer.
368   CBORTokenizer tokenizer(SpanFrom(encoded));
369   EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag());
370   span<uint8_t> decoded_string16_wirerep = tokenizer.GetString16WireRep();
371   EXPECT_TRUE(decoded_string16_wirerep.empty());
372   tokenizer.Next();
373   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
374 }
375 
376 // On the wire, we STRING16 is encoded as little endian (least
377 // significant byte first). The host may or may not be little endian,
378 // so this routine follows the advice in
379 // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html.
String16WireRepToHost(span<uint8_t> in)380 std::vector<uint16_t> String16WireRepToHost(span<uint8_t> in) {
381   // must be even number of bytes.
382   CHECK_EQ(in.size() & 1, 0u);
383   std::vector<uint16_t> host_out;
384   for (size_t ii = 0; ii < in.size(); ii += 2)
385     host_out.push_back(in[ii + 1] << 8 | in[ii]);
386   return host_out;
387 }
388 
TEST(EncodeDecodeString16Test,RoundtripsHelloWorld)389 TEST(EncodeDecodeString16Test, RoundtripsHelloWorld) {
390   // This roundtrips the hello world message which is given here in utf16
391   // characters. 0xd83c, 0xdf0e: UTF16 encoding for the "Earth Globe Americas"
392   // character, ��.
393   std::array<uint16_t, 10> msg{
394       {'H', 'e', 'l', 'l', 'o', ',', ' ', 0xd83c, 0xdf0e, '.'}};
395   std::vector<uint8_t> encoded;
396   EncodeString16(span<uint16_t>(msg.data(), msg.size()), &encoded);
397   // This will be encoded as BYTE_STRING of length 20, so the 20 is encoded in
398   // the additional info part of the initial byte. Payload is two bytes for each
399   // UTF16 character.
400   uint8_t initial_byte = /*major type=*/2 << 5 | /*additional info=*/20;
401   std::array<uint8_t, 21> encoded_expected = {
402       {initial_byte, 'H', 0,   'e', 0,    'l',  0,    'l',  0,   'o', 0,
403        ',',          0,   ' ', 0,   0x3c, 0xd8, 0x0e, 0xdf, '.', 0}};
404   EXPECT_THAT(encoded, ElementsAreArray(encoded_expected));
405 
406   // Now decode to complete the roundtrip.
407   CBORTokenizer tokenizer(SpanFrom(encoded));
408   EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag());
409   std::vector<uint16_t> decoded =
410       String16WireRepToHost(tokenizer.GetString16WireRep());
411   EXPECT_THAT(decoded, ElementsAreArray(msg));
412   tokenizer.Next();
413   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
414 
415   // For bonus points, we look at the decoded message in UTF8 as well so we can
416   // easily see it on the terminal screen.
417   std::string utf8_decoded = UTF16ToUTF8(SpanFrom(decoded));
418   EXPECT_EQ("Hello, ��.", utf8_decoded);
419 }
420 
TEST(EncodeDecodeString16Test,Roundtrips500)421 TEST(EncodeDecodeString16Test, Roundtrips500) {
422   // We roundtrip a message that has 250 16 bit values. Each of these are just
423   // set to their index. 250 is interesting because the cbor spec uses a
424   // BYTE_STRING of length 500 for one of their examples of how to encode the
425   // start of it (section 2.1) so it's easy for us to look at the first three
426   // bytes closely.
427   std::vector<uint16_t> two_fifty;
428   for (uint16_t ii = 0; ii < 250; ++ii)
429     two_fifty.push_back(ii);
430   std::vector<uint8_t> encoded;
431   EncodeString16(span<uint16_t>(two_fifty.data(), two_fifty.size()), &encoded);
432   EXPECT_EQ(3u + 250u * 2, encoded.size());
433   // Now check the first three bytes:
434   // Major type: 2 (BYTE_STRING)
435   // Additional information: 25, indicating size is represented by 2 bytes.
436   // Bytes 1 and 2 encode 500 (0x01f4).
437   EXPECT_EQ(2 << 5 | 25, encoded[0]);
438   EXPECT_EQ(0x01, encoded[1]);
439   EXPECT_EQ(0xf4, encoded[2]);
440 
441   // Now decode to complete the roundtrip.
442   CBORTokenizer tokenizer(SpanFrom(encoded));
443   EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag());
444   std::vector<uint16_t> decoded =
445       String16WireRepToHost(tokenizer.GetString16WireRep());
446   EXPECT_THAT(decoded, ElementsAreArray(two_fifty));
447   tokenizer.Next();
448   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
449 }
450 
TEST(EncodeDecodeString16Test,ErrorCases)451 TEST(EncodeDecodeString16Test, ErrorCases) {
452   struct TestCase {
453     std::vector<uint8_t> data;
454     std::string msg;
455   };
456   std::vector<TestCase> tests{
457       {TestCase{{2 << 5 | 1, 'a'},
458                 "length must be divisible by 2 (but it's 1)"},
459        TestCase{{2 << 5 | 29}, "additional info = 29 isn't recognized"},
460        TestCase{{2 << 5 | 9, 1, 2, 3, 4, 5, 6, 7, 8},
461                 "length (9) points just past the end of the test case"},
462        TestCase{{2 << 5 | 27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463                  'a', 'b', 'c'},
464                 "large length pointing past the end of the test case"}}};
465   for (const TestCase& test : tests) {
466     SCOPED_TRACE(test.msg);
467     CBORTokenizer tokenizer(SpanFrom(test.data));
468     EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
469     EXPECT_EQ(Error::CBOR_INVALID_STRING16, tokenizer.Status().error);
470   }
471 }
472 
473 //
474 // EncodeString8 / CBORTokenTag::STRING8
475 //
TEST(EncodeDecodeString8Test,RoundtripsHelloWorld)476 TEST(EncodeDecodeString8Test, RoundtripsHelloWorld) {
477   // This roundtrips the hello world message which is given here in utf8
478   // characters. �� is a four byte utf8 character.
479   std::string utf8_msg = "Hello, ��.";
480   std::vector<uint8_t> msg(utf8_msg.begin(), utf8_msg.end());
481   std::vector<uint8_t> encoded;
482   EncodeString8(SpanFrom(utf8_msg), &encoded);
483   // This will be encoded as STRING of length 12, so the 12 is encoded in
484   // the additional info part of the initial byte. Payload is one byte per
485   // utf8 byte.
486   uint8_t initial_byte = /*major type=*/3 << 5 | /*additional info=*/12;
487   std::array<uint8_t, 13> encoded_expected = {{initial_byte, 'H', 'e', 'l', 'l',
488                                                'o', ',', ' ', 0xF0, 0x9f, 0x8c,
489                                                0x8e, '.'}};
490   EXPECT_THAT(encoded, ElementsAreArray(encoded_expected));
491 
492   // Now decode to complete the roundtrip.
493   CBORTokenizer tokenizer(SpanFrom(encoded));
494   EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag());
495   std::vector<uint8_t> decoded(tokenizer.GetString8().begin(),
496                                tokenizer.GetString8().end());
497   EXPECT_THAT(decoded, ElementsAreArray(msg));
498   tokenizer.Next();
499   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
500 }
501 
TEST(EncodeDecodeString8Test,ErrorCases)502 TEST(EncodeDecodeString8Test, ErrorCases) {
503   struct TestCase {
504     std::vector<uint8_t> data;
505     std::string msg;
506   };
507   std::vector<TestCase> tests{
508       {TestCase{{3 << 5 | 29}, "additional info = 29 isn't recognized"},
509        TestCase{{3 << 5 | 9, 1, 2, 3, 4, 5, 6, 7, 8},
510                 "length (9) points just past the end of the test case"},
511        TestCase{{3 << 5 | 27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512                  'a', 'b', 'c'},
513                 "large length pointing past the end of the test case"}}};
514   for (const TestCase& test : tests) {
515     SCOPED_TRACE(test.msg);
516     CBORTokenizer tokenizer(SpanFrom(test.data));
517     EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
518     EXPECT_EQ(Error::CBOR_INVALID_STRING8, tokenizer.Status().error);
519   }
520 }
521 
TEST(EncodeFromLatin1Test,ConvertsToUTF8IfNeeded)522 TEST(EncodeFromLatin1Test, ConvertsToUTF8IfNeeded) {
523   std::vector<std::pair<std::string, std::string>> examples = {
524       {"Hello, world.", "Hello, world."},
525       {"Above: \xDC"
526        "ber",
527        "Above: Über"},
528       {"\xA5 500 are about \xA3 3.50; a y with umlaut is \xFF",
529        "¥ 500 are about £ 3.50; a y with umlaut is ÿ"}};
530 
531   for (const auto& example : examples) {
532     const std::string& latin1 = example.first;
533     const std::string& expected_utf8 = example.second;
534     std::vector<uint8_t> encoded;
535     EncodeFromLatin1(SpanFrom(latin1), &encoded);
536     CBORTokenizer tokenizer(SpanFrom(encoded));
537     EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag());
538     std::vector<uint8_t> decoded(tokenizer.GetString8().begin(),
539                                  tokenizer.GetString8().end());
540     std::string decoded_str(decoded.begin(), decoded.end());
541     EXPECT_THAT(decoded_str, testing::Eq(expected_utf8));
542   }
543 }
544 
TEST(EncodeFromUTF16Test,ConvertsToUTF8IfEasy)545 TEST(EncodeFromUTF16Test, ConvertsToUTF8IfEasy) {
546   std::vector<uint16_t> ascii = {'e', 'a', 's', 'y'};
547   std::vector<uint8_t> encoded;
548   EncodeFromUTF16(span<uint16_t>(ascii.data(), ascii.size()), &encoded);
549 
550   CBORTokenizer tokenizer(SpanFrom(encoded));
551   EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag());
552   std::vector<uint8_t> decoded(tokenizer.GetString8().begin(),
553                                tokenizer.GetString8().end());
554   std::string decoded_str(decoded.begin(), decoded.end());
555   EXPECT_THAT(decoded_str, testing::Eq("easy"));
556 }
557 
TEST(EncodeFromUTF16Test,EncodesAsString16IfNeeded)558 TEST(EncodeFromUTF16Test, EncodesAsString16IfNeeded) {
559   // Since this message contains non-ASCII characters, the routine is
560   // forced to encode as UTF16. We see this below by checking that the
561   // token tag is STRING16.
562   std::vector<uint16_t> msg = {'H', 'e', 'l',    'l',    'o',
563                                ',', ' ', 0xd83c, 0xdf0e, '.'};
564   std::vector<uint8_t> encoded;
565   EncodeFromUTF16(span<uint16_t>(msg.data(), msg.size()), &encoded);
566 
567   CBORTokenizer tokenizer(SpanFrom(encoded));
568   EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag());
569   std::vector<uint16_t> decoded =
570       String16WireRepToHost(tokenizer.GetString16WireRep());
571   std::string utf8_decoded = UTF16ToUTF8(SpanFrom(decoded));
572   EXPECT_EQ("Hello, ��.", utf8_decoded);
573 }
574 
575 //
576 // EncodeBinary / CBORTokenTag::BINARY
577 //
TEST(EncodeDecodeBinaryTest,RoundtripsHelloWorld)578 TEST(EncodeDecodeBinaryTest, RoundtripsHelloWorld) {
579   std::vector<uint8_t> binary = {'H', 'e', 'l', 'l', 'o', ',', ' ',
580                                  'w', 'o', 'r', 'l', 'd', '.'};
581   std::vector<uint8_t> encoded;
582   EncodeBinary(span<uint8_t>(binary.data(), binary.size()), &encoded);
583   // So, on the wire we see that the binary blob travels unmodified.
584   EXPECT_THAT(
585       encoded,
586       ElementsAreArray(std::array<uint8_t, 15>{
587           {(6 << 5 | 22),  // tag 22 indicating base64 interpretation in JSON
588            (2 << 5 | 13),  // BYTE_STRING (type 2) of length 13
589            'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}}));
590   std::vector<uint8_t> decoded;
591   CBORTokenizer tokenizer(SpanFrom(encoded));
592   EXPECT_EQ(CBORTokenTag::BINARY, tokenizer.TokenTag());
593   EXPECT_EQ(0, static_cast<int>(tokenizer.Status().error));
594   decoded = std::vector<uint8_t>(tokenizer.GetBinary().begin(),
595                                  tokenizer.GetBinary().end());
596   EXPECT_THAT(decoded, ElementsAreArray(binary));
597   tokenizer.Next();
598   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
599 }
600 
TEST(EncodeDecodeBinaryTest,ErrorCases)601 TEST(EncodeDecodeBinaryTest, ErrorCases) {
602   struct TestCase {
603     std::vector<uint8_t> data;
604     std::string msg;
605   };
606   std::vector<TestCase> tests{{TestCase{
607       {6 << 5 | 22,  // tag 22 indicating base64 interpretation in JSON
608        2 << 5 | 27,  // BYTE_STRING (type 2), followed by 8 bytes length
609        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
610       "large length pointing past the end of the test case"}}};
611   for (const TestCase& test : tests) {
612     SCOPED_TRACE(test.msg);
613     CBORTokenizer tokenizer(SpanFrom(test.data));
614     EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
615     EXPECT_EQ(Error::CBOR_INVALID_BINARY, tokenizer.Status().error);
616   }
617 }
618 
619 //
620 // EncodeDouble / CBORTokenTag::DOUBLE
621 //
TEST(EncodeDecodeDoubleTest,RoundtripsWikipediaExample)622 TEST(EncodeDecodeDoubleTest, RoundtripsWikipediaExample) {
623   // https://en.wikipedia.org/wiki/Double-precision_floating-point_format
624   // provides the example of a hex representation 3FD5 5555 5555 5555, which
625   // approximates 1/3.
626 
627   const double kOriginalValue = 1.0 / 3;
628   std::vector<uint8_t> encoded;
629   EncodeDouble(kOriginalValue, &encoded);
630   // first three bits: major type = 7; remaining five bits: additional info =
631   // value 27. This is followed by 8 bytes of payload (which match Wikipedia).
632   EXPECT_THAT(
633       encoded,
634       ElementsAreArray(std::array<uint8_t, 9>{
635           {7 << 5 | 27, 0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}}));
636 
637   // Reverse direction: decode and compare with original value.
638   CBORTokenizer tokenizer(SpanFrom(encoded));
639   EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag());
640   EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(kOriginalValue));
641   tokenizer.Next();
642   EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
643 }
644 
TEST(EncodeDecodeDoubleTest,RoundtripsAdditionalExamples)645 TEST(EncodeDecodeDoubleTest, RoundtripsAdditionalExamples) {
646   std::vector<double> examples = {0.0,
647                                   1.0,
648                                   -1.0,
649                                   3.1415,
650                                   std::numeric_limits<double>::min(),
651                                   std::numeric_limits<double>::max(),
652                                   std::numeric_limits<double>::infinity(),
653                                   std::numeric_limits<double>::quiet_NaN()};
654   for (double example : examples) {
655     SCOPED_TRACE(std::string("example ") + std::to_string(example));
656     std::vector<uint8_t> encoded;
657     EncodeDouble(example, &encoded);
658     CBORTokenizer tokenizer(SpanFrom(encoded));
659     EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag());
660     if (std::isnan(example))
661       EXPECT_TRUE(std::isnan(tokenizer.GetDouble()));
662     else
663       EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(example));
664     tokenizer.Next();
665     EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
666   }
667 }
668 
669 // =============================================================================
670 // cbor::NewCBOREncoder - for encoding from a streaming parser
671 // =============================================================================
672 
EncodeUTF8ForTest(const std::string & key,std::vector<uint8_t> * out)673 void EncodeUTF8ForTest(const std::string& key, std::vector<uint8_t>* out) {
674   EncodeString8(SpanFrom(key), out);
675 }
TEST(JSONToCBOREncoderTest,SevenBitStrings)676 TEST(JSONToCBOREncoderTest, SevenBitStrings) {
677   // When a string can be represented as 7 bit ASCII, the encoder will use the
678   // STRING (major Type 3) type, so the actual characters end up as bytes on the
679   // wire.
680   std::vector<uint8_t> encoded;
681   Status status;
682   std::unique_ptr<StreamingParserHandler> encoder =
683       NewCBOREncoder(&encoded, &status);
684   std::vector<uint16_t> utf16 = {'f', 'o', 'o'};
685   encoder->HandleString16(span<uint16_t>(utf16.data(), utf16.size()));
686   EXPECT_EQ(Error::OK, status.error);
687   // Here we assert that indeed, seven bit strings are represented as
688   // bytes on the wire, "foo" is just "foo".
689   EXPECT_THAT(encoded,
690               ElementsAreArray(std::array<uint8_t, 4>{
691                   {/*major type 3*/ 3 << 5 | /*length*/ 3, 'f', 'o', 'o'}}));
692 }
693 
TEST(JsonCborRoundtrip,EncodingDecoding)694 TEST(JsonCborRoundtrip, EncodingDecoding) {
695   // Hits all the cases except binary and error in StreamingParserHandler, first
696   // parsing a JSON message into CBOR, then parsing it back from CBOR into JSON.
697   std::string json =
698       "{"
699       "\"string\":\"Hello, \\ud83c\\udf0e.\","
700       "\"double\":3.1415,"
701       "\"int\":1,"
702       "\"negative int\":-1,"
703       "\"bool\":true,"
704       "\"null\":null,"
705       "\"array\":[1,2,3]"
706       "}";
707   std::vector<uint8_t> encoded;
708   Status status;
709   std::unique_ptr<StreamingParserHandler> encoder =
710       NewCBOREncoder(&encoded, &status);
711   span<uint8_t> ascii_in = SpanFrom(json);
712   json::ParseJSON(GetTestPlatform(), ascii_in, encoder.get());
713   std::vector<uint8_t> expected = {
714       0xd8,            // envelope
715       0x5a,            // byte string with 32 bit length
716       0,    0, 0, 94,  // length is 94 bytes
717   };
718   expected.push_back(0xbf);  // indef length map start
719   EncodeString8(SpanFrom("string"), &expected);
720   // This is followed by the encoded string for "Hello, ��."
721   // So, it's the same bytes that we tested above in
722   // EncodeDecodeString16Test.RoundtripsHelloWorld.
723   expected.push_back(/*major type=*/2 << 5 | /*additional info=*/20);
724   for (uint8_t ch : std::array<uint8_t, 20>{
725            {'H', 0, 'e', 0, 'l',  0,    'l',  0,    'o', 0,
726             ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}})
727     expected.push_back(ch);
728   EncodeString8(SpanFrom("double"), &expected);
729   EncodeDouble(3.1415, &expected);
730   EncodeString8(SpanFrom("int"), &expected);
731   EncodeInt32(1, &expected);
732   EncodeString8(SpanFrom("negative int"), &expected);
733   EncodeInt32(-1, &expected);
734   EncodeString8(SpanFrom("bool"), &expected);
735   expected.push_back(7 << 5 | 21);  // RFC 7049 Section 2.3, Table 2: true
736   EncodeString8(SpanFrom("null"), &expected);
737   expected.push_back(7 << 5 | 22);  // RFC 7049 Section 2.3, Table 2: null
738   EncodeString8(SpanFrom("array"), &expected);
739   expected.push_back(0xd8);  // envelope
740   expected.push_back(0x5a);  // byte string with 32 bit length
741   // the length is 5 bytes (that's up to end indef length array below).
742   for (uint8_t ch : std::array<uint8_t, 4>{{0, 0, 0, 5}})
743     expected.push_back(ch);
744   expected.push_back(0x9f);  // RFC 7049 Section 2.2.1, indef length array start
745   expected.push_back(1);     // Three UNSIGNED values (easy since Major Type 0)
746   expected.push_back(2);
747   expected.push_back(3);
748   expected.push_back(0xff);  // End indef length array
749   expected.push_back(0xff);  // End indef length map
750   EXPECT_TRUE(status.ok());
751   EXPECT_THAT(encoded, ElementsAreArray(expected));
752 
753   // And now we roundtrip, decoding the message we just encoded.
754   std::string decoded;
755   std::unique_ptr<StreamingParserHandler> json_encoder =
756       NewJSONEncoder(&GetTestPlatform(), &decoded, &status);
757   ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_encoder.get());
758   EXPECT_EQ(Error::OK, status.error);
759   EXPECT_EQ(json, decoded);
760 }
761 
TEST(JsonCborRoundtrip,MoreRoundtripExamples)762 TEST(JsonCborRoundtrip, MoreRoundtripExamples) {
763   std::vector<std::string> examples = {
764       // Tests that after closing a nested objects, additional key/value pairs
765       // are considered.
766       "{\"foo\":{\"bar\":1},\"baz\":2}", "{\"foo\":[1,2,3],\"baz\":2}"};
767   for (const std::string& json : examples) {
768     SCOPED_TRACE(std::string("example: ") + json);
769     std::vector<uint8_t> encoded;
770     Status status;
771     std::unique_ptr<StreamingParserHandler> encoder =
772         NewCBOREncoder(&encoded, &status);
773     span<uint8_t> ascii_in = SpanFrom(json);
774     ParseJSON(GetTestPlatform(), ascii_in, encoder.get());
775     std::string decoded;
776     std::unique_ptr<StreamingParserHandler> json_writer =
777         NewJSONEncoder(&GetTestPlatform(), &decoded, &status);
778     ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get());
779     EXPECT_EQ(Error::OK, status.error);
780     EXPECT_EQ(json, decoded);
781   }
782 }
783 
TEST(JSONToCBOREncoderTest,HelloWorldBinary_WithTripToJson)784 TEST(JSONToCBOREncoderTest, HelloWorldBinary_WithTripToJson) {
785   // The StreamingParserHandler::HandleBinary is a special case: The JSON parser
786   // will never call this method, because JSON does not natively support the
787   // binary type. So, we can't fully roundtrip. However, the other direction
788   // works: binary will be rendered in JSON, as a base64 string. So, we make
789   // calls to the encoder directly here, to construct a message, and one of
790   // these calls is ::HandleBinary, to which we pass a "binary" string
791   // containing "Hello, world.".
792   std::vector<uint8_t> encoded;
793   Status status;
794   std::unique_ptr<StreamingParserHandler> encoder =
795       NewCBOREncoder(&encoded, &status);
796   encoder->HandleMapBegin();
797   // Emit a key.
798   std::vector<uint16_t> key = {'f', 'o', 'o'};
799   encoder->HandleString16(SpanFrom(key));
800   // Emit the binary payload, an arbitrary array of bytes that happens to
801   // be the ascii message "Hello, world.".
802   encoder->HandleBinary(SpanFrom(std::vector<uint8_t>{
803       'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}));
804   encoder->HandleMapEnd();
805   EXPECT_EQ(Error::OK, status.error);
806 
807   // Now drive the json writer via the CBOR decoder.
808   std::string decoded;
809   std::unique_ptr<StreamingParserHandler> json_writer =
810       NewJSONEncoder(&GetTestPlatform(), &decoded, &status);
811   ParseCBOR(SpanFrom(encoded), json_writer.get());
812   EXPECT_EQ(Error::OK, status.error);
813   EXPECT_EQ(Status::npos(), status.pos);
814   // "Hello, world." in base64 is "SGVsbG8sIHdvcmxkLg==".
815   EXPECT_EQ("{\"foo\":\"SGVsbG8sIHdvcmxkLg==\"}", decoded);
816 }
817 
818 // =============================================================================
819 // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
820 // =============================================================================
821 
TEST(ParseCBORTest,ParseEmptyCBORMessage)822 TEST(ParseCBORTest, ParseEmptyCBORMessage) {
823   // An envelope starting with 0xd8, 0x5a, with the byte length
824   // of 2, containing a map that's empty (0xbf for map
825   // start, and 0xff for map end).
826   std::vector<uint8_t> in = {0xd8, 0x5a, 0, 0, 0, 2, 0xbf, 0xff};
827   std::string out;
828   Status status;
829   std::unique_ptr<StreamingParserHandler> json_writer =
830       NewJSONEncoder(&GetTestPlatform(), &out, &status);
831   ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get());
832   EXPECT_EQ(Error::OK, status.error);
833   EXPECT_EQ("{}", out);
834 }
835 
TEST(ParseCBORTest,ParseCBORHelloWorld)836 TEST(ParseCBORTest, ParseCBORHelloWorld) {
837   const uint8_t kPayloadLen = 27;
838   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen};
839   bytes.push_back(0xbf);                            // start indef length map.
840   EncodeString8(SpanFrom("msg"), &bytes);           // key: msg
841   // Now write the value, the familiar "Hello, ��." where the globe is expressed
842   // as two utf16 chars.
843   bytes.push_back(/*major type=*/2 << 5 | /*additional info=*/20);
844   for (uint8_t ch : std::array<uint8_t, 20>{
845            {'H', 0, 'e', 0, 'l',  0,    'l',  0,    'o', 0,
846             ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}})
847     bytes.push_back(ch);
848   bytes.push_back(0xff);  // stop byte
849   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
850 
851   std::string out;
852   Status status;
853   std::unique_ptr<StreamingParserHandler> json_writer =
854       NewJSONEncoder(&GetTestPlatform(), &out, &status);
855   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
856   EXPECT_EQ(Error::OK, status.error);
857   EXPECT_EQ("{\"msg\":\"Hello, \\ud83c\\udf0e.\"}", out);
858 }
859 
TEST(ParseCBORTest,UTF8IsSupportedInKeys)860 TEST(ParseCBORTest, UTF8IsSupportedInKeys) {
861   const uint8_t kPayloadLen = 11;
862   std::vector<uint8_t> bytes = {cbor::InitialByteForEnvelope(),
863                                 cbor::InitialByteFor32BitLengthByteString(),
864                                 0,
865                                 0,
866                                 0,
867                                 kPayloadLen};
868   bytes.push_back(cbor::EncodeIndefiniteLengthMapStart());
869   // Two UTF16 chars.
870   EncodeString8(SpanFrom("��"), &bytes);
871   // Can be encoded as a single UTF16 char.
872   EncodeString8(SpanFrom("☾"), &bytes);
873   bytes.push_back(cbor::EncodeStop());
874   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
875 
876   std::string out;
877   Status status;
878   std::unique_ptr<StreamingParserHandler> json_writer =
879       NewJSONEncoder(&GetTestPlatform(), &out, &status);
880   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
881   EXPECT_EQ(Error::OK, status.error);
882   EXPECT_EQ("{\"\\ud83c\\udf0e\":\"\\u263e\"}", out);
883 }
884 
TEST(ParseCBORTest,NoInputError)885 TEST(ParseCBORTest, NoInputError) {
886   std::vector<uint8_t> in = {};
887   std::string out;
888   Status status;
889   std::unique_ptr<StreamingParserHandler> json_writer =
890       NewJSONEncoder(&GetTestPlatform(), &out, &status);
891   ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get());
892   EXPECT_EQ(Error::CBOR_NO_INPUT, status.error);
893   EXPECT_EQ("", out);
894 }
895 
TEST(ParseCBORTest,InvalidStartByteError)896 TEST(ParseCBORTest, InvalidStartByteError) {
897   // Here we test that some actual json, which usually starts with {,
898   // is not considered CBOR. CBOR messages must start with 0x5a, the
899   // envelope start byte.
900   std::string json = "{\"msg\": \"Hello, world.\"}";
901   std::string out;
902   Status status;
903   std::unique_ptr<StreamingParserHandler> json_writer =
904       NewJSONEncoder(&GetTestPlatform(), &out, &status);
905   ParseCBOR(SpanFrom(json), json_writer.get());
906   EXPECT_EQ(Error::CBOR_INVALID_START_BYTE, status.error);
907   EXPECT_EQ("", out);
908 }
909 
TEST(ParseCBORTest,UnexpectedEofExpectedValueError)910 TEST(ParseCBORTest, UnexpectedEofExpectedValueError) {
911   constexpr uint8_t kPayloadLen = 5;
912   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
913                                 0xbf};                             // map start
914   // A key; so value would be next.
915   EncodeString8(SpanFrom("key"), &bytes);
916   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
917   std::string out;
918   Status status;
919   std::unique_ptr<StreamingParserHandler> json_writer =
920       NewJSONEncoder(&GetTestPlatform(), &out, &status);
921   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
922   EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, status.error);
923   EXPECT_EQ(bytes.size(), status.pos);
924   EXPECT_EQ("", out);
925 }
926 
TEST(ParseCBORTest,UnexpectedEofInArrayError)927 TEST(ParseCBORTest, UnexpectedEofInArrayError) {
928   constexpr uint8_t kPayloadLen = 8;
929   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
930                                 0xbf};  // The byte for starting a map.
931   // A key; so value would be next.
932   EncodeString8(SpanFrom("array"), &bytes);
933   bytes.push_back(0x9f);  // byte for indefinite length array start.
934   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
935   std::string out;
936   Status status;
937   std::unique_ptr<StreamingParserHandler> json_writer =
938       NewJSONEncoder(&GetTestPlatform(), &out, &status);
939   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
940   EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, status.error);
941   EXPECT_EQ(bytes.size(), status.pos);
942   EXPECT_EQ("", out);
943 }
944 
TEST(ParseCBORTest,UnexpectedEofInMapError)945 TEST(ParseCBORTest, UnexpectedEofInMapError) {
946   constexpr uint8_t kPayloadLen = 1;
947   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
948                                 0xbf};  // The byte for starting a map.
949   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
950   std::string out;
951   Status status;
952   std::unique_ptr<StreamingParserHandler> json_writer =
953       NewJSONEncoder(&GetTestPlatform(), &out, &status);
954   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
955   EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_MAP, status.error);
956   EXPECT_EQ(7u, status.pos);
957   EXPECT_EQ("", out);
958 }
959 
TEST(ParseCBORTest,InvalidMapKeyError)960 TEST(ParseCBORTest, InvalidMapKeyError) {
961   constexpr uint8_t kPayloadLen = 2;
962   std::vector<uint8_t> bytes = {0xd8,       0x5a, 0,
963                                 0,          0,    kPayloadLen,  // envelope
964                                 0xbf,                           // map start
965                                 7 << 5 | 22};  // null (not a valid map key)
966   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
967   std::string out;
968   Status status;
969   std::unique_ptr<StreamingParserHandler> json_writer =
970       NewJSONEncoder(&GetTestPlatform(), &out, &status);
971   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
972   EXPECT_EQ(Error::CBOR_INVALID_MAP_KEY, status.error);
973   EXPECT_EQ(7u, status.pos);
974   EXPECT_EQ("", out);
975 }
976 
MakeNestedCBOR(int depth)977 std::vector<uint8_t> MakeNestedCBOR(int depth) {
978   std::vector<uint8_t> bytes;
979   std::vector<EnvelopeEncoder> envelopes;
980   for (int ii = 0; ii < depth; ++ii) {
981     envelopes.emplace_back();
982     envelopes.back().EncodeStart(&bytes);
983     bytes.push_back(0xbf);  // indef length map start
984     EncodeString8(SpanFrom("key"), &bytes);
985   }
986   EncodeString8(SpanFrom("innermost_value"), &bytes);
987   for (int ii = 0; ii < depth; ++ii) {
988     bytes.push_back(0xff);  // stop byte, finishes map.
989     envelopes.back().EncodeStop(&bytes);
990     envelopes.pop_back();
991   }
992   return bytes;
993 }
994 
TEST(ParseCBORTest,StackLimitExceededError)995 TEST(ParseCBORTest, StackLimitExceededError) {
996   {  // Depth 3: no stack limit exceeded error and is easy to inspect.
997     std::vector<uint8_t> bytes = MakeNestedCBOR(3);
998     std::string out;
999     Status status;
1000     std::unique_ptr<StreamingParserHandler> json_writer =
1001         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1002     ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1003     EXPECT_EQ(Error::OK, status.error);
1004     EXPECT_EQ(Status::npos(), status.pos);
1005     EXPECT_EQ("{\"key\":{\"key\":{\"key\":\"innermost_value\"}}}", out);
1006   }
1007   {  // Depth 300: no stack limit exceeded.
1008     std::vector<uint8_t> bytes = MakeNestedCBOR(300);
1009     std::string out;
1010     Status status;
1011     std::unique_ptr<StreamingParserHandler> json_writer =
1012         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1013     ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1014     EXPECT_EQ(Error::OK, status.error);
1015     EXPECT_EQ(Status::npos(), status.pos);
1016   }
1017 
1018   // We just want to know the length of one opening map so we can compute
1019   // where the error is encountered. So we look at a small example and find
1020   // the second envelope start.
1021   std::vector<uint8_t> small_example = MakeNestedCBOR(3);
1022   size_t opening_segment_size = 1;  // Start after the first envelope start.
1023   while (opening_segment_size < small_example.size() &&
1024          small_example[opening_segment_size] != 0xd8)
1025     opening_segment_size++;
1026 
1027   {  // Depth 301: limit exceeded.
1028     std::vector<uint8_t> bytes = MakeNestedCBOR(301);
1029     std::string out;
1030     Status status;
1031     std::unique_ptr<StreamingParserHandler> json_writer =
1032         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1033     ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1034     EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error);
1035     EXPECT_EQ(opening_segment_size * 301, status.pos);
1036   }
1037   {  // Depth 320: still limit exceeded, and at the same pos as for 1001
1038     std::vector<uint8_t> bytes = MakeNestedCBOR(320);
1039     std::string out;
1040     Status status;
1041     std::unique_ptr<StreamingParserHandler> json_writer =
1042         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1043     ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1044     EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error);
1045     EXPECT_EQ(opening_segment_size * 301, status.pos);
1046   }
1047 }
1048 
TEST(ParseCBORTest,UnsupportedValueError)1049 TEST(ParseCBORTest, UnsupportedValueError) {
1050   constexpr uint8_t kPayloadLen = 6;
1051   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1052                                 0xbf};                             // map start
1053   EncodeString8(SpanFrom("key"), &bytes);
1054   size_t error_pos = bytes.size();
1055   bytes.push_back(6 << 5 | 5);  // tags aren't supported yet.
1056   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1057 
1058   std::string out;
1059   Status status;
1060   std::unique_ptr<StreamingParserHandler> json_writer =
1061       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1062   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1063   EXPECT_EQ(Error::CBOR_UNSUPPORTED_VALUE, status.error);
1064   EXPECT_EQ(error_pos, status.pos);
1065   EXPECT_EQ("", out);
1066 }
1067 
TEST(ParseCBORTest,InvalidString16Error)1068 TEST(ParseCBORTest, InvalidString16Error) {
1069   constexpr uint8_t kPayloadLen = 11;
1070   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1071                                 0xbf};                             // map start
1072   EncodeString8(SpanFrom("key"), &bytes);
1073   size_t error_pos = bytes.size();
1074   // a BYTE_STRING of length 5 as value; since we interpret these as string16,
1075   // it's going to be invalid as each character would need two bytes, but
1076   // 5 isn't divisible by 2.
1077   bytes.push_back(2 << 5 | 5);
1078   for (int ii = 0; ii < 5; ++ii)
1079     bytes.push_back(' ');
1080   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1081   std::string out;
1082   Status status;
1083   std::unique_ptr<StreamingParserHandler> json_writer =
1084       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1085   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1086   EXPECT_EQ(Error::CBOR_INVALID_STRING16, status.error);
1087   EXPECT_EQ(error_pos, status.pos);
1088   EXPECT_EQ("", out);
1089 }
1090 
TEST(ParseCBORTest,InvalidString8Error)1091 TEST(ParseCBORTest, InvalidString8Error) {
1092   constexpr uint8_t kPayloadLen = 6;
1093   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1094                                 0xbf};                             // map start
1095   EncodeString8(SpanFrom("key"), &bytes);
1096   size_t error_pos = bytes.size();
1097   // a STRING of length 5 as value, but we're at the end of the bytes array
1098   // so it can't be decoded successfully.
1099   bytes.push_back(3 << 5 | 5);
1100   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1101   std::string out;
1102   Status status;
1103   std::unique_ptr<StreamingParserHandler> json_writer =
1104       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1105   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1106   EXPECT_EQ(Error::CBOR_INVALID_STRING8, status.error);
1107   EXPECT_EQ(error_pos, status.pos);
1108   EXPECT_EQ("", out);
1109 }
1110 
TEST(ParseCBORTest,InvalidBinaryError)1111 TEST(ParseCBORTest, InvalidBinaryError) {
1112   constexpr uint8_t kPayloadLen = 9;
1113   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1114                                 0xbf};                             // map start
1115   EncodeString8(SpanFrom("key"), &bytes);
1116   size_t error_pos = bytes.size();
1117   bytes.push_back(6 << 5 | 22);  // base64 hint for JSON; indicates binary
1118   bytes.push_back(2 << 5 | 10);  // BYTE_STRING (major type 2) of length 10
1119   // Just two garbage bytes, not enough for the binary.
1120   bytes.push_back(0x31);
1121   bytes.push_back(0x23);
1122   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1123   std::string out;
1124   Status status;
1125   std::unique_ptr<StreamingParserHandler> json_writer =
1126       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1127   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1128   EXPECT_EQ(Error::CBOR_INVALID_BINARY, status.error);
1129   EXPECT_EQ(error_pos, status.pos);
1130   EXPECT_EQ("", out);
1131 }
1132 
TEST(ParseCBORTest,InvalidDoubleError)1133 TEST(ParseCBORTest, InvalidDoubleError) {
1134   constexpr uint8_t kPayloadLen = 8;
1135   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1136                                 0xbf};                             // map start
1137   EncodeString8(SpanFrom("key"), &bytes);
1138   size_t error_pos = bytes.size();
1139   bytes.push_back(7 << 5 | 27);  // initial byte for double
1140   // Just two garbage bytes, not enough to represent an actual double.
1141   bytes.push_back(0x31);
1142   bytes.push_back(0x23);
1143   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1144   std::string out;
1145   Status status;
1146   std::unique_ptr<StreamingParserHandler> json_writer =
1147       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1148   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1149   EXPECT_EQ(Error::CBOR_INVALID_DOUBLE, status.error);
1150   EXPECT_EQ(error_pos, status.pos);
1151   EXPECT_EQ("", out);
1152 }
1153 
TEST(ParseCBORTest,InvalidSignedError)1154 TEST(ParseCBORTest, InvalidSignedError) {
1155   constexpr uint8_t kPayloadLen = 14;
1156   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1157                                 0xbf};                             // map start
1158   EncodeString8(SpanFrom("key"), &bytes);
1159   size_t error_pos = bytes.size();
1160   // uint64_t max is a perfectly fine value to encode as CBOR unsigned,
1161   // but we don't support this since we only cover the int32_t range.
1162   internals::WriteTokenStart(MajorType::UNSIGNED,
1163                              std::numeric_limits<uint64_t>::max(), &bytes);
1164   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1165   std::string out;
1166   Status status;
1167   std::unique_ptr<StreamingParserHandler> json_writer =
1168       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1169   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1170   EXPECT_EQ(Error::CBOR_INVALID_INT32, status.error);
1171   EXPECT_EQ(error_pos, status.pos);
1172   EXPECT_EQ("", out);
1173 }
1174 
TEST(ParseCBORTest,TrailingJunk)1175 TEST(ParseCBORTest, TrailingJunk) {
1176   constexpr uint8_t kPayloadLen = 35;
1177   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1178                                 0xbf};                             // map start
1179   EncodeString8(SpanFrom("key"), &bytes);
1180   EncodeString8(SpanFrom("value"), &bytes);
1181   bytes.push_back(0xff);  // Up to here, it's a perfectly fine msg.
1182   size_t error_pos = bytes.size();
1183   EncodeString8(SpanFrom("trailing junk"), &bytes);
1184 
1185   internals::WriteTokenStart(MajorType::UNSIGNED,
1186                              std::numeric_limits<uint64_t>::max(), &bytes);
1187   EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1188   std::string out;
1189   Status status;
1190   std::unique_ptr<StreamingParserHandler> json_writer =
1191       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1192   ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1193   EXPECT_EQ(Error::CBOR_TRAILING_JUNK, status.error);
1194   EXPECT_EQ(error_pos, status.pos);
1195   EXPECT_EQ("", out);
1196 }
1197 
1198 // =============================================================================
1199 // cbor::AppendString8EntryToMap - for limited in-place editing of messages
1200 // =============================================================================
1201 
1202 template <typename T>
1203 class AppendString8EntryToMapTest : public ::testing::Test {};
1204 
1205 using ContainerTestTypes = ::testing::Types<std::vector<uint8_t>, std::string>;
1206 TYPED_TEST_SUITE(AppendString8EntryToMapTest, ContainerTestTypes);
1207 
TYPED_TEST(AppendString8EntryToMapTest,AppendsEntrySuccessfully)1208 TYPED_TEST(AppendString8EntryToMapTest, AppendsEntrySuccessfully) {
1209   constexpr uint8_t kPayloadLen = 12;
1210   std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen,  // envelope
1211                                 0xbf};                             // map start
1212   size_t pos_before_payload = bytes.size() - 1;
1213   EncodeString8(SpanFrom("key"), &bytes);
1214   EncodeString8(SpanFrom("value"), &bytes);
1215   bytes.push_back(0xff);  // A perfectly fine cbor message.
1216   EXPECT_EQ(kPayloadLen, bytes.size() - pos_before_payload);
1217 
1218   TypeParam msg(bytes.begin(), bytes.end());
1219 
1220   Status status =
1221       AppendString8EntryToCBORMap(SpanFrom("foo"), SpanFrom("bar"), &msg);
1222   EXPECT_EQ(Error::OK, status.error);
1223   EXPECT_EQ(Status::npos(), status.pos);
1224   std::string out;
1225   std::unique_ptr<StreamingParserHandler> json_writer =
1226       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1227   ParseCBOR(SpanFrom(msg), json_writer.get());
1228   EXPECT_EQ("{\"key\":\"value\",\"foo\":\"bar\"}", out);
1229   EXPECT_EQ(Error::OK, status.error);
1230   EXPECT_EQ(Status::npos(), status.pos);
1231 }
1232 
TYPED_TEST(AppendString8EntryToMapTest,AppendThreeEntries)1233 TYPED_TEST(AppendString8EntryToMapTest, AppendThreeEntries) {
1234   std::vector<uint8_t> encoded = {
1235       0xd8, 0x5a, 0, 0, 0, 2, EncodeIndefiniteLengthMapStart(), EncodeStop()};
1236   EXPECT_EQ(Error::OK, AppendString8EntryToCBORMap(SpanFrom("key"),
1237                                                    SpanFrom("value"), &encoded)
1238                            .error);
1239   EXPECT_EQ(Error::OK, AppendString8EntryToCBORMap(SpanFrom("key1"),
1240                                                    SpanFrom("value1"), &encoded)
1241                            .error);
1242   EXPECT_EQ(Error::OK, AppendString8EntryToCBORMap(SpanFrom("key2"),
1243                                                    SpanFrom("value2"), &encoded)
1244                            .error);
1245   TypeParam msg(encoded.begin(), encoded.end());
1246   std::string out;
1247   Status status;
1248   std::unique_ptr<StreamingParserHandler> json_writer =
1249       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1250   ParseCBOR(SpanFrom(msg), json_writer.get());
1251   EXPECT_EQ("{\"key\":\"value\",\"key1\":\"value1\",\"key2\":\"value2\"}", out);
1252   EXPECT_EQ(Error::OK, status.error);
1253   EXPECT_EQ(Status::npos(), status.pos);
1254 }
1255 
TYPED_TEST(AppendString8EntryToMapTest,MapStartExpected_Error)1256 TYPED_TEST(AppendString8EntryToMapTest, MapStartExpected_Error) {
1257   std::vector<uint8_t> bytes = {
1258       0xd8, 0x5a, 0, 0, 0, 1, EncodeIndefiniteLengthArrayStart()};
1259   TypeParam msg(bytes.begin(), bytes.end());
1260   Status status =
1261       AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1262   EXPECT_EQ(Error::CBOR_MAP_START_EXPECTED, status.error);
1263   EXPECT_EQ(6u, status.pos);
1264 }
1265 
TYPED_TEST(AppendString8EntryToMapTest,MapStopExpected_Error)1266 TYPED_TEST(AppendString8EntryToMapTest, MapStopExpected_Error) {
1267   std::vector<uint8_t> bytes = {
1268       0xd8, 0x5a, 0, 0, 0, 2, EncodeIndefiniteLengthMapStart(), 42};
1269   TypeParam msg(bytes.begin(), bytes.end());
1270   Status status =
1271       AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1272   EXPECT_EQ(Error::CBOR_MAP_STOP_EXPECTED, status.error);
1273   EXPECT_EQ(7u, status.pos);
1274 }
1275 
TYPED_TEST(AppendString8EntryToMapTest,InvalidEnvelope_Error)1276 TYPED_TEST(AppendString8EntryToMapTest, InvalidEnvelope_Error) {
1277   {  // Second byte is wrong.
1278     std::vector<uint8_t> bytes = {
1279         0x5a, 0, 0, 0, 2, EncodeIndefiniteLengthMapStart(), EncodeStop(), 0};
1280     TypeParam msg(bytes.begin(), bytes.end());
1281     Status status =
1282         AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1283     EXPECT_EQ(Error::CBOR_INVALID_ENVELOPE, status.error);
1284     EXPECT_EQ(0u, status.pos);
1285   }
1286   {  // Second byte is wrong.
1287     std::vector<uint8_t> bytes = {
1288         0xd8, 0x7a, 0, 0, 0, 2, EncodeIndefiniteLengthMapStart(), EncodeStop()};
1289     TypeParam msg(bytes.begin(), bytes.end());
1290     Status status =
1291         AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1292     EXPECT_EQ(Error::CBOR_INVALID_ENVELOPE, status.error);
1293     EXPECT_EQ(0u, status.pos);
1294   }
1295   {  // Invalid envelope size example.
1296     std::vector<uint8_t> bytes = {
1297         0xd8, 0x5a, 0, 0, 0, 3, EncodeIndefiniteLengthMapStart(), EncodeStop(),
1298     };
1299     TypeParam msg(bytes.begin(), bytes.end());
1300     Status status =
1301         AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1302     EXPECT_EQ(Error::CBOR_INVALID_ENVELOPE, status.error);
1303     EXPECT_EQ(0u, status.pos);
1304   }
1305   {  // Invalid envelope size example.
1306     std::vector<uint8_t> bytes = {
1307         0xd8, 0x5a, 0, 0, 0, 1, EncodeIndefiniteLengthMapStart(), EncodeStop(),
1308     };
1309     TypeParam msg(bytes.begin(), bytes.end());
1310     Status status =
1311         AppendString8EntryToCBORMap(SpanFrom("key"), SpanFrom("value"), &msg);
1312     EXPECT_EQ(Error::CBOR_INVALID_ENVELOPE, status.error);
1313     EXPECT_EQ(0u, status.pos);
1314   }
1315 }
1316 }  // namespace cbor
1317 
1318 namespace json {
1319 
1320 // =============================================================================
1321 // json::NewJSONEncoder - for encoding streaming parser events as JSON
1322 // =============================================================================
1323 
WriteUTF8AsUTF16(StreamingParserHandler * writer,const std::string & utf8)1324 void WriteUTF8AsUTF16(StreamingParserHandler* writer, const std::string& utf8) {
1325   writer->HandleString16(SpanFrom(UTF8ToUTF16(SpanFrom(utf8))));
1326 }
1327 
TEST(JsonStdStringWriterTest,HelloWorld)1328 TEST(JsonStdStringWriterTest, HelloWorld) {
1329   std::string out;
1330   Status status;
1331   std::unique_ptr<StreamingParserHandler> writer =
1332       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1333   writer->HandleMapBegin();
1334   WriteUTF8AsUTF16(writer.get(), "msg1");
1335   WriteUTF8AsUTF16(writer.get(), "Hello, ��.");
1336   std::string key = "msg1-as-utf8";
1337   std::string value = "Hello, ��.";
1338   writer->HandleString8(SpanFrom(key));
1339   writer->HandleString8(SpanFrom(value));
1340   WriteUTF8AsUTF16(writer.get(), "msg2");
1341   WriteUTF8AsUTF16(writer.get(), "\\\b\r\n\t\f\"");
1342   WriteUTF8AsUTF16(writer.get(), "nested");
1343   writer->HandleMapBegin();
1344   WriteUTF8AsUTF16(writer.get(), "double");
1345   writer->HandleDouble(3.1415);
1346   WriteUTF8AsUTF16(writer.get(), "int");
1347   writer->HandleInt32(-42);
1348   WriteUTF8AsUTF16(writer.get(), "bool");
1349   writer->HandleBool(false);
1350   WriteUTF8AsUTF16(writer.get(), "null");
1351   writer->HandleNull();
1352   writer->HandleMapEnd();
1353   WriteUTF8AsUTF16(writer.get(), "array");
1354   writer->HandleArrayBegin();
1355   writer->HandleInt32(1);
1356   writer->HandleInt32(2);
1357   writer->HandleInt32(3);
1358   writer->HandleArrayEnd();
1359   writer->HandleMapEnd();
1360   EXPECT_TRUE(status.ok());
1361   EXPECT_EQ(
1362       "{\"msg1\":\"Hello, \\ud83c\\udf0e.\","
1363       "\"msg1-as-utf8\":\"Hello, \\ud83c\\udf0e.\","
1364       "\"msg2\":\"\\\\\\b\\r\\n\\t\\f\\\"\","
1365       "\"nested\":{\"double\":3.1415,\"int\":-42,"
1366       "\"bool\":false,\"null\":null},\"array\":[1,2,3]}",
1367       out);
1368 }
1369 
TEST(JsonStdStringWriterTest,RepresentingNonFiniteValuesAsNull)1370 TEST(JsonStdStringWriterTest, RepresentingNonFiniteValuesAsNull) {
1371   // JSON can't represent +Infinity, -Infinity, or NaN.
1372   // So in practice it's mapped to null.
1373   std::string out;
1374   Status status;
1375   std::unique_ptr<StreamingParserHandler> writer =
1376       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1377   writer->HandleMapBegin();
1378   writer->HandleString8(SpanFrom("Infinity"));
1379   writer->HandleDouble(std::numeric_limits<double>::infinity());
1380   writer->HandleString8(SpanFrom("-Infinity"));
1381   writer->HandleDouble(-std::numeric_limits<double>::infinity());
1382   writer->HandleString8(SpanFrom("NaN"));
1383   writer->HandleDouble(std::numeric_limits<double>::quiet_NaN());
1384   writer->HandleMapEnd();
1385   EXPECT_TRUE(status.ok());
1386   EXPECT_EQ("{\"Infinity\":null,\"-Infinity\":null,\"NaN\":null}", out);
1387 }
1388 
TEST(JsonStdStringWriterTest,BinaryEncodedAsJsonString)1389 TEST(JsonStdStringWriterTest, BinaryEncodedAsJsonString) {
1390   // The encoder emits binary submitted to StreamingParserHandler::HandleBinary
1391   // as base64. The following three examples are taken from
1392   // https://en.wikipedia.org/wiki/Base64.
1393   {
1394     std::string out;
1395     Status status;
1396     std::unique_ptr<StreamingParserHandler> writer =
1397         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1398     writer->HandleBinary(SpanFrom(std::vector<uint8_t>({'M', 'a', 'n'})));
1399     EXPECT_TRUE(status.ok());
1400     EXPECT_EQ("\"TWFu\"", out);
1401   }
1402   {
1403     std::string out;
1404     Status status;
1405     std::unique_ptr<StreamingParserHandler> writer =
1406         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1407     writer->HandleBinary(SpanFrom(std::vector<uint8_t>({'M', 'a'})));
1408     EXPECT_TRUE(status.ok());
1409     EXPECT_EQ("\"TWE=\"", out);
1410   }
1411   {
1412     std::string out;
1413     Status status;
1414     std::unique_ptr<StreamingParserHandler> writer =
1415         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1416     writer->HandleBinary(SpanFrom(std::vector<uint8_t>({'M'})));
1417     EXPECT_TRUE(status.ok());
1418     EXPECT_EQ("\"TQ==\"", out);
1419   }
1420   {  // "Hello, world.", verified with base64decode.org.
1421     std::string out;
1422     Status status;
1423     std::unique_ptr<StreamingParserHandler> writer =
1424         NewJSONEncoder(&GetTestPlatform(), &out, &status);
1425     writer->HandleBinary(SpanFrom(std::vector<uint8_t>(
1426         {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'})));
1427     EXPECT_TRUE(status.ok());
1428     EXPECT_EQ("\"SGVsbG8sIHdvcmxkLg==\"", out);
1429   }
1430 }
1431 
TEST(JsonStdStringWriterTest,HandlesErrors)1432 TEST(JsonStdStringWriterTest, HandlesErrors) {
1433   // When an error is sent via HandleError, it saves it in the provided
1434   // status and clears the output.
1435   std::string out;
1436   Status status;
1437   std::unique_ptr<StreamingParserHandler> writer =
1438       NewJSONEncoder(&GetTestPlatform(), &out, &status);
1439   writer->HandleMapBegin();
1440   WriteUTF8AsUTF16(writer.get(), "msg1");
1441   writer->HandleError(Status{Error::JSON_PARSER_VALUE_EXPECTED, 42});
1442   EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, status.error);
1443   EXPECT_EQ(42u, status.pos);
1444   EXPECT_EQ("", out);
1445 }
1446 
1447 // We'd use Gmock but unfortunately it only handles copyable return types.
1448 class MockPlatform : public Platform {
1449  public:
1450   // Not implemented.
StrToD(const char * str,double * result) const1451   bool StrToD(const char* str, double* result) const override { return false; }
1452 
1453   // A map with pre-registered responses for DToSTr.
1454   std::map<double, std::string> dtostr_responses_;
1455 
DToStr(double value) const1456   std::unique_ptr<char[]> DToStr(double value) const override {
1457     auto it = dtostr_responses_.find(value);
1458     CHECK(it != dtostr_responses_.end());
1459     const std::string& str = it->second;
1460     std::unique_ptr<char[]> response(new char[str.size() + 1]);
1461     memcpy(response.get(), str.c_str(), str.size() + 1);
1462     return response;
1463   }
1464 };
1465 
TEST(JsonStdStringWriterTest,DoubleToString)1466 TEST(JsonStdStringWriterTest, DoubleToString) {
1467   // This "broken" platform responds without the leading 0 before the
1468   // decimal dot, so it'd be invalid JSON.
1469   MockPlatform platform;
1470   platform.dtostr_responses_[.1] = ".1";
1471   platform.dtostr_responses_[-.7] = "-.7";
1472 
1473   std::string out;
1474   Status status;
1475   std::unique_ptr<StreamingParserHandler> writer =
1476       NewJSONEncoder(&platform, &out, &status);
1477   writer->HandleArrayBegin();
1478   writer->HandleDouble(.1);
1479   writer->HandleDouble(-.7);
1480   writer->HandleArrayEnd();
1481   EXPECT_EQ("[0.1,-0.7]", out);
1482 }
1483 
1484 // =============================================================================
1485 // json::ParseJSON - for receiving streaming parser events for JSON
1486 // =============================================================================
1487 
1488 class Log : public StreamingParserHandler {
1489  public:
HandleMapBegin()1490   void HandleMapBegin() override { log_ << "map begin\n"; }
1491 
HandleMapEnd()1492   void HandleMapEnd() override { log_ << "map end\n"; }
1493 
HandleArrayBegin()1494   void HandleArrayBegin() override { log_ << "array begin\n"; }
1495 
HandleArrayEnd()1496   void HandleArrayEnd() override { log_ << "array end\n"; }
1497 
HandleString8(span<uint8_t> chars)1498   void HandleString8(span<uint8_t> chars) override {
1499     log_ << "string8: " << std::string(chars.begin(), chars.end()) << "\n";
1500   }
1501 
HandleString16(span<uint16_t> chars)1502   void HandleString16(span<uint16_t> chars) override {
1503     log_ << "string16: " << UTF16ToUTF8(chars) << "\n";
1504   }
1505 
HandleBinary(span<uint8_t> bytes)1506   void HandleBinary(span<uint8_t> bytes) override {
1507     // JSON doesn't have native support for arbitrary bytes, so our parser will
1508     // never call this.
1509     CHECK(false);
1510   }
1511 
HandleDouble(double value)1512   void HandleDouble(double value) override {
1513     log_ << "double: " << value << "\n";
1514   }
1515 
HandleInt32(int32_t value)1516   void HandleInt32(int32_t value) override { log_ << "int: " << value << "\n"; }
1517 
HandleBool(bool value)1518   void HandleBool(bool value) override { log_ << "bool: " << value << "\n"; }
1519 
HandleNull()1520   void HandleNull() override { log_ << "null\n"; }
1521 
HandleError(Status status)1522   void HandleError(Status status) override { status_ = status; }
1523 
str() const1524   std::string str() const { return status_.ok() ? log_.str() : ""; }
1525 
status() const1526   Status status() const { return status_; }
1527 
1528  private:
1529   std::ostringstream log_;
1530   Status status_;
1531 };
1532 
1533 class JsonParserTest : public ::testing::Test {
1534  protected:
1535   Log log_;
1536 };
1537 
TEST_F(JsonParserTest,SimpleDictionary)1538 TEST_F(JsonParserTest, SimpleDictionary) {
1539   std::string json = "{\"foo\": 42}";
1540   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1541   EXPECT_TRUE(log_.status().ok());
1542   EXPECT_EQ(
1543       "map begin\n"
1544       "string16: foo\n"
1545       "int: 42\n"
1546       "map end\n",
1547       log_.str());
1548 }
1549 
TEST_F(JsonParserTest,UsAsciiDelCornerCase)1550 TEST_F(JsonParserTest, UsAsciiDelCornerCase) {
1551   // DEL (0x7f) is a 7 bit US-ASCII character, and while it is a control
1552   // character according to Unicode, it's not considered a control
1553   // character in https://tools.ietf.org/html/rfc7159#section-7, so
1554   // it can be placed directly into the JSON string, without JSON escaping.
1555   std::string json = "{\"foo\": \"a\x7f\"}";
1556   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1557   EXPECT_TRUE(log_.status().ok());
1558   EXPECT_EQ(
1559       "map begin\n"
1560       "string16: foo\n"
1561       "string16: a\x7f\n"
1562       "map end\n",
1563       log_.str());
1564 }
1565 
TEST_F(JsonParserTest,Whitespace)1566 TEST_F(JsonParserTest, Whitespace) {
1567   std::string json = "\n  {\n\"msg\"\n: \v\"Hello, world.\"\t\r}\t";
1568   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1569   EXPECT_TRUE(log_.status().ok());
1570   EXPECT_EQ(
1571       "map begin\n"
1572       "string16: msg\n"
1573       "string16: Hello, world.\n"
1574       "map end\n",
1575       log_.str());
1576 }
1577 
TEST_F(JsonParserTest,NestedDictionary)1578 TEST_F(JsonParserTest, NestedDictionary) {
1579   std::string json = "{\"foo\": {\"bar\": {\"baz\": 1}, \"bar2\": 2}}";
1580   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1581   EXPECT_TRUE(log_.status().ok());
1582   EXPECT_EQ(
1583       "map begin\n"
1584       "string16: foo\n"
1585       "map begin\n"
1586       "string16: bar\n"
1587       "map begin\n"
1588       "string16: baz\n"
1589       "int: 1\n"
1590       "map end\n"
1591       "string16: bar2\n"
1592       "int: 2\n"
1593       "map end\n"
1594       "map end\n",
1595       log_.str());
1596 }
1597 
TEST_F(JsonParserTest,Doubles)1598 TEST_F(JsonParserTest, Doubles) {
1599   std::string json = "{\"foo\": 3.1415, \"bar\": 31415e-4}";
1600   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1601   EXPECT_TRUE(log_.status().ok());
1602   EXPECT_EQ(
1603       "map begin\n"
1604       "string16: foo\n"
1605       "double: 3.1415\n"
1606       "string16: bar\n"
1607       "double: 3.1415\n"
1608       "map end\n",
1609       log_.str());
1610 }
1611 
TEST_F(JsonParserTest,Unicode)1612 TEST_F(JsonParserTest, Unicode) {
1613   // Globe character. 0xF0 0x9F 0x8C 0x8E in utf8, 0xD83C 0xDF0E in utf16.
1614   std::string json = "{\"msg\": \"Hello, \\uD83C\\uDF0E.\"}";
1615   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1616   EXPECT_TRUE(log_.status().ok());
1617   EXPECT_EQ(
1618       "map begin\n"
1619       "string16: msg\n"
1620       "string16: Hello, ��.\n"
1621       "map end\n",
1622       log_.str());
1623 }
1624 
TEST_F(JsonParserTest,Unicode_ParseUtf16)1625 TEST_F(JsonParserTest, Unicode_ParseUtf16) {
1626   // Globe character. utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E.
1627   // Crescent moon character. utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19.
1628 
1629   // We provide the moon with json escape, but the earth as utf16 input.
1630   // Either way they arrive as utf8 (after decoding in log_.str()).
1631   std::vector<uint16_t> json =
1632       UTF8ToUTF16(SpanFrom("{\"space\": \"�� \\uD83C\\uDF19.\"}"));
1633   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1634   EXPECT_TRUE(log_.status().ok());
1635   EXPECT_EQ(
1636       "map begin\n"
1637       "string16: space\n"
1638       "string16: �� ��.\n"
1639       "map end\n",
1640       log_.str());
1641 }
1642 
TEST_F(JsonParserTest,Unicode_ParseUtf8)1643 TEST_F(JsonParserTest, Unicode_ParseUtf8) {
1644   // Used below:
1645   // гласность - example for 2 byte utf8, Russian word "glasnost"
1646   // 屋 - example for 3 byte utf8, Chinese word for "house"
1647   // �� - example for 4 byte utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E.
1648   // �� - example for escapes: utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19.
1649 
1650   // We provide the moon with json escape, but the earth as utf8 input.
1651   // Either way they arrive as utf8 (after decoding in log_.str()).
1652   std::string json =
1653       "{"
1654       "\"escapes\": \"\\uD83C\\uDF19\","
1655       "\"2 byte\":\"гласность\","
1656       "\"3 byte\":\"屋\","
1657       "\"4 byte\":\"��\""
1658       "}";
1659   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1660   EXPECT_TRUE(log_.status().ok());
1661   EXPECT_EQ(
1662       "map begin\n"
1663       "string16: escapes\n"
1664       "string16: ��\n"
1665       "string16: 2 byte\n"
1666       "string16: гласность\n"
1667       "string16: 3 byte\n"
1668       "string16: 屋\n"
1669       "string16: 4 byte\n"
1670       "string16: ��\n"
1671       "map end\n",
1672       log_.str());
1673 }
1674 
TEST_F(JsonParserTest,UnprocessedInputRemainsError)1675 TEST_F(JsonParserTest, UnprocessedInputRemainsError) {
1676   // Trailing junk after the valid JSON.
1677   std::string json = "{\"foo\": 3.1415} junk";
1678   size_t junk_idx = json.find("junk");
1679   EXPECT_NE(junk_idx, std::string::npos);
1680   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1681   EXPECT_EQ(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, log_.status().error);
1682   EXPECT_EQ(junk_idx, log_.status().pos);
1683   EXPECT_EQ("", log_.str());
1684 }
1685 
MakeNestedJson(int depth)1686 std::string MakeNestedJson(int depth) {
1687   std::string json;
1688   for (int ii = 0; ii < depth; ++ii)
1689     json += "{\"foo\":";
1690   json += "42";
1691   for (int ii = 0; ii < depth; ++ii)
1692     json += "}";
1693   return json;
1694 }
1695 
TEST_F(JsonParserTest,StackLimitExceededError_BelowLimit)1696 TEST_F(JsonParserTest, StackLimitExceededError_BelowLimit) {
1697   // kStackLimit is 300 (see json_parser.cc). First let's
1698   // try with a small nested example.
1699   std::string json_3 = MakeNestedJson(3);
1700   ParseJSON(GetTestPlatform(), SpanFrom(json_3), &log_);
1701   EXPECT_TRUE(log_.status().ok());
1702   EXPECT_EQ(
1703       "map begin\n"
1704       "string16: foo\n"
1705       "map begin\n"
1706       "string16: foo\n"
1707       "map begin\n"
1708       "string16: foo\n"
1709       "int: 42\n"
1710       "map end\n"
1711       "map end\n"
1712       "map end\n",
1713       log_.str());
1714 }
1715 
TEST_F(JsonParserTest,StackLimitExceededError_AtLimit)1716 TEST_F(JsonParserTest, StackLimitExceededError_AtLimit) {
1717   // Now with kStackLimit (300).
1718   std::string json_limit = MakeNestedJson(300);
1719   ParseJSON(GetTestPlatform(),
1720             span<uint8_t>(reinterpret_cast<const uint8_t*>(json_limit.data()),
1721                           json_limit.size()),
1722             &log_);
1723   EXPECT_TRUE(log_.status().ok());
1724 }
1725 
TEST_F(JsonParserTest,StackLimitExceededError_AboveLimit)1726 TEST_F(JsonParserTest, StackLimitExceededError_AboveLimit) {
1727   // Now with kStackLimit + 1 (301) - it exceeds in the innermost instance.
1728   std::string exceeded = MakeNestedJson(301);
1729   ParseJSON(GetTestPlatform(), SpanFrom(exceeded), &log_);
1730   EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error);
1731   EXPECT_EQ(strlen("{\"foo\":") * 301, log_.status().pos);
1732 }
1733 
TEST_F(JsonParserTest,StackLimitExceededError_WayAboveLimit)1734 TEST_F(JsonParserTest, StackLimitExceededError_WayAboveLimit) {
1735   // Now way past the limit. Still, the point of exceeding is 301.
1736   std::string far_out = MakeNestedJson(320);
1737   ParseJSON(GetTestPlatform(), SpanFrom(far_out), &log_);
1738   EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error);
1739   EXPECT_EQ(strlen("{\"foo\":") * 301, log_.status().pos);
1740 }
1741 
TEST_F(JsonParserTest,NoInputError)1742 TEST_F(JsonParserTest, NoInputError) {
1743   std::string json = "";
1744   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1745   EXPECT_EQ(Error::JSON_PARSER_NO_INPUT, log_.status().error);
1746   EXPECT_EQ(0u, log_.status().pos);
1747   EXPECT_EQ("", log_.str());
1748 }
1749 
TEST_F(JsonParserTest,InvalidTokenError)1750 TEST_F(JsonParserTest, InvalidTokenError) {
1751   std::string json = "|";
1752   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1753   EXPECT_EQ(Error::JSON_PARSER_INVALID_TOKEN, log_.status().error);
1754   EXPECT_EQ(0u, log_.status().pos);
1755   EXPECT_EQ("", log_.str());
1756 }
1757 
TEST_F(JsonParserTest,InvalidNumberError)1758 TEST_F(JsonParserTest, InvalidNumberError) {
1759   // Mantissa exceeds max (the constant used here is int64_t max).
1760   std::string json = "1E9223372036854775807";
1761   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1762   EXPECT_EQ(Error::JSON_PARSER_INVALID_NUMBER, log_.status().error);
1763   EXPECT_EQ(0u, log_.status().pos);
1764   EXPECT_EQ("", log_.str());
1765 }
1766 
TEST_F(JsonParserTest,InvalidStringError)1767 TEST_F(JsonParserTest, InvalidStringError) {
1768   // \x22 is an unsupported escape sequence
1769   std::string json = "\"foo\\x22\"";
1770   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1771   EXPECT_EQ(Error::JSON_PARSER_INVALID_STRING, log_.status().error);
1772   EXPECT_EQ(0u, log_.status().pos);
1773   EXPECT_EQ("", log_.str());
1774 }
1775 
TEST_F(JsonParserTest,UnexpectedArrayEndError)1776 TEST_F(JsonParserTest, UnexpectedArrayEndError) {
1777   std::string json = "[1,2,]";
1778   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1779   EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, log_.status().error);
1780   EXPECT_EQ(5u, log_.status().pos);
1781   EXPECT_EQ("", log_.str());
1782 }
1783 
TEST_F(JsonParserTest,CommaOrArrayEndExpectedError)1784 TEST_F(JsonParserTest, CommaOrArrayEndExpectedError) {
1785   std::string json = "[1,2 2";
1786   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1787   EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED,
1788             log_.status().error);
1789   EXPECT_EQ(5u, log_.status().pos);
1790   EXPECT_EQ("", log_.str());
1791 }
1792 
TEST_F(JsonParserTest,StringLiteralExpectedError)1793 TEST_F(JsonParserTest, StringLiteralExpectedError) {
1794   // There's an error because the key bar, a string, is not terminated.
1795   std::string json = "{\"foo\": 3.1415, \"bar: 31415e-4}";
1796   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1797   EXPECT_EQ(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, log_.status().error);
1798   EXPECT_EQ(16u, log_.status().pos);
1799   EXPECT_EQ("", log_.str());
1800 }
1801 
TEST_F(JsonParserTest,ColonExpectedError)1802 TEST_F(JsonParserTest, ColonExpectedError) {
1803   std::string json = "{\"foo\", 42}";
1804   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1805   EXPECT_EQ(Error::JSON_PARSER_COLON_EXPECTED, log_.status().error);
1806   EXPECT_EQ(6u, log_.status().pos);
1807   EXPECT_EQ("", log_.str());
1808 }
1809 
TEST_F(JsonParserTest,UnexpectedMapEndError)1810 TEST_F(JsonParserTest, UnexpectedMapEndError) {
1811   std::string json = "{\"foo\": 42, }";
1812   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1813   EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_MAP_END, log_.status().error);
1814   EXPECT_EQ(12u, log_.status().pos);
1815   EXPECT_EQ("", log_.str());
1816 }
1817 
TEST_F(JsonParserTest,CommaOrMapEndExpectedError)1818 TEST_F(JsonParserTest, CommaOrMapEndExpectedError) {
1819   // The second separator should be a comma.
1820   std::string json = "{\"foo\": 3.1415: \"bar\": 0}";
1821   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1822   EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED, log_.status().error);
1823   EXPECT_EQ(14u, log_.status().pos);
1824   EXPECT_EQ("", log_.str());
1825 }
1826 
TEST_F(JsonParserTest,ValueExpectedError)1827 TEST_F(JsonParserTest, ValueExpectedError) {
1828   std::string json = "}";
1829   ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
1830   EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, log_.status().error);
1831   EXPECT_EQ(0u, log_.status().pos);
1832   EXPECT_EQ("", log_.str());
1833 }
1834 
1835 template <typename T>
1836 class ConvertJSONToCBORTest : public ::testing::Test {};
1837 
1838 using ContainerTestTypes = ::testing::Types<std::vector<uint8_t>, std::string>;
1839 TYPED_TEST_SUITE(ConvertJSONToCBORTest, ContainerTestTypes);
1840 
TYPED_TEST(ConvertJSONToCBORTest,RoundTripValidJson)1841 TYPED_TEST(ConvertJSONToCBORTest, RoundTripValidJson) {
1842   std::string json_in = "{\"msg\":\"Hello, world.\",\"lst\":[1,2,3]}";
1843   TypeParam json(json_in.begin(), json_in.end());
1844   TypeParam cbor;
1845   {
1846     Status status = ConvertJSONToCBOR(GetTestPlatform(), SpanFrom(json), &cbor);
1847     EXPECT_EQ(Error::OK, status.error);
1848     EXPECT_EQ(Status::npos(), status.pos);
1849   }
1850   TypeParam roundtrip_json;
1851   {
1852     Status status =
1853         ConvertCBORToJSON(GetTestPlatform(), SpanFrom(cbor), &roundtrip_json);
1854     EXPECT_EQ(Error::OK, status.error);
1855     EXPECT_EQ(Status::npos(), status.pos);
1856   }
1857   EXPECT_EQ(json, roundtrip_json);
1858 }
1859 
TYPED_TEST(ConvertJSONToCBORTest,RoundTripValidJson16)1860 TYPED_TEST(ConvertJSONToCBORTest, RoundTripValidJson16) {
1861   std::vector<uint16_t> json16 = {
1862       '{', '"', 'm', 's',    'g',    '"', ':', '"', 'H', 'e', 'l', 'l',
1863       'o', ',', ' ', 0xd83c, 0xdf0e, '.', '"', ',', '"', 'l', 's', 't',
1864       '"', ':', '[', '1',    ',',    '2', ',', '3', ']', '}'};
1865   TypeParam cbor;
1866   {
1867     Status status = ConvertJSONToCBOR(
1868         GetTestPlatform(), span<uint16_t>(json16.data(), json16.size()), &cbor);
1869     EXPECT_EQ(Error::OK, status.error);
1870     EXPECT_EQ(Status::npos(), status.pos);
1871   }
1872   TypeParam roundtrip_json;
1873   {
1874     Status status =
1875         ConvertCBORToJSON(GetTestPlatform(), SpanFrom(cbor), &roundtrip_json);
1876     EXPECT_EQ(Error::OK, status.error);
1877     EXPECT_EQ(Status::npos(), status.pos);
1878   }
1879   std::string json = "{\"msg\":\"Hello, \\ud83c\\udf0e.\",\"lst\":[1,2,3]}";
1880   TypeParam expected_json(json.begin(), json.end());
1881   EXPECT_EQ(expected_json, roundtrip_json);
1882 }
1883 }  // namespace json
1884 }  // namespace v8_inspector_protocol_encoding
1885