Line data Source code
1 : // This file is generated by Protocol_cpp.template.
2 :
3 : // Copyright 2016 The Chromium Authors. All rights reserved.
4 : // Use of this source code is governed by a BSD-style license that can be
5 : // found in the LICENSE file.
6 :
7 : #include "src/inspector/protocol/Protocol.h"
8 :
9 : #include <algorithm>
10 : #include <climits>
11 : #include <cmath>
12 : #include <cstring>
13 :
14 :
15 : // This file is generated by ErrorSupport_cpp.template.
16 :
17 : // Copyright 2016 The Chromium Authors. All rights reserved.
18 : // Use of this source code is governed by a BSD-style license that can be
19 : // found in the LICENSE file.
20 :
21 : //#include "ErrorSupport.h"
22 :
23 : namespace v8_inspector {
24 : namespace protocol {
25 :
26 309966 : ErrorSupport::ErrorSupport() { }
27 154983 : ErrorSupport::~ErrorSupport() { }
28 :
29 204946 : void ErrorSupport::setName(const char* name)
30 : {
31 409892 : setName(String(name));
32 204946 : }
33 :
34 205291 : void ErrorSupport::setName(const String& name)
35 : {
36 : DCHECK(m_path.size());
37 205291 : m_path[m_path.size() - 1] = name;
38 205291 : }
39 :
40 144039 : void ErrorSupport::push()
41 : {
42 432117 : m_path.push_back(String());
43 144039 : }
44 :
45 144039 : void ErrorSupport::pop()
46 : {
47 : m_path.pop_back();
48 144039 : }
49 :
50 68 : void ErrorSupport::addError(const char* error)
51 : {
52 136 : addError(String(error));
53 68 : }
54 :
55 68 : void ErrorSupport::addError(const String& error)
56 : {
57 68 : StringBuilder builder;
58 214 : for (size_t i = 0; i < m_path.size(); ++i) {
59 73 : if (i)
60 : StringUtil::builderAppend(builder, '.');
61 : StringUtil::builderAppend(builder, m_path[i]);
62 : }
63 136 : StringUtil::builderAppend(builder, ": ");
64 : StringUtil::builderAppend(builder, error);
65 136 : m_errors.push_back(StringUtil::builderToString(builder));
66 68 : }
67 :
68 144039 : bool ErrorSupport::hasErrors()
69 : {
70 144039 : return !!m_errors.size();
71 : }
72 :
73 59 : String ErrorSupport::errors()
74 : {
75 59 : StringBuilder builder;
76 195 : for (size_t i = 0; i < m_errors.size(); ++i) {
77 68 : if (i)
78 18 : StringUtil::builderAppend(builder, "; ");
79 : StringUtil::builderAppend(builder, m_errors[i]);
80 : }
81 59 : return StringUtil::builderToString(builder);
82 : }
83 :
84 : } // namespace v8_inspector
85 : } // namespace protocol
86 :
87 :
88 : // This file is generated by Values_cpp.template.
89 :
90 : // Copyright 2016 The Chromium Authors. All rights reserved.
91 : // Use of this source code is governed by a BSD-style license that can be
92 : // found in the LICENSE file.
93 :
94 : //#include "Values.h"
95 :
96 : namespace v8_inspector {
97 : namespace protocol {
98 :
99 : namespace {
100 :
101 : const char* const nullValueString = "null";
102 : const char* const trueValueString = "true";
103 : const char* const falseValueString = "false";
104 :
105 1243506090 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
106 : {
107 1243506090 : switch (c) {
108 0 : case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
109 0 : case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
110 43626130 : case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
111 0 : case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
112 0 : case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
113 145694 : case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
114 36897652 : case '"': StringUtil::builderAppend(*dst, "\\\""); break;
115 : default:
116 : return false;
117 : }
118 : return true;
119 : }
120 :
121 : const char hexDigits[17] = "0123456789ABCDEF";
122 :
123 2250142 : void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
124 : {
125 4500284 : StringUtil::builderAppend(*dst, "\\u");
126 20251278 : for (size_t i = 0; i < 4; ++i) {
127 9000568 : uint16_t c = hexDigits[(number & 0xF000) >> 12];
128 : StringUtil::builderAppend(*dst, c);
129 9000568 : number <<= 4;
130 : }
131 2250142 : }
132 :
133 : template <typename Char>
134 49491077 : void escapeStringForJSONInternal(const Char* str, unsigned len,
135 : StringBuilder* dst)
136 : {
137 2536503257 : for (unsigned i = 0; i < len; ++i) {
138 1243506090 : Char c = str[i];
139 1243506090 : if (escapeChar(c, dst))
140 : continue;
141 1203171352 : if (c < 32 || c > 126) {
142 2250142 : appendUnsignedAsHex(c, dst);
143 : } else {
144 : StringUtil::builderAppend(*dst, c);
145 : }
146 : }
147 49491077 : }
148 :
149 : // When parsing CBOR, we limit recursion depth for objects and arrays
150 : // to this constant.
151 : static constexpr int kStackLimitValues = 1000;
152 :
153 : // Below are three parsing routines for CBOR, which cover enough
154 : // to roundtrip JSON messages.
155 : std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
156 : std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
157 : std::unique_ptr<Value> parseValue(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
158 :
159 : // |bytes| must start with the indefinite length array byte, so basically,
160 : // ParseArray may only be called after an indefinite length array has been
161 : // detected.
162 0 : std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
163 : DCHECK(tokenizer->TokenTag() == cbor::CBORTokenTag::ARRAY_START);
164 : tokenizer->Next();
165 0 : auto list = ListValue::create();
166 0 : while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
167 : // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY
168 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) return nullptr;
169 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
170 : // Parse value.
171 0 : auto value = parseValue(stack_depth, tokenizer);
172 0 : if (!value) return nullptr;
173 0 : list->pushValue(std::move(value));
174 : }
175 : tokenizer->Next();
176 : return list;
177 : }
178 :
179 0 : std::unique_ptr<Value> parseValue(
180 : int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
181 : // Error::CBOR_STACK_LIMIT_EXCEEDED
182 0 : if (stack_depth > kStackLimitValues) return nullptr;
183 : // Skip past the envelope to get to what's inside.
184 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::ENVELOPE)
185 : tokenizer->EnterEnvelope();
186 0 : switch (tokenizer->TokenTag()) {
187 : case cbor::CBORTokenTag::ERROR_VALUE:
188 : return nullptr;
189 : case cbor::CBORTokenTag::DONE:
190 : // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE
191 : return nullptr;
192 : case cbor::CBORTokenTag::TRUE_VALUE: {
193 : std::unique_ptr<Value> value = FundamentalValue::create(true);
194 : tokenizer->Next();
195 : return value;
196 : }
197 : case cbor::CBORTokenTag::FALSE_VALUE: {
198 : std::unique_ptr<Value> value = FundamentalValue::create(false);
199 : tokenizer->Next();
200 : return value;
201 : }
202 : case cbor::CBORTokenTag::NULL_VALUE: {
203 : std::unique_ptr<Value> value = FundamentalValue::null();
204 : tokenizer->Next();
205 : return value;
206 : }
207 : case cbor::CBORTokenTag::INT32: {
208 : std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32());
209 : tokenizer->Next();
210 : return value;
211 : }
212 : case cbor::CBORTokenTag::DOUBLE: {
213 : std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble());
214 : tokenizer->Next();
215 : return value;
216 : }
217 : case cbor::CBORTokenTag::STRING8: {
218 : span<uint8_t> str = tokenizer->GetString8();
219 : std::unique_ptr<Value> value =
220 0 : StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
221 : tokenizer->Next();
222 : return value;
223 : }
224 : case cbor::CBORTokenTag::STRING16: {
225 : span<uint8_t> wire = tokenizer->GetString16WireRep();
226 : DCHECK_EQ(wire.size() & 1, 0);
227 0 : std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16(
228 0 : reinterpret_cast<const uint16_t*>(wire.data()), wire.size() / 2));
229 : tokenizer->Next();
230 : return value;
231 : }
232 : case cbor::CBORTokenTag::BINARY: {
233 : span<uint8_t> payload = tokenizer->GetBinary();
234 : tokenizer->Next();
235 0 : return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size()));
236 : }
237 : case cbor::CBORTokenTag::MAP_START:
238 0 : return parseMap(stack_depth + 1, tokenizer);
239 : case cbor::CBORTokenTag::ARRAY_START:
240 0 : return parseArray(stack_depth + 1, tokenizer);
241 : default:
242 : // Error::CBOR_UNSUPPORTED_VALUE
243 : return nullptr;
244 : }
245 : }
246 :
247 : // |bytes| must start with the indefinite length array byte, so basically,
248 : // ParseArray may only be called after an indefinite length array has been
249 : // detected.
250 0 : std::unique_ptr<DictionaryValue> parseMap(
251 : int32_t stack_depth, cbor::CBORTokenizer* tokenizer) {
252 0 : auto dict = DictionaryValue::create();
253 : tokenizer->Next();
254 0 : while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) {
255 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) {
256 : // Error::CBOR_UNEXPECTED_EOF_IN_MAP
257 0 : return nullptr;
258 : }
259 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
260 : // Parse key.
261 : String key;
262 0 : if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) {
263 : span<uint8_t> key_span = tokenizer->GetString8();
264 0 : key = StringUtil::fromUTF8(key_span.data(), key_span.size());
265 : tokenizer->Next();
266 0 : } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) {
267 : return nullptr; // STRING16 not supported yet.
268 : } else {
269 : // Error::CBOR_INVALID_MAP_KEY
270 : return nullptr;
271 : }
272 : // Parse value.
273 0 : auto value = parseValue(stack_depth, tokenizer);
274 0 : if (!value) return nullptr;
275 0 : dict->setValue(key, std::move(value));
276 : }
277 : tokenizer->Next();
278 : return dict;
279 : }
280 :
281 : } // anonymous namespace
282 :
283 : // static
284 0 : std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
285 0 : span<uint8_t> bytes(data, size);
286 :
287 : // Error::CBOR_NO_INPUT
288 0 : if (bytes.empty()) return nullptr;
289 :
290 : // Error::CBOR_INVALID_START_BYTE
291 0 : if (bytes[0] != cbor::InitialByteForEnvelope()) return nullptr;
292 :
293 : cbor::CBORTokenizer tokenizer(bytes);
294 0 : if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
295 :
296 : // We checked for the envelope start byte above, so the tokenizer
297 : // must agree here, since it's not an error.
298 : DCHECK(tokenizer.TokenTag() == cbor::CBORTokenTag::ENVELOPE);
299 : tokenizer.EnterEnvelope();
300 : // Error::MAP_START_EXPECTED
301 0 : if (tokenizer.TokenTag() != cbor::CBORTokenTag::MAP_START) return nullptr;
302 0 : std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer);
303 0 : if (!result) return nullptr;
304 0 : if (tokenizer.TokenTag() == cbor::CBORTokenTag::DONE) return result;
305 0 : if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr;
306 : // Error::CBOR_TRAILING_JUNK
307 : return nullptr;
308 : }
309 :
310 0 : bool Value::asBoolean(bool*) const
311 : {
312 0 : return false;
313 : }
314 :
315 0 : bool Value::asDouble(double*) const
316 : {
317 0 : return false;
318 : }
319 :
320 5 : bool Value::asInteger(int*) const
321 : {
322 5 : return false;
323 : }
324 :
325 33 : bool Value::asString(String*) const
326 : {
327 33 : return false;
328 : }
329 :
330 0 : bool Value::asBinary(Binary*) const
331 : {
332 0 : return false;
333 : }
334 :
335 2667 : void Value::writeJSON(StringBuilder* output) const
336 : {
337 : DCHECK(m_type == TypeNull);
338 : StringUtil::builderAppend(*output, nullValueString, 4);
339 2667 : }
340 :
341 0 : void Value::writeBinary(std::vector<uint8_t>* bytes) const {
342 : DCHECK(m_type == TypeNull);
343 0 : bytes->push_back(cbor::EncodeNull());
344 0 : }
345 :
346 2667 : std::unique_ptr<Value> Value::clone() const
347 : {
348 2667 : return Value::null();
349 : }
350 :
351 659375 : String Value::toJSONString() const
352 : {
353 659375 : StringBuilder result;
354 : StringUtil::builderReserve(result, 512);
355 659375 : writeJSON(&result);
356 659375 : return StringUtil::builderToString(result);
357 : }
358 :
359 658979 : String Value::serializeToJSON() {
360 658979 : return toJSONString();
361 : }
362 :
363 0 : std::vector<uint8_t> Value::serializeToBinary() {
364 : std::vector<uint8_t> bytes;
365 0 : writeBinary(&bytes);
366 0 : return bytes;
367 : }
368 :
369 82361 : bool FundamentalValue::asBoolean(bool* output) const
370 : {
371 82361 : if (type() != TypeBoolean)
372 : return false;
373 82361 : *output = m_boolValue;
374 82361 : return true;
375 : }
376 :
377 35 : bool FundamentalValue::asDouble(double* output) const
378 : {
379 35 : if (type() == TypeDouble) {
380 0 : *output = m_doubleValue;
381 0 : return true;
382 : }
383 35 : if (type() == TypeInteger) {
384 35 : *output = m_integerValue;
385 35 : return true;
386 : }
387 : return false;
388 : }
389 :
390 348385 : bool FundamentalValue::asInteger(int* output) const
391 : {
392 348385 : if (type() != TypeInteger)
393 : return false;
394 348385 : *output = m_integerValue;
395 348385 : return true;
396 : }
397 :
398 12232131 : void FundamentalValue::writeJSON(StringBuilder* output) const
399 : {
400 : DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
401 12232131 : if (type() == TypeBoolean) {
402 10229634 : if (m_boolValue)
403 : StringUtil::builderAppend(*output, trueValueString, 4);
404 : else
405 : StringUtil::builderAppend(*output, falseValueString, 5);
406 2002497 : } else if (type() == TypeDouble) {
407 303936 : if (!std::isfinite(m_doubleValue)) {
408 : StringUtil::builderAppend(*output, nullValueString, 4);
409 : return;
410 : }
411 151963 : StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
412 1850529 : } else if (type() == TypeInteger) {
413 3701058 : StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
414 : }
415 : }
416 :
417 0 : void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const {
418 0 : switch (type()) {
419 : case TypeDouble:
420 0 : cbor::EncodeDouble(m_doubleValue, bytes);
421 : return;
422 : case TypeInteger:
423 0 : cbor::EncodeInt32(m_integerValue, bytes);
424 : return;
425 : case TypeBoolean:
426 0 : bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse());
427 0 : return;
428 : default:
429 : DCHECK(false);
430 : }
431 : }
432 :
433 167740 : std::unique_ptr<Value> FundamentalValue::clone() const
434 : {
435 167740 : switch (type()) {
436 144906 : case TypeDouble: return FundamentalValue::create(m_doubleValue);
437 837 : case TypeInteger: return FundamentalValue::create(m_integerValue);
438 21997 : case TypeBoolean: return FundamentalValue::create(m_boolValue);
439 : default:
440 : DCHECK(false);
441 : }
442 : return nullptr;
443 : }
444 :
445 268920 : bool StringValue::asString(String* output) const
446 : {
447 : *output = m_stringValue;
448 268920 : return true;
449 : }
450 :
451 16479594 : void StringValue::writeJSON(StringBuilder* output) const
452 : {
453 : DCHECK(type() == TypeString);
454 16479594 : StringUtil::builderAppendQuotedString(*output, m_stringValue);
455 16479594 : }
456 :
457 : namespace {
458 : // This routine distinguishes between the current encoding for a given
459 : // string |s|, and calls encoding routines that will
460 : // - Ensure that all ASCII strings end up being encoded as UTF8 in
461 : // the wire format - e.g., EncodeFromUTF16 will detect ASCII and
462 : // do the (trivial) transcode to STRING8 on the wire, but if it's
463 : // not ASCII it'll do STRING16.
464 : // - Select a format that's cheap to convert to. E.g., we don't
465 : // have LATIN1 on the wire, so we call EncodeFromLatin1 which
466 : // transcodes to UTF8 if needed.
467 0 : void EncodeString(const String& s, std::vector<uint8_t>* out) {
468 0 : if (StringUtil::CharacterCount(s) == 0) {
469 : cbor::EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string.
470 : } else if (StringUtil::CharactersLatin1(s)) {
471 : cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s),
472 : StringUtil::CharacterCount(s)),
473 : out);
474 0 : } else if (StringUtil::CharactersUTF16(s)) {
475 0 : cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s),
476 : StringUtil::CharacterCount(s)),
477 : out);
478 : } else if (StringUtil::CharactersUTF8(s)) {
479 : cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s),
480 : StringUtil::CharacterCount(s)),
481 : out);
482 : }
483 0 : }
484 : } // namespace
485 :
486 0 : void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
487 0 : EncodeString(m_stringValue, bytes);
488 0 : }
489 :
490 66050 : std::unique_ptr<Value> StringValue::clone() const
491 : {
492 132100 : return StringValue::create(m_stringValue);
493 : }
494 :
495 0 : bool BinaryValue::asBinary(Binary* output) const
496 : {
497 : *output = m_binaryValue;
498 0 : return true;
499 : }
500 :
501 0 : void BinaryValue::writeJSON(StringBuilder* output) const
502 : {
503 : DCHECK(type() == TypeBinary);
504 0 : StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64());
505 : }
506 :
507 0 : void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
508 : cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(),
509 0 : m_binaryValue.size()), bytes);
510 : }
511 :
512 0 : std::unique_ptr<Value> BinaryValue::clone() const
513 : {
514 0 : return BinaryValue::create(m_binaryValue);
515 : }
516 :
517 329034 : void SerializedValue::writeJSON(StringBuilder* output) const
518 : {
519 : DCHECK(type() == TypeSerialized);
520 329034 : StringUtil::builderAppend(*output, m_serializedJSON);
521 329034 : }
522 :
523 0 : void SerializedValue::writeBinary(std::vector<uint8_t>* output) const
524 : {
525 : DCHECK(type() == TypeSerialized);
526 0 : output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end());
527 0 : }
528 :
529 0 : std::unique_ptr<Value> SerializedValue::clone() const
530 : {
531 0 : return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
532 : }
533 :
534 15904380 : DictionaryValue::~DictionaryValue()
535 : {
536 7952190 : }
537 :
538 26856 : void DictionaryValue::setBoolean(const String& name, bool value)
539 : {
540 26856 : setValue(name, FundamentalValue::create(value));
541 26856 : }
542 :
543 168123 : void DictionaryValue::setInteger(const String& name, int value)
544 : {
545 168123 : setValue(name, FundamentalValue::create(value));
546 168123 : }
547 :
548 5 : void DictionaryValue::setDouble(const String& name, double value)
549 : {
550 5 : setValue(name, FundamentalValue::create(value));
551 5 : }
552 :
553 176662 : void DictionaryValue::setString(const String& name, const String& value)
554 : {
555 176662 : setValue(name, StringValue::create(value));
556 176662 : }
557 :
558 32538306 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
559 : {
560 34065403 : set(name, value);
561 32538306 : }
562 :
563 23512 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
564 : {
565 24423 : set(name, value);
566 23512 : }
567 :
568 10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
569 : {
570 10 : set(name, value);
571 10 : }
572 :
573 8367 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
574 : {
575 : protocol::Value* value = get(name);
576 8367 : if (!value)
577 : return false;
578 214 : return value->asBoolean(output);
579 : }
580 :
581 187862 : bool DictionaryValue::getInteger(const String& name, int* output) const
582 : {
583 : Value* value = get(name);
584 187862 : if (!value)
585 : return false;
586 187798 : return value->asInteger(output);
587 : }
588 :
589 0 : bool DictionaryValue::getDouble(const String& name, double* output) const
590 : {
591 : Value* value = get(name);
592 0 : if (!value)
593 : return false;
594 0 : return value->asDouble(output);
595 : }
596 :
597 110 : bool DictionaryValue::getString(const String& name, String* output) const
598 : {
599 : protocol::Value* value = get(name);
600 110 : if (!value)
601 : return false;
602 90 : return value->asString(output);
603 : }
604 :
605 173853 : DictionaryValue* DictionaryValue::getObject(const String& name) const
606 : {
607 173853 : return DictionaryValue::cast(get(name));
608 : }
609 :
610 0 : protocol::ListValue* DictionaryValue::getArray(const String& name) const
611 : {
612 0 : return ListValue::cast(get(name));
613 : }
614 :
615 655109 : protocol::Value* DictionaryValue::get(const String& name) const
616 : {
617 : Dictionary::const_iterator it = m_data.find(name);
618 1335135 : if (it == m_data.end())
619 : return nullptr;
620 310230 : return it->second.get();
621 : }
622 :
623 120 : DictionaryValue::Entry DictionaryValue::at(size_t index) const
624 : {
625 : const String key = m_order[index];
626 120 : return std::make_pair(key, m_data.find(key)->second.get());
627 : }
628 :
629 4488 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
630 : {
631 4488 : bool result = defaultValue;
632 4488 : getBoolean(name, &result);
633 4488 : return result;
634 : }
635 :
636 39 : int DictionaryValue::integerProperty(const String& name, int defaultValue) const
637 : {
638 39 : int result = defaultValue;
639 39 : getInteger(name, &result);
640 39 : return result;
641 : }
642 :
643 0 : double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
644 : {
645 0 : double result = defaultValue;
646 0 : getDouble(name, &result);
647 0 : return result;
648 : }
649 :
650 18302 : void DictionaryValue::remove(const String& name)
651 : {
652 : m_data.erase(name);
653 18302 : m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
654 18302 : }
655 :
656 7551430 : void DictionaryValue::writeJSON(StringBuilder* output) const
657 : {
658 : StringUtil::builderAppend(*output, '{');
659 73957302 : for (size_t i = 0; i < m_order.size(); ++i) {
660 : Dictionary::const_iterator it = m_data.find(m_order[i]);
661 33202936 : CHECK(it != m_data.end());
662 33202936 : if (i)
663 : StringUtil::builderAppend(*output, ',');
664 33202936 : StringUtil::builderAppendQuotedString(*output, it->first);
665 : StringUtil::builderAppend(*output, ':');
666 33202936 : it->second->writeJSON(output);
667 : }
668 : StringUtil::builderAppend(*output, '}');
669 7551430 : }
670 :
671 0 : void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
672 0 : cbor::EnvelopeEncoder encoder;
673 : encoder.EncodeStart(bytes);
674 0 : bytes->push_back(cbor::EncodeIndefiniteLengthMapStart());
675 0 : for (size_t i = 0; i < m_order.size(); ++i) {
676 : const String& key = m_order[i];
677 : Dictionary::const_iterator value = m_data.find(key);
678 : DCHECK(value != m_data.cend() && value->second);
679 0 : EncodeString(key, bytes);
680 0 : value->second->writeBinary(bytes);
681 : }
682 0 : bytes->push_back(cbor::EncodeStop());
683 : encoder.EncodeStop(bytes);
684 0 : }
685 :
686 3010 : std::unique_ptr<Value> DictionaryValue::clone() const
687 : {
688 3010 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
689 19618 : for (size_t i = 0; i < m_order.size(); ++i) {
690 : String key = m_order[i];
691 : Dictionary::const_iterator value = m_data.find(key);
692 : DCHECK(value != m_data.cend() && value->second);
693 16608 : result->setValue(key, value->second->clone());
694 : }
695 3010 : return std::move(result);
696 : }
697 :
698 7140461 : DictionaryValue::DictionaryValue()
699 7952190 : : Value(TypeObject)
700 : {
701 7140461 : }
702 :
703 811142 : ListValue::~ListValue()
704 : {
705 405571 : }
706 :
707 404636 : void ListValue::writeJSON(StringBuilder* output) const
708 : {
709 : StringUtil::builderAppend(*output, '[');
710 : bool first = true;
711 3541817 : for (const std::unique_ptr<protocol::Value>& value : m_data) {
712 3137181 : if (!first)
713 : StringUtil::builderAppend(*output, ',');
714 3137181 : value->writeJSON(output);
715 : first = false;
716 : }
717 : StringUtil::builderAppend(*output, ']');
718 404636 : }
719 :
720 0 : void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
721 0 : cbor::EnvelopeEncoder encoder;
722 : encoder.EncodeStart(bytes);
723 0 : bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart());
724 0 : for (size_t i = 0; i < m_data.size(); ++i) {
725 0 : m_data[i]->writeBinary(bytes);
726 : }
727 0 : bytes->push_back(cbor::EncodeStop());
728 : encoder.EncodeStop(bytes);
729 0 : }
730 :
731 270 : std::unique_ptr<Value> ListValue::clone() const
732 : {
733 270 : std::unique_ptr<ListValue> result = ListValue::create();
734 985 : for (const std::unique_ptr<protocol::Value>& value : m_data)
735 1430 : result->pushValue(value->clone());
736 270 : return std::move(result);
737 : }
738 :
739 404631 : ListValue::ListValue()
740 405571 : : Value(TypeArray)
741 : {
742 404631 : }
743 :
744 3137166 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
745 : {
746 : DCHECK(value);
747 3138741 : m_data.push_back(std::move(value));
748 3137166 : }
749 :
750 345 : protocol::Value* ListValue::at(size_t index)
751 : {
752 : DCHECK_LT(index, m_data.size());
753 345 : return m_data[index].get();
754 : }
755 :
756 0 : void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
757 : {
758 0 : escapeStringForJSONInternal<uint8_t>(str, len, dst);
759 0 : }
760 :
761 49491077 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
762 : {
763 49491077 : escapeStringForJSONInternal<uint16_t>(str, len, dst);
764 49491077 : }
765 :
766 : } // namespace v8_inspector
767 : } // namespace protocol
768 :
769 :
770 : // This file is generated by Object_cpp.template.
771 :
772 : // Copyright 2016 The Chromium Authors. All rights reserved.
773 : // Use of this source code is governed by a BSD-style license that can be
774 : // found in the LICENSE file.
775 :
776 : //#include "Object.h"
777 :
778 : namespace v8_inspector {
779 : namespace protocol {
780 :
781 0 : std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
782 : {
783 : protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
784 0 : if (!dictionary) {
785 0 : errors->addError("object expected");
786 : return nullptr;
787 : }
788 0 : dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
789 0 : return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
790 : }
791 :
792 0 : std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
793 : {
794 0 : return DictionaryValue::cast(m_object->clone());
795 : }
796 :
797 0 : std::unique_ptr<Object> Object::clone() const
798 : {
799 0 : return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
800 : }
801 :
802 0 : Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
803 :
804 0 : Object::~Object() { }
805 :
806 : } // namespace v8_inspector
807 : } // namespace protocol
808 :
809 :
810 : // This file is generated by DispatcherBase_cpp.template.
811 :
812 : // Copyright 2016 The Chromium Authors. All rights reserved.
813 : // Use of this source code is governed by a BSD-style license that can be
814 : // found in the LICENSE file.
815 :
816 : //#include "DispatcherBase.h"
817 : //#include "Parser.h"
818 :
819 : namespace v8_inspector {
820 : namespace protocol {
821 :
822 : // static
823 10528114 : DispatchResponse DispatchResponse::OK()
824 : {
825 : DispatchResponse result;
826 10528114 : result.m_status = kSuccess;
827 10528114 : result.m_errorCode = kParseError;
828 10528114 : return result;
829 : }
830 :
831 : // static
832 1535 : DispatchResponse DispatchResponse::Error(const String& error)
833 : {
834 : DispatchResponse result;
835 1535 : result.m_status = kError;
836 1535 : result.m_errorCode = kServerError;
837 : result.m_errorMessage = error;
838 1535 : return result;
839 : }
840 :
841 : // static
842 133 : DispatchResponse DispatchResponse::InternalError()
843 : {
844 : DispatchResponse result;
845 133 : result.m_status = kError;
846 133 : result.m_errorCode = kInternalError;
847 266 : result.m_errorMessage = "Internal error";
848 133 : return result;
849 : }
850 :
851 : // static
852 0 : DispatchResponse DispatchResponse::InvalidParams(const String& error)
853 : {
854 : DispatchResponse result;
855 0 : result.m_status = kError;
856 0 : result.m_errorCode = kInvalidParams;
857 : result.m_errorMessage = error;
858 0 : return result;
859 : }
860 :
861 : // static
862 0 : DispatchResponse DispatchResponse::FallThrough()
863 : {
864 : DispatchResponse result;
865 0 : result.m_status = kFallThrough;
866 0 : result.m_errorCode = kParseError;
867 0 : return result;
868 : }
869 :
870 : // static
871 : const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
872 :
873 164831 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
874 :
875 319685 : DispatcherBase::WeakPtr::~WeakPtr()
876 : {
877 164831 : if (m_dispatcher)
878 329642 : m_dispatcher->m_weakPtrs.erase(this);
879 154854 : }
880 :
881 9977 : DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
882 : : m_backendImpl(std::move(backendImpl))
883 : , m_callId(callId)
884 : , m_method(method)
885 29931 : , m_message(message) { }
886 :
887 : DispatcherBase::Callback::~Callback() = default;
888 :
889 0 : void DispatcherBase::Callback::dispose()
890 : {
891 : m_backendImpl = nullptr;
892 0 : }
893 :
894 9977 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
895 : {
896 19954 : if (!m_backendImpl || !m_backendImpl->get())
897 : return;
898 19944 : m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
899 : m_backendImpl = nullptr;
900 : }
901 :
902 0 : void DispatcherBase::Callback::fallThroughIfActive()
903 : {
904 0 : if (!m_backendImpl || !m_backendImpl->get())
905 : return;
906 0 : m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
907 : m_backendImpl = nullptr;
908 : }
909 :
910 23274 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
911 46548 : : m_frontendChannel(frontendChannel) { }
912 :
913 46548 : DispatcherBase::~DispatcherBase()
914 : {
915 : clearFrontend();
916 23274 : }
917 :
918 154849 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
919 : {
920 154849 : if (!m_frontendChannel)
921 : return;
922 154849 : if (response.status() == DispatchResponse::kError) {
923 : reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
924 : return;
925 : }
926 924006 : m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
927 : }
928 :
929 57112 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
930 : {
931 114224 : sendResponse(callId, response, DictionaryValue::create());
932 57112 : }
933 :
934 : namespace {
935 :
936 : class ProtocolError : public Serializable {
937 : public:
938 911 : static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
939 : {
940 911 : std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
941 911 : protocolError->m_callId = callId;
942 911 : protocolError->m_hasCallId = true;
943 970 : if (errors && errors->hasErrors())
944 118 : protocolError->m_data = errors->errors();
945 911 : return protocolError;
946 : }
947 :
948 : static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
949 : {
950 0 : return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
951 : }
952 :
953 911 : String serializeToJSON() override
954 : {
955 2733 : return serialize()->serializeToJSON();
956 : }
957 :
958 0 : std::vector<uint8_t> serializeToBinary() override
959 : {
960 0 : return serialize()->serializeToBinary();
961 : }
962 :
963 2733 : ~ProtocolError() override {}
964 :
965 : private:
966 911 : ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
967 : : m_code(code)
968 1822 : , m_errorMessage(errorMessage)
969 : {
970 911 : }
971 :
972 911 : std::unique_ptr<DictionaryValue> serialize() {
973 911 : std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
974 2733 : error->setInteger("code", m_code);
975 2733 : error->setString("message", m_errorMessage);
976 911 : if (m_data.length())
977 177 : error->setString("data", m_data);
978 911 : std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
979 2733 : message->setObject("error", std::move(error));
980 911 : if (m_hasCallId)
981 2733 : message->setInteger("id", m_callId);
982 911 : return message;
983 : }
984 :
985 : DispatchResponse::ErrorCode m_code;
986 : String m_errorMessage;
987 : String m_data;
988 : int m_callId = 0;
989 : bool m_hasCallId = false;
990 : };
991 :
992 : } // namespace
993 :
994 911 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
995 : {
996 911 : if (frontendChannel)
997 2733 : frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
998 911 : }
999 :
1000 0 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
1001 : {
1002 0 : if (frontendChannel)
1003 0 : frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
1004 0 : }
1005 :
1006 59 : void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
1007 : {
1008 907 : reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
1009 59 : }
1010 :
1011 0 : void DispatcherBase::clearFrontend()
1012 : {
1013 23274 : m_frontendChannel = nullptr;
1014 23284 : for (auto& weak : m_weakPtrs)
1015 10 : weak->dispose();
1016 : m_weakPtrs.clear();
1017 0 : }
1018 :
1019 164831 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
1020 : {
1021 164831 : std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
1022 329662 : m_weakPtrs.insert(weak.get());
1023 164831 : return weak;
1024 : }
1025 :
1026 3879 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
1027 7758 : : m_frontendChannel(frontendChannel) { }
1028 :
1029 23274 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
1030 : {
1031 : m_dispatchers[name] = std::move(dispatcher);
1032 23274 : }
1033 :
1034 23274 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
1035 : {
1036 27153 : for (const auto& pair : redirects)
1037 3879 : m_redirects[pair.first] = pair.second;
1038 23274 : }
1039 :
1040 154917 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
1041 154917 : if (!parsedMessage) {
1042 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
1043 0 : return false;
1044 : }
1045 : protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
1046 154917 : if (!messageObject) {
1047 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
1048 0 : return false;
1049 : }
1050 :
1051 154917 : int callId = 0;
1052 309834 : protocol::Value* callIdValue = messageObject->get("id");
1053 154917 : bool success = callIdValue && callIdValue->asInteger(&callId);
1054 154917 : if (!success) {
1055 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
1056 0 : return false;
1057 : }
1058 154917 : if (outCallId)
1059 154917 : *outCallId = callId;
1060 :
1061 309834 : protocol::Value* methodValue = messageObject->get("method");
1062 : String method;
1063 154917 : success = methodValue && methodValue->asString(&method);
1064 154917 : if (!success) {
1065 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
1066 0 : return false;
1067 : }
1068 154917 : if (outMethod)
1069 : *outMethod = method;
1070 : return true;
1071 : }
1072 :
1073 154917 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
1074 154917 : size_t dotIndex = StringUtil::find(method, ".");
1075 154917 : if (dotIndex == StringUtil::kNotFound)
1076 : return nullptr;
1077 : String domain = StringUtil::substring(method, 0, dotIndex);
1078 : auto it = m_dispatchers.find(domain);
1079 154917 : if (it == m_dispatchers.end())
1080 : return nullptr;
1081 154917 : if (!it->second->canDispatch(method))
1082 : return nullptr;
1083 154913 : return it->second.get();
1084 : }
1085 :
1086 0 : bool UberDispatcher::canDispatch(const String& in_method)
1087 : {
1088 : String method = in_method;
1089 : auto redirectIt = m_redirects.find(method);
1090 0 : if (redirectIt != m_redirects.end())
1091 : method = redirectIt->second;
1092 0 : return !!findDispatcher(method);
1093 : }
1094 :
1095 154917 : void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
1096 : {
1097 : String method = in_method;
1098 : auto redirectIt = m_redirects.find(method);
1099 154917 : if (redirectIt != m_redirects.end())
1100 : method = redirectIt->second;
1101 154917 : protocol::DispatcherBase* dispatcher = findDispatcher(method);
1102 154917 : if (!dispatcher) {
1103 16 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
1104 : return;
1105 : }
1106 : std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
1107 464739 : dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
1108 : }
1109 :
1110 : UberDispatcher::~UberDispatcher() = default;
1111 :
1112 : // static
1113 154001 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
1114 : {
1115 616004 : return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
1116 : }
1117 :
1118 : // static
1119 175033 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
1120 : {
1121 350066 : return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
1122 : }
1123 :
1124 329034 : String InternalResponse::serializeToJSON()
1125 : {
1126 329034 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
1127 768490 : std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
1128 329034 : if (m_notification.length()) {
1129 525099 : result->setString("method", m_notification);
1130 875165 : result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
1131 : } else {
1132 462003 : result->setInteger("id", m_callId);
1133 770005 : result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
1134 : }
1135 658068 : return result->serializeToJSON();
1136 : }
1137 :
1138 0 : std::vector<uint8_t> InternalResponse::serializeToBinary()
1139 : {
1140 0 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
1141 0 : std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
1142 0 : if (m_notification.length()) {
1143 0 : result->setString("method", m_notification);
1144 0 : result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
1145 : } else {
1146 0 : result->setInteger("id", m_callId);
1147 0 : result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
1148 : }
1149 0 : return result->serializeToBinary();
1150 : }
1151 :
1152 329034 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
1153 : : m_callId(callId)
1154 : , m_notification(notification)
1155 658068 : , m_params(params ? std::move(params) : nullptr)
1156 : {
1157 329034 : }
1158 :
1159 : } // namespace v8_inspector
1160 : } // namespace protocol
1161 :
1162 :
1163 : // This file is generated by Parser_cpp.template.
1164 :
1165 : // Copyright 2016 The Chromium Authors. All rights reserved.
1166 : // Use of this source code is governed by a BSD-style license that can be
1167 : // found in the LICENSE file.
1168 :
1169 : namespace v8_inspector {
1170 : namespace protocol {
1171 :
1172 : namespace {
1173 :
1174 : const int stackLimit = 1000;
1175 :
1176 : enum Token {
1177 : ObjectBegin,
1178 : ObjectEnd,
1179 : ArrayBegin,
1180 : ArrayEnd,
1181 : StringLiteral,
1182 : Number,
1183 : BoolTrue,
1184 : BoolFalse,
1185 : NullToken,
1186 : ListSeparator,
1187 : ObjectPairSeparator,
1188 : InvalidToken,
1189 : };
1190 :
1191 : const char* const nullString = "null";
1192 : const char* const trueString = "true";
1193 : const char* const falseString = "false";
1194 :
1195 : bool isASCII(uint16_t c)
1196 : {
1197 5149828 : return !(c & ~0x7F);
1198 : }
1199 :
1200 : bool isSpaceOrNewLine(uint16_t c)
1201 : {
1202 4354442 : return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
1203 : }
1204 :
1205 349830 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
1206 : {
1207 : std::vector<char> buffer;
1208 349830 : buffer.reserve(length + 1);
1209 1940602 : for (size_t i = 0; i < length; ++i) {
1210 1590772 : if (!isASCII(characters[i])) {
1211 0 : *ok = false;
1212 0 : return 0;
1213 : }
1214 1590772 : buffer.push_back(static_cast<char>(characters[i]));
1215 : }
1216 699660 : buffer.push_back('\0');
1217 349830 : return StringUtil::toDouble(buffer.data(), length, ok);
1218 : }
1219 :
1220 0 : double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
1221 : {
1222 : std::string buffer(reinterpret_cast<const char*>(characters), length);
1223 0 : return StringUtil::toDouble(buffer.data(), length, ok);
1224 : }
1225 :
1226 : template<typename Char>
1227 : bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
1228 : {
1229 419209 : while (start < end && *token != '\0' && *start++ == *token++) { }
1230 82440 : if (*token != '\0')
1231 : return false;
1232 82435 : *tokenEnd = start;
1233 : return true;
1234 : }
1235 :
1236 : template<typename Char>
1237 : bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
1238 : {
1239 349835 : if (start == end)
1240 : return false;
1241 349830 : bool haveLeadingZero = '0' == *start;
1242 : int length = 0;
1243 1145203 : while (start < end && '0' <= *start && *start <= '9') {
1244 795368 : ++start;
1245 795368 : ++length;
1246 : }
1247 349835 : if (!length)
1248 : return false;
1249 349830 : if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
1250 : return false;
1251 : *tokenEnd = start;
1252 : return true;
1253 : }
1254 :
1255 : template<typename Char>
1256 349830 : bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
1257 : {
1258 : // We just grab the number here. We validate the size in DecodeNumber.
1259 : // According to RFC4627, a valid number is: [minus] int [frac] [exp]
1260 349830 : if (start == end)
1261 : return false;
1262 349830 : Char c = *start;
1263 349830 : if ('-' == c)
1264 13 : ++start;
1265 :
1266 349830 : if (!readInt(start, end, &start, false))
1267 : return false;
1268 349830 : if (start == end) {
1269 5 : *tokenEnd = start;
1270 5 : return true;
1271 : }
1272 :
1273 : // Optional fraction part
1274 349825 : c = *start;
1275 349825 : if ('.' == c) {
1276 5 : ++start;
1277 5 : if (!readInt(start, end, &start, true))
1278 : return false;
1279 5 : if (start == end) {
1280 0 : *tokenEnd = start;
1281 0 : return true;
1282 : }
1283 5 : c = *start;
1284 : }
1285 :
1286 : // Optional exponent part
1287 349825 : if ('e' == c || 'E' == c) {
1288 0 : ++start;
1289 0 : if (start == end)
1290 : return false;
1291 0 : c = *start;
1292 0 : if ('-' == c || '+' == c) {
1293 0 : ++start;
1294 0 : if (start == end)
1295 : return false;
1296 : }
1297 0 : if (!readInt(start, end, &start, true))
1298 : return false;
1299 : }
1300 :
1301 349825 : *tokenEnd = start;
1302 349825 : return true;
1303 : }
1304 :
1305 : template<typename Char>
1306 : bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
1307 : {
1308 45 : if (end - start < digits)
1309 : return false;
1310 405 : for (int i = 0; i < digits; ++i) {
1311 180 : Char c = *start++;
1312 180 : if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
1313 : return false;
1314 : }
1315 : *tokenEnd = start;
1316 : return true;
1317 : }
1318 :
1319 : template<typename Char>
1320 1087687 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1321 : {
1322 13433629 : while (start < end) {
1323 13433629 : Char c = *start++;
1324 13433629 : if ('\\' == c) {
1325 334337 : if (start == end)
1326 : return false;
1327 334337 : c = *start++;
1328 : // Make sure the escaped char is valid.
1329 334337 : switch (c) {
1330 : case 'x':
1331 0 : if (!readHexDigits(start, end, &start, 2))
1332 : return false;
1333 : break;
1334 : case 'u':
1335 45 : if (!readHexDigits(start, end, &start, 4))
1336 : return false;
1337 : break;
1338 : case '\\':
1339 : case '/':
1340 : case 'b':
1341 : case 'f':
1342 : case 'n':
1343 : case 'r':
1344 : case 't':
1345 : case 'v':
1346 : case '"':
1347 : break;
1348 : default:
1349 : return false;
1350 : }
1351 13099292 : } else if ('"' == c) {
1352 1087687 : *tokenEnd = start;
1353 1087687 : return true;
1354 : }
1355 : }
1356 : return false;
1357 : }
1358 :
1359 : template<typename Char>
1360 0 : bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
1361 : {
1362 0 : if (start == end)
1363 : return false;
1364 :
1365 0 : if (*start != '/' || start + 1 >= end)
1366 : return false;
1367 : ++start;
1368 :
1369 0 : if (*start == '/') {
1370 : // Single line comment, read to newline.
1371 0 : for (++start; start < end; ++start) {
1372 0 : if (*start == '\n' || *start == '\r') {
1373 0 : *commentEnd = start + 1;
1374 0 : return true;
1375 : }
1376 : }
1377 0 : *commentEnd = end;
1378 : // Comment reaches end-of-input, which is fine.
1379 0 : return true;
1380 : }
1381 :
1382 0 : if (*start == '*') {
1383 : Char previous = '\0';
1384 : // Block comment, read until end marker.
1385 0 : for (++start; start < end; previous = *start++) {
1386 0 : if (previous == '*' && *start == '/') {
1387 0 : *commentEnd = start + 1;
1388 0 : return true;
1389 : }
1390 : }
1391 : // Block comment must close before end-of-input.
1392 : return false;
1393 : }
1394 :
1395 : return false;
1396 : }
1397 :
1398 : template<typename Char>
1399 4603393 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1400 : {
1401 4603393 : while (start < end) {
1402 8708884 : if (isSpaceOrNewLine(*start)) {
1403 0 : ++start;
1404 4354442 : } else if (*start == '/') {
1405 : const Char* commentEnd;
1406 0 : if (!skipComment(start, end, &commentEnd))
1407 : break;
1408 0 : start = commentEnd;
1409 : } else {
1410 : break;
1411 : }
1412 : }
1413 4603393 : *whitespaceEnd = start;
1414 4603393 : }
1415 :
1416 : template<typename Char>
1417 3535469 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1418 : {
1419 3535469 : skipWhitespaceAndComments(start, end, tokenStart);
1420 3535469 : start = *tokenStart;
1421 :
1422 3535469 : if (start == end)
1423 : return InvalidToken;
1424 :
1425 3535469 : switch (*start) {
1426 : case 'n':
1427 5 : if (parseConstToken(start, end, tokenEnd, nullString))
1428 : return NullToken;
1429 : break;
1430 : case 't':
1431 75411 : if (parseConstToken(start, end, tokenEnd, trueString))
1432 : return BoolTrue;
1433 : break;
1434 : case 'f':
1435 7024 : if (parseConstToken(start, end, tokenEnd, falseString))
1436 : return BoolFalse;
1437 : break;
1438 : case '[':
1439 670 : *tokenEnd = start + 1;
1440 670 : return ArrayBegin;
1441 : case ']':
1442 670 : *tokenEnd = start + 1;
1443 670 : return ArrayEnd;
1444 : case ',':
1445 464244 : *tokenEnd = start + 1;
1446 464244 : return ListSeparator;
1447 : case '{':
1448 366275 : *tokenEnd = start + 1;
1449 366275 : return ObjectBegin;
1450 : case '}':
1451 365540 : *tokenEnd = start + 1;
1452 365540 : return ObjectEnd;
1453 : case ':':
1454 818113 : *tokenEnd = start + 1;
1455 818113 : return ObjectPairSeparator;
1456 : case '0':
1457 : case '1':
1458 : case '2':
1459 : case '3':
1460 : case '4':
1461 : case '5':
1462 : case '6':
1463 : case '7':
1464 : case '8':
1465 : case '9':
1466 : case '-':
1467 349830 : if (parseNumberToken(start, end, tokenEnd))
1468 : return Number;
1469 : break;
1470 : case '"':
1471 1087687 : if (parseStringToken(start + 1, end, tokenEnd))
1472 : return StringLiteral;
1473 : break;
1474 : }
1475 : return InvalidToken;
1476 : }
1477 :
1478 : template<typename Char>
1479 : int hexToInt(Char c)
1480 : {
1481 180 : if ('0' <= c && c <= '9')
1482 170 : return c - '0';
1483 10 : if ('A' <= c && c <= 'F')
1484 10 : return c - 'A' + 10;
1485 0 : if ('a' <= c && c <= 'f')
1486 0 : return c - 'a' + 10;
1487 : DCHECK(false);
1488 : return 0;
1489 : }
1490 :
1491 : template<typename Char>
1492 1087356 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1493 : {
1494 13432203 : while (start < end) {
1495 12344847 : uint16_t c = *start++;
1496 12344847 : if ('\\' != c) {
1497 : StringUtil::builderAppend(*output, c);
1498 : continue;
1499 : }
1500 334337 : if (start == end)
1501 : return false;
1502 334337 : c = *start++;
1503 :
1504 334337 : if (c == 'x') {
1505 : // \x is not supported.
1506 : return false;
1507 : }
1508 :
1509 334337 : switch (c) {
1510 : case '"':
1511 : case '/':
1512 : case '\\':
1513 : break;
1514 : case 'b':
1515 : c = '\b';
1516 0 : break;
1517 : case 'f':
1518 : c = '\f';
1519 0 : break;
1520 : case 'n':
1521 : c = '\n';
1522 7207 : break;
1523 : case 'r':
1524 : c = '\r';
1525 0 : break;
1526 : case 't':
1527 : c = '\t';
1528 0 : break;
1529 : case 'v':
1530 : c = '\v';
1531 0 : break;
1532 : case 'u':
1533 225 : c = (hexToInt(*start) << 12) +
1534 45 : (hexToInt(*(start + 1)) << 8) +
1535 45 : (hexToInt(*(start + 2)) << 4) +
1536 45 : hexToInt(*(start + 3));
1537 45 : start += 4;
1538 45 : break;
1539 : default:
1540 : return false;
1541 : }
1542 : StringUtil::builderAppend(*output, c);
1543 : }
1544 : return true;
1545 : }
1546 :
1547 : template<typename Char>
1548 1087562 : bool decodeString(const Char* start, const Char* end, String* output)
1549 : {
1550 1087562 : if (start == end) {
1551 412 : *output = "";
1552 206 : return true;
1553 : }
1554 1087356 : if (start > end)
1555 : return false;
1556 1087356 : StringBuilder buffer;
1557 1087356 : StringUtil::builderReserve(buffer, end - start);
1558 1087356 : if (!decodeString(start, end, &buffer))
1559 : return false;
1560 1087356 : *output = StringUtil::builderToString(buffer);
1561 1087356 : return true;
1562 : }
1563 :
1564 : template<typename Char>
1565 1067929 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1566 : {
1567 1067929 : if (depth > stackLimit)
1568 : return nullptr;
1569 :
1570 : std::unique_ptr<Value> result;
1571 : const Char* tokenStart;
1572 : const Char* tokenEnd;
1573 1067929 : Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1574 1067929 : switch (token) {
1575 : case InvalidToken:
1576 : return nullptr;
1577 : case NullToken:
1578 : result = Value::null();
1579 5 : break;
1580 : case BoolTrue:
1581 : result = FundamentalValue::create(true);
1582 75411 : break;
1583 : case BoolFalse:
1584 : result = FundamentalValue::create(false);
1585 7019 : break;
1586 : case Number: {
1587 : bool ok;
1588 349830 : double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1589 349830 : if (!ok)
1590 0 : return nullptr;
1591 349830 : if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
1592 349825 : result = FundamentalValue::create(static_cast<int>(value));
1593 : else
1594 : result = FundamentalValue::create(value);
1595 349830 : break;
1596 : }
1597 : case StringLiteral: {
1598 : String value;
1599 269449 : bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1600 269449 : if (!ok)
1601 : return nullptr;
1602 : result = StringValue::create(value);
1603 : break;
1604 : }
1605 : case ArrayBegin: {
1606 670 : std::unique_ptr<ListValue> array = ListValue::create();
1607 670 : start = tokenEnd;
1608 670 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1609 1530 : while (token != ArrayEnd) {
1610 860 : std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
1611 860 : if (!arrayNode)
1612 : return nullptr;
1613 860 : array->pushValue(std::move(arrayNode));
1614 :
1615 : // After a list value, we expect a comma or the end of the list.
1616 860 : start = tokenEnd;
1617 860 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1618 860 : if (token == ListSeparator) {
1619 258 : start = tokenEnd;
1620 258 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1621 258 : if (token == ArrayEnd)
1622 : return nullptr;
1623 602 : } else if (token != ArrayEnd) {
1624 : // Unexpected value after list value. Bail out.
1625 : return nullptr;
1626 : }
1627 : }
1628 670 : if (token != ArrayEnd)
1629 : return nullptr;
1630 : result = std::move(array);
1631 : break;
1632 : }
1633 : case ObjectBegin: {
1634 365540 : std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1635 365540 : start = tokenEnd;
1636 365540 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1637 1183653 : while (token != ObjectEnd) {
1638 818113 : if (token != StringLiteral)
1639 0 : return nullptr;
1640 : String key;
1641 818113 : if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1642 : return nullptr;
1643 818113 : start = tokenEnd;
1644 :
1645 818113 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1646 818113 : if (token != ObjectPairSeparator)
1647 : return nullptr;
1648 818113 : start = tokenEnd;
1649 :
1650 818113 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
1651 818113 : if (!value)
1652 : return nullptr;
1653 818113 : object->setValue(key, std::move(value));
1654 818113 : start = tokenEnd;
1655 :
1656 : // After a key/value pair, we expect a comma or the end of the
1657 : // object.
1658 818113 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1659 818113 : if (token == ListSeparator) {
1660 463986 : start = tokenEnd;
1661 463986 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1662 463986 : if (token == ObjectEnd)
1663 : return nullptr;
1664 354127 : } else if (token != ObjectEnd) {
1665 : // Unexpected value after last object value. Bail out.
1666 : return nullptr;
1667 : }
1668 : }
1669 365540 : if (token != ObjectEnd)
1670 : return nullptr;
1671 : result = std::move(object);
1672 : break;
1673 : }
1674 :
1675 : default:
1676 : // We got a token that's not a value.
1677 : return nullptr;
1678 : }
1679 :
1680 1067924 : skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1681 : return result;
1682 : }
1683 :
1684 : template<typename Char>
1685 248956 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1686 : {
1687 248956 : const Char* end = start + length;
1688 : const Char *tokenEnd;
1689 248956 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1690 248956 : if (!value || tokenEnd != end)
1691 : return nullptr;
1692 : return value;
1693 : }
1694 :
1695 : } // anonymous namespace
1696 :
1697 248956 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1698 : {
1699 248956 : return parseJSONInternal<uint16_t>(characters, length);
1700 : }
1701 :
1702 0 : std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
1703 : {
1704 0 : return parseJSONInternal<uint8_t>(characters, length);
1705 : }
1706 :
1707 : } // namespace v8_inspector
1708 : } // namespace protocol
1709 :
1710 :
1711 : // Generated by lib/encoding_cpp.template.
1712 :
1713 : // Copyright 2019 The Chromium Authors. All rights reserved.
1714 : // Use of this source code is governed by a BSD-style license that can be
1715 : // found in the LICENSE file.
1716 :
1717 :
1718 : #include <cassert>
1719 : #include <cmath>
1720 : #include <cstring>
1721 : #include <limits>
1722 : #include <stack>
1723 :
1724 : namespace v8_inspector {
1725 : namespace protocol {
1726 :
1727 : // ===== encoding/encoding.cc =====
1728 :
1729 : namespace cbor {
1730 : namespace {
1731 : // Indicates the number of bits the "initial byte" needs to be shifted to the
1732 : // right after applying |kMajorTypeMask| to produce the major type in the
1733 : // lowermost bits.
1734 : static constexpr uint8_t kMajorTypeBitShift = 5u;
1735 : // Mask selecting the low-order 5 bits of the "initial byte", which is where
1736 : // the additional information is encoded.
1737 : static constexpr uint8_t kAdditionalInformationMask = 0x1f;
1738 : // Mask selecting the high-order 3 bits of the "initial byte", which indicates
1739 : // the major type of the encoded value.
1740 : static constexpr uint8_t kMajorTypeMask = 0xe0;
1741 : // Indicates the integer is in the following byte.
1742 : static constexpr uint8_t kAdditionalInformation1Byte = 24u;
1743 : // Indicates the integer is in the next 2 bytes.
1744 : static constexpr uint8_t kAdditionalInformation2Bytes = 25u;
1745 : // Indicates the integer is in the next 4 bytes.
1746 : static constexpr uint8_t kAdditionalInformation4Bytes = 26u;
1747 : // Indicates the integer is in the next 8 bytes.
1748 : static constexpr uint8_t kAdditionalInformation8Bytes = 27u;
1749 :
1750 : // Encodes the initial byte, consisting of the |type| in the first 3 bits
1751 : // followed by 5 bits of |additional_info|.
1752 : constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) {
1753 0 : return (static_cast<uint8_t>(type) << kMajorTypeBitShift) |
1754 0 : (additional_info & kAdditionalInformationMask);
1755 : }
1756 :
1757 : // TAG 24 indicates that what follows is a byte string which is
1758 : // encoded in CBOR format. We use this as a wrapper for
1759 : // maps and arrays, allowing us to skip them, because the
1760 : // byte string carries its size (byte length).
1761 : // https://tools.ietf.org/html/rfc7049#section-2.4.4.1
1762 : static constexpr uint8_t kInitialByteForEnvelope =
1763 : EncodeInitialByte(MajorType::TAG, 24);
1764 : // The initial byte for a byte string with at most 2^32 bytes
1765 : // of payload. This is used for envelope encoding, even if
1766 : // the byte string is shorter.
1767 : static constexpr uint8_t kInitialByteFor32BitLengthByteString =
1768 : EncodeInitialByte(MajorType::BYTE_STRING, 26);
1769 :
1770 : // See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional
1771 : // info = 31.
1772 : static constexpr uint8_t kInitialByteIndefiniteLengthArray =
1773 : EncodeInitialByte(MajorType::ARRAY, 31);
1774 : static constexpr uint8_t kInitialByteIndefiniteLengthMap =
1775 : EncodeInitialByte(MajorType::MAP, 31);
1776 : // See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite
1777 : // length maps / arrays.
1778 : static constexpr uint8_t kStopByte =
1779 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 31);
1780 :
1781 : // See RFC 7049 Section 2.3, Table 2.
1782 : static constexpr uint8_t kEncodedTrue =
1783 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
1784 : static constexpr uint8_t kEncodedFalse =
1785 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
1786 : static constexpr uint8_t kEncodedNull =
1787 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
1788 : static constexpr uint8_t kInitialByteForDouble =
1789 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
1790 :
1791 : // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
1792 : // arbitrary binary data encoded as BYTE_STRING.
1793 : static constexpr uint8_t kExpectedConversionToBase64Tag =
1794 : EncodeInitialByte(MajorType::TAG, 22);
1795 :
1796 : // Writes the bytes for |v| to |out|, starting with the most significant byte.
1797 : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1798 : template <typename T, class C>
1799 : void WriteBytesMostSignificantByteFirst(T v, C* out) {
1800 0 : for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
1801 0 : out->push_back(0xff & (v >> (shift_bytes * 8)));
1802 : }
1803 :
1804 : // Extracts sizeof(T) bytes from |in| to extract a value of type T
1805 : // (e.g. uint64_t, uint32_t, ...), most significant byte first.
1806 : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1807 : template <typename T>
1808 : T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
1809 : assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
1810 : T result = 0;
1811 0 : for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
1812 0 : result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
1813 : return result;
1814 : }
1815 : } // namespace
1816 :
1817 : namespace internals {
1818 : // Reads the start of a token with definitive size from |bytes|.
1819 : // |type| is the major type as specified in RFC 7049 Section 2.1.
1820 : // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size
1821 : // (e.g. for BYTE_STRING).
1822 : // If successful, returns the number of bytes read. Otherwise returns -1.
1823 0 : int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
1824 0 : if (bytes.empty())
1825 : return -1;
1826 0 : uint8_t initial_byte = bytes[0];
1827 0 : *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
1828 :
1829 0 : uint8_t additional_information = initial_byte & kAdditionalInformationMask;
1830 0 : if (additional_information < 24) {
1831 : // Values 0-23 are encoded directly into the additional info of the
1832 : // initial byte.
1833 0 : *value = additional_information;
1834 0 : return 1;
1835 : }
1836 0 : if (additional_information == kAdditionalInformation1Byte) {
1837 : // Values 24-255 are encoded with one initial byte, followed by the value.
1838 0 : if (bytes.size() < 2)
1839 : return -1;
1840 0 : *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
1841 0 : return 2;
1842 : }
1843 0 : if (additional_information == kAdditionalInformation2Bytes) {
1844 : // Values 256-65535: 1 initial byte + 2 bytes payload.
1845 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
1846 : return -1;
1847 0 : *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
1848 0 : return 3;
1849 : }
1850 0 : if (additional_information == kAdditionalInformation4Bytes) {
1851 : // 32 bit uint: 1 initial byte + 4 bytes payload.
1852 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
1853 : return -1;
1854 0 : *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
1855 0 : return 5;
1856 : }
1857 0 : if (additional_information == kAdditionalInformation8Bytes) {
1858 : // 64 bit uint: 1 initial byte + 8 bytes payload.
1859 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
1860 : return -1;
1861 0 : *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
1862 0 : return 9;
1863 : }
1864 : return -1;
1865 : }
1866 :
1867 : // Writes the start of a token with |type|. The |value| may indicate the size,
1868 : // or it may be the payload if the value is an unsigned integer.
1869 : template <typename C>
1870 0 : void WriteTokenStartTmpl(MajorType type, uint64_t value, C* encoded) {
1871 0 : if (value < 24) {
1872 : // Values 0-23 are encoded directly into the additional info of the
1873 : // initial byte.
1874 0 : encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value));
1875 0 : return;
1876 : }
1877 0 : if (value <= std::numeric_limits<uint8_t>::max()) {
1878 : // Values 24-255 are encoded with one initial byte, followed by the value.
1879 0 : encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte));
1880 0 : encoded->push_back(value);
1881 0 : return;
1882 : }
1883 0 : if (value <= std::numeric_limits<uint16_t>::max()) {
1884 : // Values 256-65535: 1 initial byte + 2 bytes payload.
1885 0 : encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes));
1886 0 : WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded);
1887 : return;
1888 : }
1889 0 : if (value <= std::numeric_limits<uint32_t>::max()) {
1890 : // 32 bit uint: 1 initial byte + 4 bytes payload.
1891 0 : encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes));
1892 0 : WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value),
1893 : encoded);
1894 : return;
1895 : }
1896 : // 64 bit uint: 1 initial byte + 8 bytes payload.
1897 0 : encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes));
1898 : WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded);
1899 : }
1900 0 : void WriteTokenStart(MajorType type,
1901 : uint64_t value,
1902 : std::vector<uint8_t>* encoded) {
1903 0 : WriteTokenStartTmpl(type, value, encoded);
1904 0 : }
1905 0 : void WriteTokenStart(MajorType type, uint64_t value, std::string* encoded) {
1906 0 : WriteTokenStartTmpl(type, value, encoded);
1907 0 : }
1908 : } // namespace internals
1909 :
1910 : // =============================================================================
1911 : // Detecting CBOR content
1912 : // =============================================================================
1913 :
1914 0 : uint8_t InitialByteForEnvelope() {
1915 0 : return kInitialByteForEnvelope;
1916 : }
1917 0 : uint8_t InitialByteFor32BitLengthByteString() {
1918 0 : return kInitialByteFor32BitLengthByteString;
1919 : }
1920 0 : bool IsCBORMessage(span<uint8_t> msg) {
1921 0 : return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() &&
1922 0 : msg[1] == InitialByteFor32BitLengthByteString();
1923 : }
1924 :
1925 : // =============================================================================
1926 : // Encoding invidiual CBOR items
1927 : // =============================================================================
1928 :
1929 0 : uint8_t EncodeTrue() {
1930 0 : return kEncodedTrue;
1931 : }
1932 0 : uint8_t EncodeFalse() {
1933 0 : return kEncodedFalse;
1934 : }
1935 0 : uint8_t EncodeNull() {
1936 0 : return kEncodedNull;
1937 : }
1938 :
1939 0 : uint8_t EncodeIndefiniteLengthArrayStart() {
1940 0 : return kInitialByteIndefiniteLengthArray;
1941 : }
1942 :
1943 0 : uint8_t EncodeIndefiniteLengthMapStart() {
1944 0 : return kInitialByteIndefiniteLengthMap;
1945 : }
1946 :
1947 0 : uint8_t EncodeStop() {
1948 0 : return kStopByte;
1949 : }
1950 :
1951 : template <typename C>
1952 0 : void EncodeInt32Tmpl(int32_t value, C* out) {
1953 0 : if (value >= 0) {
1954 0 : internals::WriteTokenStart(MajorType::UNSIGNED, value, out);
1955 : } else {
1956 0 : uint64_t representation = static_cast<uint64_t>(-(value + 1));
1957 : internals::WriteTokenStart(MajorType::NEGATIVE, representation, out);
1958 : }
1959 0 : }
1960 0 : void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
1961 0 : EncodeInt32Tmpl(value, out);
1962 0 : }
1963 0 : void EncodeInt32(int32_t value, std::string* out) {
1964 0 : EncodeInt32Tmpl(value, out);
1965 0 : }
1966 :
1967 : template <typename C>
1968 0 : void EncodeString16Tmpl(span<uint16_t> in, C* out) {
1969 : uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
1970 : internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
1971 : // When emitting UTF16 characters, we always write the least significant byte
1972 : // first; this is because it's the native representation for X86.
1973 : // TODO(johannes): Implement a more efficient thing here later, e.g.
1974 : // casting *iff* the machine has this byte order.
1975 : // The wire format for UTF16 chars will probably remain the same
1976 : // (least significant byte first) since this way we can have
1977 : // golden files, unittests, etc. that port easily and universally.
1978 : // See also:
1979 : // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1980 0 : for (const uint16_t two_bytes : in) {
1981 0 : out->push_back(two_bytes);
1982 0 : out->push_back(two_bytes >> 8);
1983 : }
1984 0 : }
1985 0 : void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
1986 0 : EncodeString16Tmpl(in, out);
1987 0 : }
1988 0 : void EncodeString16(span<uint16_t> in, std::string* out) {
1989 0 : EncodeString16Tmpl(in, out);
1990 0 : }
1991 :
1992 : template <typename C>
1993 0 : void EncodeString8Tmpl(span<uint8_t> in, C* out) {
1994 0 : internals::WriteTokenStart(MajorType::STRING,
1995 : static_cast<uint64_t>(in.size_bytes()), out);
1996 0 : out->insert(out->end(), in.begin(), in.end());
1997 0 : }
1998 0 : void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
1999 0 : EncodeString8Tmpl(in, out);
2000 0 : }
2001 0 : void EncodeString8(span<uint8_t> in, std::string* out) {
2002 0 : EncodeString8Tmpl(in, out);
2003 0 : }
2004 :
2005 : template <typename C>
2006 0 : void EncodeFromLatin1Tmpl(span<uint8_t> latin1, C* out) {
2007 0 : for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) {
2008 0 : if (latin1[ii] <= 127)
2009 0 : continue;
2010 : // If there's at least one non-ASCII char, convert to UTF8.
2011 : std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii);
2012 0 : for (; ii < latin1.size(); ++ii) {
2013 0 : if (latin1[ii] <= 127) {
2014 0 : utf8.push_back(latin1[ii]);
2015 : } else {
2016 : // 0xC0 means it's a UTF8 sequence with 2 bytes.
2017 0 : utf8.push_back((latin1[ii] >> 6) | 0xc0);
2018 0 : utf8.push_back((latin1[ii] | 0x80) & 0xbf);
2019 : }
2020 : }
2021 : EncodeString8(SpanFromVector(utf8), out);
2022 : return;
2023 : }
2024 : EncodeString8(latin1, out);
2025 : }
2026 0 : void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) {
2027 0 : EncodeFromLatin1Tmpl(latin1, out);
2028 0 : }
2029 0 : void EncodeFromLatin1(span<uint8_t> latin1, std::string* out) {
2030 0 : EncodeFromLatin1Tmpl(latin1, out);
2031 0 : }
2032 :
2033 : template <typename C>
2034 0 : void EncodeFromUTF16Tmpl(span<uint16_t> utf16, C* out) {
2035 : // If there's at least one non-ASCII char, encode as STRING16 (UTF16).
2036 0 : for (uint16_t ch : utf16) {
2037 0 : if (ch <= 127)
2038 : continue;
2039 : EncodeString16(utf16, out);
2040 : return;
2041 : }
2042 : // It's all US-ASCII, strip out every second byte and encode as UTF8.
2043 : internals::WriteTokenStart(MajorType::STRING,
2044 : static_cast<uint64_t>(utf16.size()), out);
2045 0 : out->insert(out->end(), utf16.begin(), utf16.end());
2046 : }
2047 0 : void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) {
2048 0 : EncodeFromUTF16Tmpl(utf16, out);
2049 0 : }
2050 0 : void EncodeFromUTF16(span<uint16_t> utf16, std::string* out) {
2051 0 : EncodeFromUTF16Tmpl(utf16, out);
2052 0 : }
2053 :
2054 : template <typename C>
2055 0 : void EncodeBinaryTmpl(span<uint8_t> in, C* out) {
2056 0 : out->push_back(kExpectedConversionToBase64Tag);
2057 0 : uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
2058 : internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
2059 0 : out->insert(out->end(), in.begin(), in.end());
2060 0 : }
2061 0 : void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
2062 0 : EncodeBinaryTmpl(in, out);
2063 0 : }
2064 0 : void EncodeBinary(span<uint8_t> in, std::string* out) {
2065 0 : EncodeBinaryTmpl(in, out);
2066 0 : }
2067 :
2068 : // A double is encoded with a specific initial byte
2069 : // (kInitialByteForDouble) plus the 64 bits of payload for its value.
2070 : constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
2071 :
2072 : // An envelope is encoded with a specific initial byte
2073 : // (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
2074 : // bit wide length, plus a 32 bit length for that string.
2075 : constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
2076 :
2077 : template <typename C>
2078 0 : void EncodeDoubleTmpl(double value, C* out) {
2079 : // The additional_info=27 indicates 64 bits for the double follow.
2080 : // See RFC 7049 Section 2.3, Table 1.
2081 0 : out->push_back(kInitialByteForDouble);
2082 : union {
2083 : double from_double;
2084 : uint64_t to_uint64;
2085 : } reinterpret;
2086 : reinterpret.from_double = value;
2087 0 : WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
2088 0 : }
2089 0 : void EncodeDouble(double value, std::vector<uint8_t>* out) {
2090 0 : EncodeDoubleTmpl(value, out);
2091 0 : }
2092 0 : void EncodeDouble(double value, std::string* out) {
2093 0 : EncodeDoubleTmpl(value, out);
2094 0 : }
2095 :
2096 : // =============================================================================
2097 : // cbor::EnvelopeEncoder - for wrapping submessages
2098 : // =============================================================================
2099 :
2100 : template <typename C>
2101 0 : void EncodeStartTmpl(C* out, std::size_t& byte_size_pos) {
2102 : assert(byte_size_pos == 0);
2103 0 : out->push_back(kInitialByteForEnvelope);
2104 0 : out->push_back(kInitialByteFor32BitLengthByteString);
2105 0 : byte_size_pos = out->size();
2106 0 : out->resize(out->size() + sizeof(uint32_t));
2107 0 : }
2108 :
2109 0 : void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
2110 0 : EncodeStartTmpl<std::vector<uint8_t>>(out, byte_size_pos_);
2111 0 : }
2112 :
2113 0 : void EnvelopeEncoder::EncodeStart(std::string* out) {
2114 0 : EncodeStartTmpl<std::string>(out, byte_size_pos_);
2115 0 : }
2116 :
2117 : template <typename C>
2118 : bool EncodeStopTmpl(C* out, std::size_t& byte_size_pos) {
2119 : assert(byte_size_pos != 0);
2120 : // The byte size is the size of the payload, that is, all the
2121 : // bytes that were written past the byte size position itself.
2122 0 : uint64_t byte_size = out->size() - (byte_size_pos + sizeof(uint32_t));
2123 : // We store exactly 4 bytes, so at most INT32MAX, with most significant
2124 : // byte first.
2125 0 : if (byte_size > std::numeric_limits<uint32_t>::max())
2126 : return false;
2127 0 : for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
2128 : --shift_bytes) {
2129 0 : (*out)[byte_size_pos++] = 0xff & (byte_size >> (shift_bytes * 8));
2130 : }
2131 : return true;
2132 : }
2133 :
2134 0 : bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
2135 0 : return EncodeStopTmpl(out, byte_size_pos_);
2136 : }
2137 :
2138 0 : bool EnvelopeEncoder::EncodeStop(std::string* out) {
2139 0 : return EncodeStopTmpl(out, byte_size_pos_);
2140 : }
2141 :
2142 : // =============================================================================
2143 : // cbor::NewCBOREncoder - for encoding from a streaming parser
2144 : // =============================================================================
2145 :
2146 : namespace {
2147 : template <typename C>
2148 0 : class CBOREncoder : public StreamingParserHandler {
2149 : public:
2150 0 : CBOREncoder(C* out, Status* status) : out_(out), status_(status) {
2151 0 : *status_ = Status();
2152 : }
2153 :
2154 0 : void HandleMapBegin() override {
2155 0 : envelopes_.emplace_back();
2156 0 : envelopes_.back().EncodeStart(out_);
2157 0 : out_->push_back(kInitialByteIndefiniteLengthMap);
2158 0 : }
2159 :
2160 0 : void HandleMapEnd() override {
2161 0 : out_->push_back(kStopByte);
2162 : assert(!envelopes_.empty());
2163 0 : envelopes_.back().EncodeStop(out_);
2164 : envelopes_.pop_back();
2165 0 : }
2166 :
2167 0 : void HandleArrayBegin() override {
2168 0 : envelopes_.emplace_back();
2169 0 : envelopes_.back().EncodeStart(out_);
2170 0 : out_->push_back(kInitialByteIndefiniteLengthArray);
2171 0 : }
2172 :
2173 0 : void HandleArrayEnd() override {
2174 0 : out_->push_back(kStopByte);
2175 : assert(!envelopes_.empty());
2176 0 : envelopes_.back().EncodeStop(out_);
2177 : envelopes_.pop_back();
2178 0 : }
2179 :
2180 0 : void HandleString8(span<uint8_t> chars) override {
2181 0 : EncodeString8(chars, out_);
2182 0 : }
2183 :
2184 0 : void HandleString16(span<uint16_t> chars) override {
2185 0 : EncodeFromUTF16(chars, out_);
2186 0 : }
2187 :
2188 0 : void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); }
2189 :
2190 0 : void HandleDouble(double value) override { EncodeDouble(value, out_); }
2191 :
2192 0 : void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
2193 :
2194 0 : void HandleBool(bool value) override {
2195 : // See RFC 7049 Section 2.3, Table 2.
2196 0 : out_->push_back(value ? kEncodedTrue : kEncodedFalse);
2197 0 : }
2198 :
2199 0 : void HandleNull() override {
2200 : // See RFC 7049 Section 2.3, Table 2.
2201 0 : out_->push_back(kEncodedNull);
2202 0 : }
2203 :
2204 0 : void HandleError(Status error) override {
2205 : assert(!error.ok());
2206 0 : *status_ = error;
2207 0 : out_->clear();
2208 0 : }
2209 :
2210 : private:
2211 : C* out_;
2212 : std::vector<EnvelopeEncoder> envelopes_;
2213 : Status* status_;
2214 : };
2215 : } // namespace
2216 :
2217 0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(
2218 : std::vector<uint8_t>* out,
2219 : Status* status) {
2220 : return std::unique_ptr<StreamingParserHandler>(
2221 0 : new CBOREncoder<std::vector<uint8_t>>(out, status));
2222 : }
2223 0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(std::string* out,
2224 : Status* status) {
2225 : return std::unique_ptr<StreamingParserHandler>(
2226 0 : new CBOREncoder<std::string>(out, status));
2227 : }
2228 :
2229 : // =============================================================================
2230 : // cbor::CBORTokenizer - for parsing individual CBOR items
2231 : // =============================================================================
2232 :
2233 0 : CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
2234 0 : ReadNextToken(/*enter_envelope=*/false);
2235 0 : }
2236 0 : CBORTokenizer::~CBORTokenizer() {}
2237 :
2238 0 : CBORTokenTag CBORTokenizer::TokenTag() const {
2239 0 : return token_tag_;
2240 : }
2241 :
2242 0 : void CBORTokenizer::Next() {
2243 0 : if (token_tag_ == CBORTokenTag::ERROR_VALUE ||
2244 : token_tag_ == CBORTokenTag::DONE)
2245 : return;
2246 0 : ReadNextToken(/*enter_envelope=*/false);
2247 : }
2248 :
2249 0 : void CBORTokenizer::EnterEnvelope() {
2250 : assert(token_tag_ == CBORTokenTag::ENVELOPE);
2251 0 : ReadNextToken(/*enter_envelope=*/true);
2252 0 : }
2253 :
2254 0 : Status CBORTokenizer::Status() const {
2255 0 : return status_;
2256 : }
2257 :
2258 0 : int32_t CBORTokenizer::GetInt32() const {
2259 : assert(token_tag_ == CBORTokenTag::INT32);
2260 : // The range checks happen in ::ReadNextToken().
2261 : return static_cast<uint32_t>(
2262 0 : token_start_type_ == MajorType::UNSIGNED
2263 0 : ? token_start_internal_value_
2264 0 : : -static_cast<int64_t>(token_start_internal_value_) - 1);
2265 : }
2266 :
2267 0 : double CBORTokenizer::GetDouble() const {
2268 : assert(token_tag_ == CBORTokenTag::DOUBLE);
2269 : union {
2270 : uint64_t from_uint64;
2271 : double to_double;
2272 : } reinterpret;
2273 0 : reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
2274 0 : bytes_.subspan(status_.pos + 1));
2275 0 : return reinterpret.to_double;
2276 : }
2277 :
2278 0 : span<uint8_t> CBORTokenizer::GetString8() const {
2279 : assert(token_tag_ == CBORTokenTag::STRING8);
2280 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2281 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2282 : }
2283 :
2284 0 : span<uint8_t> CBORTokenizer::GetString16WireRep() const {
2285 : assert(token_tag_ == CBORTokenTag::STRING16);
2286 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2287 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2288 : }
2289 :
2290 0 : span<uint8_t> CBORTokenizer::GetBinary() const {
2291 : assert(token_tag_ == CBORTokenTag::BINARY);
2292 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2293 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2294 : }
2295 :
2296 0 : span<uint8_t> CBORTokenizer::GetEnvelopeContents() const {
2297 : assert(token_tag_ == CBORTokenTag::ENVELOPE);
2298 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2299 0 : return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length);
2300 : }
2301 :
2302 0 : void CBORTokenizer::ReadNextToken(bool enter_envelope) {
2303 0 : if (enter_envelope) {
2304 0 : status_.pos += kEncodedEnvelopeHeaderSize;
2305 : } else {
2306 : status_.pos =
2307 0 : status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
2308 : }
2309 0 : status_.error = Error::OK;
2310 0 : if (status_.pos >= bytes_.size()) {
2311 0 : token_tag_ = CBORTokenTag::DONE;
2312 0 : return;
2313 : }
2314 0 : switch (bytes_[status_.pos]) {
2315 : case kStopByte:
2316 : SetToken(CBORTokenTag::STOP, 1);
2317 : return;
2318 : case kInitialByteIndefiniteLengthMap:
2319 : SetToken(CBORTokenTag::MAP_START, 1);
2320 : return;
2321 : case kInitialByteIndefiniteLengthArray:
2322 : SetToken(CBORTokenTag::ARRAY_START, 1);
2323 : return;
2324 : case kEncodedTrue:
2325 : SetToken(CBORTokenTag::TRUE_VALUE, 1);
2326 : return;
2327 : case kEncodedFalse:
2328 : SetToken(CBORTokenTag::FALSE_VALUE, 1);
2329 : return;
2330 : case kEncodedNull:
2331 : SetToken(CBORTokenTag::NULL_VALUE, 1);
2332 : return;
2333 : case kExpectedConversionToBase64Tag: { // BINARY
2334 0 : int8_t bytes_read = internals::ReadTokenStart(
2335 : bytes_.subspan(status_.pos + 1), &token_start_type_,
2336 0 : &token_start_internal_value_);
2337 0 : int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
2338 0 : if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
2339 0 : status_.pos + token_byte_length > bytes_.size()) {
2340 : SetError(Error::CBOR_INVALID_BINARY);
2341 : return;
2342 : }
2343 : SetToken(CBORTokenTag::BINARY,
2344 : static_cast<std::ptrdiff_t>(token_byte_length));
2345 : return;
2346 : }
2347 : case kInitialByteForDouble: { // DOUBLE
2348 0 : if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
2349 : SetError(Error::CBOR_INVALID_DOUBLE);
2350 : return;
2351 : }
2352 : SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
2353 : return;
2354 : }
2355 : case kInitialByteForEnvelope: { // ENVELOPE
2356 0 : if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
2357 : SetError(Error::CBOR_INVALID_ENVELOPE);
2358 : return;
2359 : }
2360 : // The envelope must be a byte string with 32 bit length.
2361 0 : if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
2362 : SetError(Error::CBOR_INVALID_ENVELOPE);
2363 : return;
2364 : }
2365 : // Read the length of the byte string.
2366 0 : token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
2367 0 : bytes_.subspan(status_.pos + 2));
2368 : // Make sure the payload is contained within the message.
2369 0 : if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
2370 0 : status_.pos >
2371 : static_cast<std::size_t>(bytes_.size())) {
2372 : SetError(Error::CBOR_INVALID_ENVELOPE);
2373 : return;
2374 : }
2375 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2376 0 : SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length);
2377 : return;
2378 : }
2379 : default: {
2380 : span<uint8_t> remainder =
2381 0 : bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
2382 : assert(!remainder.empty());
2383 0 : int8_t token_start_length = internals::ReadTokenStart(
2384 0 : remainder, &token_start_type_, &token_start_internal_value_);
2385 : bool success = token_start_length != -1;
2386 0 : switch (token_start_type_) {
2387 : case MajorType::UNSIGNED: // INT32.
2388 0 : if (!success || std::numeric_limits<int32_t>::max() <
2389 0 : token_start_internal_value_) {
2390 : SetError(Error::CBOR_INVALID_INT32);
2391 0 : return;
2392 : }
2393 0 : SetToken(CBORTokenTag::INT32, token_start_length);
2394 : return;
2395 : case MajorType::NEGATIVE: // INT32.
2396 0 : if (!success ||
2397 : std::numeric_limits<int32_t>::min() >
2398 0 : -static_cast<int64_t>(token_start_internal_value_) - 1) {
2399 : SetError(Error::CBOR_INVALID_INT32);
2400 : return;
2401 : }
2402 0 : SetToken(CBORTokenTag::INT32, token_start_length);
2403 : return;
2404 : case MajorType::STRING: { // STRING8.
2405 0 : if (!success || remainder.size() < static_cast<int64_t>(
2406 0 : token_start_internal_value_)) {
2407 : SetError(Error::CBOR_INVALID_STRING8);
2408 : return;
2409 : }
2410 : auto length =
2411 0 : static_cast<std::ptrdiff_t>(token_start_internal_value_);
2412 0 : SetToken(CBORTokenTag::STRING8, token_start_length + length);
2413 : return;
2414 : }
2415 : case MajorType::BYTE_STRING: { // STRING16.
2416 0 : if (!success ||
2417 0 : remainder.size() <
2418 0 : static_cast<int64_t>(token_start_internal_value_) ||
2419 : // Must be divisible by 2 since UTF16 is 2 bytes per character.
2420 0 : token_start_internal_value_ & 1) {
2421 : SetError(Error::CBOR_INVALID_STRING16);
2422 : return;
2423 : }
2424 : auto length =
2425 0 : static_cast<std::ptrdiff_t>(token_start_internal_value_);
2426 0 : SetToken(CBORTokenTag::STRING16, token_start_length + length);
2427 : return;
2428 : }
2429 : case MajorType::ARRAY:
2430 : case MajorType::MAP:
2431 : case MajorType::TAG:
2432 : case MajorType::SIMPLE_VALUE:
2433 : SetError(Error::CBOR_UNSUPPORTED_VALUE);
2434 : return;
2435 : }
2436 : }
2437 : }
2438 : }
2439 :
2440 0 : void CBORTokenizer::SetToken(CBORTokenTag token_tag,
2441 : std::ptrdiff_t token_byte_length) {
2442 0 : token_tag_ = token_tag;
2443 0 : token_byte_length_ = token_byte_length;
2444 0 : }
2445 :
2446 0 : void CBORTokenizer::SetError(Error error) {
2447 0 : token_tag_ = CBORTokenTag::ERROR_VALUE;
2448 0 : status_.error = error;
2449 0 : }
2450 :
2451 : // =============================================================================
2452 : // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
2453 : // =============================================================================
2454 :
2455 : namespace {
2456 : // When parsing CBOR, we limit recursion depth for objects and arrays
2457 : // to this constant.
2458 : static constexpr int kStackLimit = 300;
2459 :
2460 : // Below are three parsing routines for CBOR, which cover enough
2461 : // to roundtrip JSON messages.
2462 : bool ParseMap(int32_t stack_depth,
2463 : CBORTokenizer* tokenizer,
2464 : StreamingParserHandler* out);
2465 : bool ParseArray(int32_t stack_depth,
2466 : CBORTokenizer* tokenizer,
2467 : StreamingParserHandler* out);
2468 : bool ParseValue(int32_t stack_depth,
2469 : CBORTokenizer* tokenizer,
2470 : StreamingParserHandler* out);
2471 :
2472 0 : void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
2473 : std::vector<uint16_t> value;
2474 : span<uint8_t> rep = tokenizer->GetString16WireRep();
2475 0 : for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
2476 0 : value.push_back((rep[ii + 1] << 8) | rep[ii]);
2477 0 : out->HandleString16(span<uint16_t>(value.data(), value.size()));
2478 : tokenizer->Next();
2479 0 : }
2480 :
2481 0 : bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
2482 : assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
2483 0 : out->HandleString8(tokenizer->GetString8());
2484 : tokenizer->Next();
2485 0 : return true;
2486 : }
2487 :
2488 0 : bool ParseValue(int32_t stack_depth,
2489 : CBORTokenizer* tokenizer,
2490 : StreamingParserHandler* out) {
2491 0 : if (stack_depth > kStackLimit) {
2492 0 : out->HandleError(
2493 0 : Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
2494 0 : return false;
2495 : }
2496 : // Skip past the envelope to get to what's inside.
2497 0 : if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
2498 : tokenizer->EnterEnvelope();
2499 0 : switch (tokenizer->TokenTag()) {
2500 : case CBORTokenTag::ERROR_VALUE:
2501 0 : out->HandleError(tokenizer->Status());
2502 0 : return false;
2503 : case CBORTokenTag::DONE:
2504 0 : out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
2505 0 : tokenizer->Status().pos});
2506 0 : return false;
2507 : case CBORTokenTag::TRUE_VALUE:
2508 0 : out->HandleBool(true);
2509 : tokenizer->Next();
2510 : return true;
2511 : case CBORTokenTag::FALSE_VALUE:
2512 0 : out->HandleBool(false);
2513 : tokenizer->Next();
2514 : return true;
2515 : case CBORTokenTag::NULL_VALUE:
2516 0 : out->HandleNull();
2517 : tokenizer->Next();
2518 : return true;
2519 : case CBORTokenTag::INT32:
2520 0 : out->HandleInt32(tokenizer->GetInt32());
2521 : tokenizer->Next();
2522 : return true;
2523 : case CBORTokenTag::DOUBLE:
2524 0 : out->HandleDouble(tokenizer->GetDouble());
2525 : tokenizer->Next();
2526 : return true;
2527 : case CBORTokenTag::STRING8:
2528 0 : return ParseUTF8String(tokenizer, out);
2529 : case CBORTokenTag::STRING16:
2530 0 : ParseUTF16String(tokenizer, out);
2531 0 : return true;
2532 : case CBORTokenTag::BINARY: {
2533 0 : out->HandleBinary(tokenizer->GetBinary());
2534 : tokenizer->Next();
2535 : return true;
2536 : }
2537 : case CBORTokenTag::MAP_START:
2538 0 : return ParseMap(stack_depth + 1, tokenizer, out);
2539 : case CBORTokenTag::ARRAY_START:
2540 0 : return ParseArray(stack_depth + 1, tokenizer, out);
2541 : default:
2542 0 : out->HandleError(
2543 0 : Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
2544 0 : return false;
2545 : }
2546 : }
2547 :
2548 : // |bytes| must start with the indefinite length array byte, so basically,
2549 : // ParseArray may only be called after an indefinite length array has been
2550 : // detected.
2551 0 : bool ParseArray(int32_t stack_depth,
2552 : CBORTokenizer* tokenizer,
2553 : StreamingParserHandler* out) {
2554 : assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
2555 : tokenizer->Next();
2556 0 : out->HandleArrayBegin();
2557 0 : while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2558 0 : if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2559 0 : out->HandleError(
2560 0 : Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
2561 0 : return false;
2562 : }
2563 0 : if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2564 0 : out->HandleError(tokenizer->Status());
2565 0 : return false;
2566 : }
2567 : // Parse value.
2568 0 : if (!ParseValue(stack_depth, tokenizer, out))
2569 : return false;
2570 : }
2571 0 : out->HandleArrayEnd();
2572 : tokenizer->Next();
2573 : return true;
2574 : }
2575 :
2576 : // |bytes| must start with the indefinite length array byte, so basically,
2577 : // ParseArray may only be called after an indefinite length array has been
2578 : // detected.
2579 0 : bool ParseMap(int32_t stack_depth,
2580 : CBORTokenizer* tokenizer,
2581 : StreamingParserHandler* out) {
2582 : assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
2583 0 : out->HandleMapBegin();
2584 : tokenizer->Next();
2585 0 : while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2586 0 : if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2587 0 : out->HandleError(
2588 0 : Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
2589 0 : return false;
2590 : }
2591 0 : if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2592 0 : out->HandleError(tokenizer->Status());
2593 0 : return false;
2594 : }
2595 : // Parse key.
2596 0 : if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
2597 0 : if (!ParseUTF8String(tokenizer, out))
2598 : return false;
2599 0 : } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
2600 0 : ParseUTF16String(tokenizer, out);
2601 : } else {
2602 0 : out->HandleError(
2603 0 : Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
2604 0 : return false;
2605 : }
2606 : // Parse value.
2607 0 : if (!ParseValue(stack_depth, tokenizer, out))
2608 : return false;
2609 : }
2610 0 : out->HandleMapEnd();
2611 : tokenizer->Next();
2612 : return true;
2613 : }
2614 : } // namespace
2615 :
2616 0 : void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) {
2617 0 : if (bytes.empty()) {
2618 0 : out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
2619 0 : return;
2620 : }
2621 0 : if (bytes[0] != kInitialByteForEnvelope) {
2622 0 : out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
2623 0 : return;
2624 : }
2625 : CBORTokenizer tokenizer(bytes);
2626 0 : if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2627 0 : out->HandleError(tokenizer.Status());
2628 0 : return;
2629 : }
2630 : // We checked for the envelope start byte above, so the tokenizer
2631 : // must agree here, since it's not an error.
2632 : assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
2633 : tokenizer.EnterEnvelope();
2634 0 : if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
2635 0 : out->HandleError(
2636 0 : Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
2637 0 : return;
2638 : }
2639 0 : if (!ParseMap(/*stack_depth=*/1, &tokenizer, out))
2640 : return;
2641 0 : if (tokenizer.TokenTag() == CBORTokenTag::DONE)
2642 : return;
2643 0 : if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2644 0 : out->HandleError(tokenizer.Status());
2645 0 : return;
2646 : }
2647 0 : out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
2648 : }
2649 :
2650 : // =============================================================================
2651 : // cbor::AppendString8EntryToMap - for limited in-place editing of messages
2652 : // =============================================================================
2653 :
2654 : template <typename C>
2655 0 : Status AppendString8EntryToCBORMapTmpl(span<uint8_t> string8_key,
2656 : span<uint8_t> string8_value,
2657 : C* cbor) {
2658 : span<uint8_t> bytes(reinterpret_cast<const uint8_t*>(cbor->data()),
2659 0 : cbor->size());
2660 : CBORTokenizer tokenizer(bytes);
2661 0 : if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE)
2662 : return tokenizer.Status();
2663 0 : if (tokenizer.TokenTag() != CBORTokenTag::ENVELOPE)
2664 0 : return Status(Error::CBOR_INVALID_ENVELOPE, 0);
2665 : std::ptrdiff_t envelope_size = tokenizer.GetEnvelopeContents().size();
2666 : std::size_t old_size = cbor->size();
2667 0 : if (old_size != std::size_t(envelope_size) + kEncodedEnvelopeHeaderSize)
2668 0 : return Status(Error::CBOR_INVALID_ENVELOPE, 0);
2669 0 : if (envelope_size == 0 ||
2670 : (tokenizer.GetEnvelopeContents()[0] != EncodeIndefiniteLengthMapStart()))
2671 0 : return Status(Error::CBOR_MAP_START_EXPECTED, kEncodedEnvelopeHeaderSize);
2672 0 : if (cbor->back() != EncodeStop())
2673 0 : return Status(Error::CBOR_MAP_STOP_EXPECTED, cbor->size() - 1);
2674 : cbor->pop_back();
2675 : EncodeString8(string8_key, cbor);
2676 : EncodeString8(string8_value, cbor);
2677 0 : cbor->push_back(EncodeStop());
2678 0 : std::size_t new_envelope_size = envelope_size + (cbor->size() - old_size);
2679 0 : if (new_envelope_size > std::numeric_limits<uint32_t>::max())
2680 0 : return Status(Error::CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED, 0);
2681 0 : std::size_t size_pos = cbor->size() - new_envelope_size - sizeof(uint32_t);
2682 : uint8_t* out = reinterpret_cast<uint8_t*>(&cbor->at(size_pos));
2683 0 : *(out++) = (new_envelope_size >> 24) & 0xff;
2684 0 : *(out++) = (new_envelope_size >> 16) & 0xff;
2685 0 : *(out++) = (new_envelope_size >> 8) & 0xff;
2686 0 : *(out) = new_envelope_size & 0xff;
2687 0 : return Status();
2688 : }
2689 0 : Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
2690 : span<uint8_t> string8_value,
2691 : std::vector<uint8_t>* cbor) {
2692 0 : return AppendString8EntryToCBORMapTmpl(string8_key, string8_value, cbor);
2693 : }
2694 0 : Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
2695 : span<uint8_t> string8_value,
2696 : std::string* cbor) {
2697 0 : return AppendString8EntryToCBORMapTmpl(string8_key, string8_value, cbor);
2698 : }
2699 : } // namespace cbor
2700 :
2701 : namespace json {
2702 :
2703 : // =============================================================================
2704 : // json::NewJSONEncoder - for encoding streaming parser events as JSON
2705 : // =============================================================================
2706 :
2707 : namespace {
2708 : // Prints |value| to |out| with 4 hex digits, most significant chunk first.
2709 : template <typename C>
2710 0 : void PrintHex(uint16_t value, C* out) {
2711 0 : for (int ii = 3; ii >= 0; --ii) {
2712 0 : int four_bits = 0xf & (value >> (4 * ii));
2713 0 : out->push_back(four_bits + ((four_bits <= 9) ? '0' : ('a' - 10)));
2714 : }
2715 0 : }
2716 :
2717 : // In the writer below, we maintain a stack of State instances.
2718 : // It is just enough to emit the appropriate delimiters and brackets
2719 : // in JSON.
2720 : enum class Container {
2721 : // Used for the top-level, initial state.
2722 : NONE,
2723 : // Inside a JSON object.
2724 : MAP,
2725 : // Inside a JSON array.
2726 : ARRAY
2727 : };
2728 : class State {
2729 : public:
2730 0 : explicit State(Container container) : container_(container) {}
2731 : void StartElement(std::vector<uint8_t>* out) {
2732 : // FIXME!!!
2733 : }
2734 0 : void StartElement(std::string* out) {
2735 : assert(container_ != Container::NONE || size_ == 0);
2736 0 : if (size_ != 0) {
2737 0 : char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':';
2738 : out->append(1, delim);
2739 : }
2740 0 : ++size_;
2741 0 : }
2742 : Container container() const { return container_; }
2743 :
2744 : private:
2745 : Container container_ = Container::NONE;
2746 : int size_ = 0;
2747 : };
2748 :
2749 : constexpr char kBase64Table[] =
2750 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2751 : "abcdefghijklmnopqrstuvwxyz0123456789+/";
2752 :
2753 : template <typename C>
2754 0 : void Base64Encode(const span<uint8_t>& in, C* out) {
2755 : // The following three cases are based on the tables in the example
2756 : // section in https://en.wikipedia.org/wiki/Base64. We process three
2757 : // input bytes at a time, emitting 4 output bytes at a time.
2758 : std::ptrdiff_t ii = 0;
2759 :
2760 : // While possible, process three input bytes.
2761 0 : for (; ii + 3 <= in.size(); ii += 3) {
2762 0 : uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2];
2763 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2764 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2765 0 : out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
2766 0 : out->push_back(kBase64Table[twentyfour_bits & 0x3f]);
2767 : }
2768 0 : if (ii + 2 <= in.size()) { // Process two input bytes.
2769 0 : uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8);
2770 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2771 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2772 0 : out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
2773 0 : out->push_back('='); // Emit padding.
2774 0 : return;
2775 : }
2776 0 : if (ii + 1 <= in.size()) { // Process a single input byte.
2777 0 : uint32_t twentyfour_bits = (in[ii] << 16);
2778 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2779 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2780 0 : out->push_back('='); // Emit padding.
2781 0 : out->push_back('='); // Emit padding.
2782 : }
2783 : }
2784 :
2785 : // Implements a handler for JSON parser events to emit a JSON string.
2786 : template <typename C>
2787 0 : class JSONEncoder : public StreamingParserHandler {
2788 : public:
2789 0 : JSONEncoder(const Platform* platform, C* out, Status* status)
2790 0 : : platform_(platform), out_(out), status_(status) {
2791 0 : *status_ = Status();
2792 0 : state_.emplace(Container::NONE);
2793 0 : }
2794 :
2795 0 : void HandleMapBegin() override {
2796 0 : if (!status_->ok())
2797 : return;
2798 : assert(!state_.empty());
2799 0 : state_.top().StartElement(out_);
2800 0 : state_.emplace(Container::MAP);
2801 : Emit('{');
2802 : }
2803 :
2804 0 : void HandleMapEnd() override {
2805 0 : if (!status_->ok())
2806 : return;
2807 : assert(state_.size() >= 2 && state_.top().container() == Container::MAP);
2808 : state_.pop();
2809 : Emit('}');
2810 : }
2811 :
2812 0 : void HandleArrayBegin() override {
2813 0 : if (!status_->ok())
2814 : return;
2815 0 : state_.top().StartElement(out_);
2816 0 : state_.emplace(Container::ARRAY);
2817 : Emit('[');
2818 : }
2819 :
2820 0 : void HandleArrayEnd() override {
2821 0 : if (!status_->ok())
2822 : return;
2823 : assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY);
2824 : state_.pop();
2825 : Emit(']');
2826 : }
2827 :
2828 0 : void HandleString16(span<uint16_t> chars) override {
2829 0 : if (!status_->ok())
2830 : return;
2831 0 : state_.top().StartElement(out_);
2832 : Emit('"');
2833 0 : for (const uint16_t ch : chars) {
2834 0 : if (ch == '"') {
2835 0 : Emit("\\\"");
2836 0 : } else if (ch == '\\') {
2837 0 : Emit("\\\\");
2838 0 : } else if (ch == '\b') {
2839 0 : Emit("\\b");
2840 0 : } else if (ch == '\f') {
2841 0 : Emit("\\f");
2842 0 : } else if (ch == '\n') {
2843 0 : Emit("\\n");
2844 0 : } else if (ch == '\r') {
2845 0 : Emit("\\r");
2846 0 : } else if (ch == '\t') {
2847 0 : Emit("\\t");
2848 0 : } else if (ch >= 32 && ch <= 126) {
2849 0 : Emit(ch);
2850 : } else {
2851 0 : Emit("\\u");
2852 0 : PrintHex(ch, out_);
2853 : }
2854 : }
2855 : Emit('"');
2856 : }
2857 :
2858 0 : void HandleString8(span<uint8_t> chars) override {
2859 0 : if (!status_->ok())
2860 : return;
2861 0 : state_.top().StartElement(out_);
2862 : Emit('"');
2863 0 : for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) {
2864 0 : uint8_t c = chars[ii];
2865 0 : if (c == '"') {
2866 0 : Emit("\\\"");
2867 0 : } else if (c == '\\') {
2868 0 : Emit("\\\\");
2869 0 : } else if (c == '\b') {
2870 0 : Emit("\\b");
2871 0 : } else if (c == '\f') {
2872 0 : Emit("\\f");
2873 0 : } else if (c == '\n') {
2874 0 : Emit("\\n");
2875 0 : } else if (c == '\r') {
2876 0 : Emit("\\r");
2877 0 : } else if (c == '\t') {
2878 0 : Emit("\\t");
2879 0 : } else if (c >= 32 && c <= 126) {
2880 0 : Emit(c);
2881 0 : } else if (c < 32) {
2882 0 : Emit("\\u");
2883 0 : PrintHex(static_cast<uint16_t>(c), out_);
2884 : } else {
2885 : // Inspect the leading byte to figure out how long the utf8
2886 : // byte sequence is; while doing this initialize |codepoint|
2887 : // with the first few bits.
2888 : // See table in: https://en.wikipedia.org/wiki/UTF-8
2889 : // byte one is 110x xxxx -> 2 byte utf8 sequence
2890 : // byte one is 1110 xxxx -> 3 byte utf8 sequence
2891 : // byte one is 1111 0xxx -> 4 byte utf8 sequence
2892 : uint32_t codepoint;
2893 : int num_bytes_left;
2894 0 : if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence
2895 : num_bytes_left = 1;
2896 0 : codepoint = c & 0x1f;
2897 0 : } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence
2898 : num_bytes_left = 2;
2899 0 : codepoint = c & 0x0f;
2900 0 : } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence
2901 0 : codepoint = c & 0x07;
2902 : num_bytes_left = 3;
2903 : } else {
2904 : continue; // invalid leading byte
2905 : }
2906 :
2907 : // If we have enough bytes in our input, decode the remaining ones
2908 : // belonging to this Unicode character into |codepoint|.
2909 0 : if (ii + num_bytes_left > chars.size())
2910 : continue;
2911 0 : while (num_bytes_left > 0) {
2912 0 : c = chars[++ii];
2913 0 : --num_bytes_left;
2914 : // Check the next byte is a continuation byte, that is 10xx xxxx.
2915 0 : if ((c & 0xc0) != 0x80)
2916 : continue;
2917 0 : codepoint = (codepoint << 6) | (c & 0x3f);
2918 : }
2919 :
2920 : // Disallow overlong encodings for ascii characters, as these
2921 : // would include " and other characters significant to JSON
2922 : // string termination / control.
2923 0 : if (codepoint < 0x7f)
2924 : continue;
2925 : // Invalid in UTF8, and can't be represented in UTF16 anyway.
2926 0 : if (codepoint > 0x10ffff)
2927 : continue;
2928 :
2929 : // So, now we transcode to UTF16,
2930 : // using the math described at https://en.wikipedia.org/wiki/UTF-16,
2931 : // for either one or two 16 bit characters.
2932 0 : if (codepoint < 0xffff) {
2933 0 : Emit("\\u");
2934 0 : PrintHex(static_cast<uint16_t>(codepoint), out_);
2935 0 : continue;
2936 : }
2937 0 : codepoint -= 0x10000;
2938 : // high surrogate
2939 0 : Emit("\\u");
2940 0 : PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_);
2941 : // low surrogate
2942 0 : Emit("\\u");
2943 0 : PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_);
2944 : }
2945 : }
2946 : Emit('"');
2947 : }
2948 :
2949 0 : void HandleBinary(span<uint8_t> bytes) override {
2950 0 : if (!status_->ok())
2951 : return;
2952 0 : state_.top().StartElement(out_);
2953 : Emit('"');
2954 0 : Base64Encode(bytes, out_);
2955 : Emit('"');
2956 : }
2957 :
2958 0 : void HandleDouble(double value) override {
2959 0 : if (!status_->ok())
2960 0 : return;
2961 0 : state_.top().StartElement(out_);
2962 : // JSON cannot represent NaN or Infinity. So, for compatibility,
2963 : // we behave like the JSON object in web browsers: emit 'null'.
2964 0 : if (!std::isfinite(value)) {
2965 0 : Emit("null");
2966 0 : return;
2967 : }
2968 0 : std::unique_ptr<char[]> str_value = platform_->DToStr(value);
2969 :
2970 : // DToStr may fail to emit a 0 before the decimal dot. E.g. this is
2971 : // the case in base::NumberToString in Chromium (which is based on
2972 : // dmg_fp). So, much like
2973 : // https://cs.chromium.org/chromium/src/base/json/json_writer.cc
2974 : // we probe for this and emit the leading 0 anyway if necessary.
2975 : const char* chars = str_value.get();
2976 0 : if (chars[0] == '.') {
2977 : Emit('0');
2978 0 : } else if (chars[0] == '-' && chars[1] == '.') {
2979 0 : Emit("-0");
2980 0 : ++chars;
2981 : }
2982 0 : Emit(chars);
2983 : }
2984 :
2985 0 : void HandleInt32(int32_t value) override {
2986 0 : if (!status_->ok())
2987 : return;
2988 0 : state_.top().StartElement(out_);
2989 0 : Emit(std::to_string(value));
2990 : }
2991 :
2992 0 : void HandleBool(bool value) override {
2993 0 : if (!status_->ok())
2994 : return;
2995 0 : state_.top().StartElement(out_);
2996 0 : Emit(value ? "true" : "false");
2997 : }
2998 :
2999 0 : void HandleNull() override {
3000 0 : if (!status_->ok())
3001 : return;
3002 0 : state_.top().StartElement(out_);
3003 0 : Emit("null");
3004 : }
3005 :
3006 0 : void HandleError(Status error) override {
3007 : assert(!error.ok());
3008 0 : *status_ = error;
3009 0 : out_->clear();
3010 0 : }
3011 :
3012 : private:
3013 0 : void Emit(char c) { out_->push_back(c); }
3014 0 : void Emit(const char* str) {
3015 0 : out_->insert(out_->end(), str, str + strlen(str));
3016 0 : }
3017 0 : void Emit(const std::string& str) {
3018 0 : out_->insert(out_->end(), str.begin(), str.end());
3019 0 : }
3020 :
3021 : const Platform* platform_;
3022 : C* out_;
3023 : Status* status_;
3024 : std::stack<State> state_;
3025 : };
3026 : } // namespace
3027 :
3028 0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(
3029 : const Platform* platform,
3030 : std::vector<uint8_t>* out,
3031 : Status* status) {
3032 : return std::unique_ptr<StreamingParserHandler>(
3033 0 : new JSONEncoder<std::vector<uint8_t>>(platform, out, status));
3034 : }
3035 0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform,
3036 : std::string* out,
3037 : Status* status) {
3038 : return std::unique_ptr<StreamingParserHandler>(
3039 0 : new JSONEncoder<std::string>(platform, out, status));
3040 : }
3041 :
3042 : // =============================================================================
3043 : // json::ParseJSON - for receiving streaming parser events for JSON.
3044 : // =============================================================================
3045 :
3046 : namespace {
3047 : const int kStackLimit = 300;
3048 :
3049 : enum Token {
3050 : ObjectBegin,
3051 : ObjectEnd,
3052 : ArrayBegin,
3053 : ArrayEnd,
3054 : StringLiteral,
3055 : Number,
3056 : BoolTrue,
3057 : BoolFalse,
3058 : NullToken,
3059 : ListSeparator,
3060 : ObjectPairSeparator,
3061 : InvalidToken,
3062 : NoInput
3063 : };
3064 :
3065 : const char* const kNullString = "null";
3066 : const char* const kTrueString = "true";
3067 : const char* const kFalseString = "false";
3068 :
3069 : template <typename Char>
3070 : class JsonParser {
3071 : public:
3072 : JsonParser(const Platform* platform, StreamingParserHandler* handler)
3073 0 : : platform_(platform), handler_(handler) {}
3074 :
3075 0 : void Parse(const Char* start, std::size_t length) {
3076 0 : start_pos_ = start;
3077 0 : const Char* end = start + length;
3078 : const Char* tokenEnd;
3079 0 : ParseValue(start, end, &tokenEnd, 0);
3080 0 : if (tokenEnd != end) {
3081 : HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd);
3082 : }
3083 0 : }
3084 :
3085 : private:
3086 0 : bool CharsToDouble(const uint16_t* chars,
3087 : std::size_t length,
3088 : double* result) {
3089 : std::string buffer;
3090 0 : buffer.reserve(length + 1);
3091 0 : for (std::size_t ii = 0; ii < length; ++ii) {
3092 0 : bool is_ascii = !(chars[ii] & ~0x7F);
3093 0 : if (!is_ascii)
3094 : return false;
3095 0 : buffer.push_back(static_cast<char>(chars[ii]));
3096 : }
3097 0 : return platform_->StrToD(buffer.c_str(), result);
3098 : }
3099 :
3100 0 : bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) {
3101 : std::string buffer(reinterpret_cast<const char*>(chars), length);
3102 0 : return platform_->StrToD(buffer.c_str(), result);
3103 : }
3104 :
3105 : static bool ParseConstToken(const Char* start,
3106 : const Char* end,
3107 : const Char** token_end,
3108 : const char* token) {
3109 : // |token| is \0 terminated, it's one of the constants at top of the file.
3110 0 : while (start < end && *token != '\0' && *start++ == *token++) {
3111 : }
3112 0 : if (*token != '\0')
3113 : return false;
3114 0 : *token_end = start;
3115 : return true;
3116 : }
3117 :
3118 : static bool ReadInt(const Char* start,
3119 : const Char* end,
3120 : const Char** token_end,
3121 : bool allow_leading_zeros) {
3122 0 : if (start == end)
3123 : return false;
3124 0 : bool has_leading_zero = '0' == *start;
3125 : int length = 0;
3126 0 : while (start < end && '0' <= *start && *start <= '9') {
3127 0 : ++start;
3128 0 : ++length;
3129 : }
3130 0 : if (!length)
3131 : return false;
3132 0 : if (!allow_leading_zeros && length > 1 && has_leading_zero)
3133 : return false;
3134 : *token_end = start;
3135 : return true;
3136 : }
3137 :
3138 0 : static bool ParseNumberToken(const Char* start,
3139 : const Char* end,
3140 : const Char** token_end) {
3141 : // We just grab the number here. We validate the size in DecodeNumber.
3142 : // According to RFC4627, a valid number is: [minus] int [frac] [exp]
3143 0 : if (start == end)
3144 : return false;
3145 0 : Char c = *start;
3146 0 : if ('-' == c)
3147 0 : ++start;
3148 :
3149 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false))
3150 : return false;
3151 0 : if (start == end) {
3152 0 : *token_end = start;
3153 0 : return true;
3154 : }
3155 :
3156 : // Optional fraction part
3157 0 : c = *start;
3158 0 : if ('.' == c) {
3159 0 : ++start;
3160 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
3161 : return false;
3162 0 : if (start == end) {
3163 0 : *token_end = start;
3164 0 : return true;
3165 : }
3166 0 : c = *start;
3167 : }
3168 :
3169 : // Optional exponent part
3170 0 : if ('e' == c || 'E' == c) {
3171 0 : ++start;
3172 0 : if (start == end)
3173 : return false;
3174 0 : c = *start;
3175 0 : if ('-' == c || '+' == c) {
3176 0 : ++start;
3177 0 : if (start == end)
3178 : return false;
3179 : }
3180 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
3181 : return false;
3182 : }
3183 :
3184 0 : *token_end = start;
3185 0 : return true;
3186 : }
3187 :
3188 : static bool ReadHexDigits(const Char* start,
3189 : const Char* end,
3190 : const Char** token_end,
3191 : int digits) {
3192 0 : if (end - start < digits)
3193 : return false;
3194 0 : for (int i = 0; i < digits; ++i) {
3195 0 : Char c = *start++;
3196 0 : if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
3197 : ('A' <= c && c <= 'F')))
3198 : return false;
3199 : }
3200 : *token_end = start;
3201 : return true;
3202 : }
3203 :
3204 0 : static bool ParseStringToken(const Char* start,
3205 : const Char* end,
3206 : const Char** token_end) {
3207 0 : while (start < end) {
3208 0 : Char c = *start++;
3209 0 : if ('\\' == c) {
3210 0 : if (start == end)
3211 : return false;
3212 0 : c = *start++;
3213 : // Make sure the escaped char is valid.
3214 0 : switch (c) {
3215 : case 'x':
3216 0 : if (!ReadHexDigits(start, end, &start, 2))
3217 : return false;
3218 : break;
3219 : case 'u':
3220 0 : if (!ReadHexDigits(start, end, &start, 4))
3221 : return false;
3222 : break;
3223 : case '\\':
3224 : case '/':
3225 : case 'b':
3226 : case 'f':
3227 : case 'n':
3228 : case 'r':
3229 : case 't':
3230 : case 'v':
3231 : case '"':
3232 : break;
3233 : default:
3234 : return false;
3235 : }
3236 0 : } else if ('"' == c) {
3237 0 : *token_end = start;
3238 0 : return true;
3239 : }
3240 : }
3241 : return false;
3242 : }
3243 :
3244 0 : static bool SkipComment(const Char* start,
3245 : const Char* end,
3246 : const Char** comment_end) {
3247 0 : if (start == end)
3248 : return false;
3249 :
3250 0 : if (*start != '/' || start + 1 >= end)
3251 : return false;
3252 : ++start;
3253 :
3254 0 : if (*start == '/') {
3255 : // Single line comment, read to newline.
3256 0 : for (++start; start < end; ++start) {
3257 0 : if (*start == '\n' || *start == '\r') {
3258 0 : *comment_end = start + 1;
3259 0 : return true;
3260 : }
3261 : }
3262 0 : *comment_end = end;
3263 : // Comment reaches end-of-input, which is fine.
3264 0 : return true;
3265 : }
3266 :
3267 0 : if (*start == '*') {
3268 : Char previous = '\0';
3269 : // Block comment, read until end marker.
3270 0 : for (++start; start < end; previous = *start++) {
3271 0 : if (previous == '*' && *start == '/') {
3272 0 : *comment_end = start + 1;
3273 0 : return true;
3274 : }
3275 : }
3276 : // Block comment must close before end-of-input.
3277 : return false;
3278 : }
3279 :
3280 : return false;
3281 : }
3282 :
3283 : static bool IsSpaceOrNewLine(Char c) {
3284 : // \v = vertial tab; \f = form feed page break.
3285 : return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' ||
3286 0 : c == '\t';
3287 : }
3288 :
3289 0 : static void SkipWhitespaceAndComments(const Char* start,
3290 : const Char* end,
3291 : const Char** whitespace_end) {
3292 0 : while (start < end) {
3293 0 : if (IsSpaceOrNewLine(*start)) {
3294 0 : ++start;
3295 0 : } else if (*start == '/') {
3296 : const Char* comment_end;
3297 0 : if (!SkipComment(start, end, &comment_end))
3298 : break;
3299 0 : start = comment_end;
3300 : } else {
3301 : break;
3302 : }
3303 : }
3304 0 : *whitespace_end = start;
3305 0 : }
3306 :
3307 0 : static Token ParseToken(const Char* start,
3308 : const Char* end,
3309 : const Char** tokenStart,
3310 : const Char** token_end) {
3311 0 : SkipWhitespaceAndComments(start, end, tokenStart);
3312 0 : start = *tokenStart;
3313 :
3314 0 : if (start == end)
3315 : return NoInput;
3316 :
3317 0 : switch (*start) {
3318 : case 'n':
3319 0 : if (ParseConstToken(start, end, token_end, kNullString))
3320 : return NullToken;
3321 : break;
3322 : case 't':
3323 0 : if (ParseConstToken(start, end, token_end, kTrueString))
3324 : return BoolTrue;
3325 : break;
3326 : case 'f':
3327 0 : if (ParseConstToken(start, end, token_end, kFalseString))
3328 : return BoolFalse;
3329 : break;
3330 : case '[':
3331 0 : *token_end = start + 1;
3332 0 : return ArrayBegin;
3333 : case ']':
3334 0 : *token_end = start + 1;
3335 0 : return ArrayEnd;
3336 : case ',':
3337 0 : *token_end = start + 1;
3338 0 : return ListSeparator;
3339 : case '{':
3340 0 : *token_end = start + 1;
3341 0 : return ObjectBegin;
3342 : case '}':
3343 0 : *token_end = start + 1;
3344 0 : return ObjectEnd;
3345 : case ':':
3346 0 : *token_end = start + 1;
3347 0 : return ObjectPairSeparator;
3348 : case '0':
3349 : case '1':
3350 : case '2':
3351 : case '3':
3352 : case '4':
3353 : case '5':
3354 : case '6':
3355 : case '7':
3356 : case '8':
3357 : case '9':
3358 : case '-':
3359 0 : if (ParseNumberToken(start, end, token_end))
3360 : return Number;
3361 : break;
3362 : case '"':
3363 0 : if (ParseStringToken(start + 1, end, token_end))
3364 : return StringLiteral;
3365 : break;
3366 : }
3367 : return InvalidToken;
3368 : }
3369 :
3370 : static int HexToInt(Char c) {
3371 0 : if ('0' <= c && c <= '9')
3372 0 : return c - '0';
3373 0 : if ('A' <= c && c <= 'F')
3374 0 : return c - 'A' + 10;
3375 0 : if ('a' <= c && c <= 'f')
3376 0 : return c - 'a' + 10;
3377 : assert(false); // Unreachable.
3378 : return 0;
3379 : }
3380 :
3381 0 : static bool DecodeString(const Char* start,
3382 : const Char* end,
3383 : std::vector<uint16_t>* output) {
3384 0 : if (start == end)
3385 : return true;
3386 0 : if (start > end)
3387 : return false;
3388 0 : output->reserve(end - start);
3389 0 : while (start < end) {
3390 0 : uint16_t c = *start++;
3391 : // If the |Char| we're dealing with is really a byte, then
3392 : // we have utf8 here, and we need to check for multibyte characters
3393 : // and transcode them to utf16 (either one or two utf16 chars).
3394 0 : if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) {
3395 : // Inspect the leading byte to figure out how long the utf8
3396 : // byte sequence is; while doing this initialize |codepoint|
3397 : // with the first few bits.
3398 : // See table in: https://en.wikipedia.org/wiki/UTF-8
3399 : // byte one is 110x xxxx -> 2 byte utf8 sequence
3400 : // byte one is 1110 xxxx -> 3 byte utf8 sequence
3401 : // byte one is 1111 0xxx -> 4 byte utf8 sequence
3402 : uint32_t codepoint;
3403 : int num_bytes_left;
3404 0 : if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence
3405 : num_bytes_left = 1;
3406 0 : codepoint = c & 0x1f;
3407 0 : } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence
3408 : num_bytes_left = 2;
3409 0 : codepoint = c & 0x0f;
3410 0 : } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence
3411 0 : codepoint = c & 0x07;
3412 : num_bytes_left = 3;
3413 : } else {
3414 0 : return false; // invalid leading byte
3415 : }
3416 :
3417 : // If we have enough bytes in our inpput, decode the remaining ones
3418 : // belonging to this Unicode character into |codepoint|.
3419 0 : if (start + num_bytes_left > end)
3420 : return false;
3421 0 : while (num_bytes_left > 0) {
3422 0 : c = *start++;
3423 0 : --num_bytes_left;
3424 : // Check the next byte is a continuation byte, that is 10xx xxxx.
3425 0 : if ((c & 0xc0) != 0x80)
3426 : return false;
3427 0 : codepoint = (codepoint << 6) | (c & 0x3f);
3428 : }
3429 :
3430 : // Disallow overlong encodings for ascii characters, as these
3431 : // would include " and other characters significant to JSON
3432 : // string termination / control.
3433 0 : if (codepoint < 0x7f)
3434 : return false;
3435 : // Invalid in UTF8, and can't be represented in UTF16 anyway.
3436 0 : if (codepoint > 0x10ffff)
3437 : return false;
3438 :
3439 : // So, now we transcode to UTF16,
3440 : // using the math described at https://en.wikipedia.org/wiki/UTF-16,
3441 : // for either one or two 16 bit characters.
3442 0 : if (codepoint < 0xffff) {
3443 0 : output->push_back(codepoint);
3444 0 : continue;
3445 : }
3446 0 : codepoint -= 0x10000;
3447 0 : output->push_back((codepoint >> 10) + 0xd800); // high surrogate
3448 0 : output->push_back((codepoint & 0x3ff) + 0xdc00); // low surrogate
3449 0 : continue;
3450 : }
3451 0 : if ('\\' != c) {
3452 0 : output->push_back(c);
3453 0 : continue;
3454 : }
3455 0 : if (start == end)
3456 : return false;
3457 0 : c = *start++;
3458 :
3459 0 : if (c == 'x') {
3460 : // \x is not supported.
3461 : return false;
3462 : }
3463 :
3464 0 : switch (c) {
3465 : case '"':
3466 : case '/':
3467 : case '\\':
3468 : break;
3469 : case 'b':
3470 0 : c = '\b';
3471 0 : break;
3472 : case 'f':
3473 0 : c = '\f';
3474 0 : break;
3475 : case 'n':
3476 0 : c = '\n';
3477 0 : break;
3478 : case 'r':
3479 0 : c = '\r';
3480 0 : break;
3481 : case 't':
3482 0 : c = '\t';
3483 0 : break;
3484 : case 'v':
3485 0 : c = '\v';
3486 0 : break;
3487 : case 'u':
3488 0 : c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) +
3489 0 : (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3));
3490 0 : start += 4;
3491 0 : break;
3492 : default:
3493 : return false;
3494 : }
3495 0 : output->push_back(c);
3496 : }
3497 : return true;
3498 : }
3499 :
3500 0 : void ParseValue(const Char* start,
3501 : const Char* end,
3502 : const Char** value_token_end,
3503 : int depth) {
3504 0 : if (depth > kStackLimit) {
3505 : HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start);
3506 0 : return;
3507 : }
3508 : const Char* token_start;
3509 : const Char* token_end;
3510 0 : Token token = ParseToken(start, end, &token_start, &token_end);
3511 0 : switch (token) {
3512 : case NoInput:
3513 0 : HandleError(Error::JSON_PARSER_NO_INPUT, token_start);
3514 : return;
3515 : case InvalidToken:
3516 0 : HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start);
3517 : return;
3518 : case NullToken:
3519 0 : handler_->HandleNull();
3520 0 : break;
3521 : case BoolTrue:
3522 0 : handler_->HandleBool(true);
3523 0 : break;
3524 : case BoolFalse:
3525 0 : handler_->HandleBool(false);
3526 0 : break;
3527 : case Number: {
3528 : double value;
3529 0 : if (!CharsToDouble(token_start, token_end - token_start, &value)) {
3530 0 : HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start);
3531 0 : return;
3532 : }
3533 0 : if (value >= std::numeric_limits<int32_t>::min() &&
3534 : value <= std::numeric_limits<int32_t>::max() &&
3535 : static_cast<int32_t>(value) == value)
3536 0 : handler_->HandleInt32(static_cast<int32_t>(value));
3537 : else
3538 0 : handler_->HandleDouble(value);
3539 0 : break;
3540 : }
3541 : case StringLiteral: {
3542 : std::vector<uint16_t> value;
3543 0 : bool ok = DecodeString(token_start + 1, token_end - 1, &value);
3544 0 : if (!ok) {
3545 0 : HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
3546 : return;
3547 : }
3548 0 : handler_->HandleString16(span<uint16_t>(value.data(), value.size()));
3549 : break;
3550 : }
3551 : case ArrayBegin: {
3552 0 : handler_->HandleArrayBegin();
3553 0 : start = token_end;
3554 0 : token = ParseToken(start, end, &token_start, &token_end);
3555 0 : while (token != ArrayEnd) {
3556 0 : ParseValue(start, end, &token_end, depth + 1);
3557 0 : if (error_)
3558 : return;
3559 :
3560 : // After a list value, we expect a comma or the end of the list.
3561 0 : start = token_end;
3562 0 : token = ParseToken(start, end, &token_start, &token_end);
3563 0 : if (token == ListSeparator) {
3564 0 : start = token_end;
3565 0 : token = ParseToken(start, end, &token_start, &token_end);
3566 0 : if (token == ArrayEnd) {
3567 0 : HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start);
3568 : return;
3569 : }
3570 0 : } else if (token != ArrayEnd) {
3571 : // Unexpected value after list value. Bail out.
3572 0 : HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED,
3573 : token_start);
3574 : return;
3575 : }
3576 : }
3577 0 : handler_->HandleArrayEnd();
3578 0 : break;
3579 : }
3580 : case ObjectBegin: {
3581 0 : handler_->HandleMapBegin();
3582 0 : start = token_end;
3583 0 : token = ParseToken(start, end, &token_start, &token_end);
3584 0 : while (token != ObjectEnd) {
3585 0 : if (token != StringLiteral) {
3586 0 : HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED,
3587 : token_start);
3588 0 : return;
3589 : }
3590 : std::vector<uint16_t> key;
3591 0 : if (!DecodeString(token_start + 1, token_end - 1, &key)) {
3592 0 : HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
3593 : return;
3594 : }
3595 0 : handler_->HandleString16(span<uint16_t>(key.data(), key.size()));
3596 0 : start = token_end;
3597 :
3598 0 : token = ParseToken(start, end, &token_start, &token_end);
3599 0 : if (token != ObjectPairSeparator) {
3600 0 : HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start);
3601 : return;
3602 : }
3603 0 : start = token_end;
3604 :
3605 0 : ParseValue(start, end, &token_end, depth + 1);
3606 0 : if (error_)
3607 : return;
3608 0 : start = token_end;
3609 :
3610 : // After a key/value pair, we expect a comma or the end of the
3611 : // object.
3612 0 : token = ParseToken(start, end, &token_start, &token_end);
3613 0 : if (token == ListSeparator) {
3614 0 : start = token_end;
3615 0 : token = ParseToken(start, end, &token_start, &token_end);
3616 0 : if (token == ObjectEnd) {
3617 0 : HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start);
3618 : return;
3619 : }
3620 0 : } else if (token != ObjectEnd) {
3621 : // Unexpected value after last object value. Bail out.
3622 0 : HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED,
3623 : token_start);
3624 : return;
3625 : }
3626 : }
3627 0 : handler_->HandleMapEnd();
3628 0 : break;
3629 : }
3630 :
3631 : default:
3632 : // We got a token that's not a value.
3633 0 : HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start);
3634 : return;
3635 : }
3636 :
3637 0 : SkipWhitespaceAndComments(token_end, end, value_token_end);
3638 : }
3639 :
3640 : void HandleError(Error error, const Char* pos) {
3641 : assert(error != Error::OK);
3642 0 : if (!error_) {
3643 0 : handler_->HandleError(Status{error, pos - start_pos_});
3644 0 : error_ = true;
3645 : }
3646 : }
3647 :
3648 : const Char* start_pos_ = nullptr;
3649 : bool error_ = false;
3650 : const Platform* platform_;
3651 : StreamingParserHandler* handler_;
3652 : };
3653 : } // namespace
3654 :
3655 0 : void ParseJSON(const Platform& platform,
3656 : span<uint8_t> chars,
3657 : StreamingParserHandler* handler) {
3658 : JsonParser<uint8_t> parser(&platform, handler);
3659 0 : parser.Parse(chars.data(), chars.size());
3660 0 : }
3661 :
3662 0 : void ParseJSON(const Platform& platform,
3663 : span<uint16_t> chars,
3664 : StreamingParserHandler* handler) {
3665 : JsonParser<uint16_t> parser(&platform, handler);
3666 0 : parser.Parse(chars.data(), chars.size());
3667 0 : }
3668 :
3669 : // =============================================================================
3670 : // json::ConvertCBORToJSON, json::ConvertJSONToCBOR - for transcoding
3671 : // =============================================================================
3672 : template <typename C>
3673 0 : Status ConvertCBORToJSONTmpl(const Platform& platform,
3674 : span<uint8_t> cbor,
3675 : C* json) {
3676 0 : Status status;
3677 : std::unique_ptr<StreamingParserHandler> json_writer =
3678 : NewJSONEncoder(&platform, json, &status);
3679 0 : cbor::ParseCBOR(cbor, json_writer.get());
3680 0 : return status;
3681 : }
3682 :
3683 0 : Status ConvertCBORToJSON(const Platform& platform,
3684 : span<uint8_t> cbor,
3685 : std::vector<uint8_t>* json) {
3686 0 : return ConvertCBORToJSONTmpl(platform, cbor, json);
3687 : }
3688 0 : Status ConvertCBORToJSON(const Platform& platform,
3689 : span<uint8_t> cbor,
3690 : std::string* json) {
3691 0 : return ConvertCBORToJSONTmpl(platform, cbor, json);
3692 : }
3693 :
3694 : template <typename C>
3695 0 : Status ConvertJSONToCBORTmpl(const Platform& platform,
3696 : span<uint8_t> json,
3697 : C* cbor) {
3698 0 : Status status;
3699 : std::unique_ptr<StreamingParserHandler> encoder =
3700 0 : cbor::NewCBOREncoder(cbor, &status);
3701 : ParseJSON(platform, json, encoder.get());
3702 0 : return status;
3703 : }
3704 0 : Status ConvertJSONToCBOR(const Platform& platform,
3705 : span<uint8_t> json,
3706 : std::string* cbor) {
3707 0 : return ConvertJSONToCBORTmpl(platform, json, cbor);
3708 : }
3709 0 : Status ConvertJSONToCBOR(const Platform& platform,
3710 : span<uint8_t> json,
3711 : std::vector<uint8_t>* cbor) {
3712 0 : return ConvertJSONToCBORTmpl(platform, json, cbor);
3713 : }
3714 : } // namespace json
3715 :
3716 : } // namespace v8_inspector
3717 : } // namespace protocol
3718 :
|