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 309822 : ErrorSupport::ErrorSupport() { }
27 154911 : ErrorSupport::~ErrorSupport() { }
28 :
29 204842 : void ErrorSupport::setName(const char* name)
30 : {
31 409684 : setName(String(name));
32 204842 : }
33 :
34 205187 : void ErrorSupport::setName(const String& name)
35 : {
36 : DCHECK(m_path.size());
37 205187 : m_path[m_path.size() - 1] = name;
38 205187 : }
39 :
40 143964 : void ErrorSupport::push()
41 : {
42 431892 : m_path.push_back(String());
43 143964 : }
44 :
45 143964 : void ErrorSupport::pop()
46 : {
47 : m_path.pop_back();
48 143964 : }
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 143964 : bool ErrorSupport::hasErrors()
69 : {
70 143964 : 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 1243572448 : inline bool escapeChar(uint16_t c, StringBuilder* dst)
106 : {
107 1243572448 : switch (c) {
108 0 : case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
109 0 : case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
110 43624854 : 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 36896804 : 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 49487140 : void escapeStringForJSONInternal(const Char* str, unsigned len,
135 : StringBuilder* dst)
136 : {
137 2536632036 : for (unsigned i = 0; i < len; ++i) {
138 1243572448 : Char c = str[i];
139 1243572448 : if (escapeChar(c, dst))
140 : continue;
141 1203238772 : if (c < 32 || c > 126) {
142 2250142 : appendUnsignedAsHex(c, dst);
143 : } else {
144 : StringUtil::builderAppend(*dst, c);
145 : }
146 : }
147 49487140 : }
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 658929 : String Value::toJSONString() const
352 : {
353 658929 : StringBuilder result;
354 : StringUtil::builderReserve(result, 512);
355 658929 : writeJSON(&result);
356 658929 : return StringUtil::builderToString(result);
357 : }
358 :
359 658533 : String Value::serializeToJSON() {
360 658533 : 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 82351 : bool FundamentalValue::asBoolean(bool* output) const
370 : {
371 82351 : if (type() != TypeBoolean)
372 : return false;
373 82351 : *output = m_boolValue;
374 82351 : 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 348251 : bool FundamentalValue::asInteger(int* output) const
391 : {
392 348251 : if (type() != TypeInteger)
393 : return false;
394 348251 : *output = m_integerValue;
395 348251 : return true;
396 : }
397 :
398 12230668 : void FundamentalValue::writeJSON(StringBuilder* output) const
399 : {
400 : DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
401 12230668 : if (type() == TypeBoolean) {
402 10229265 : if (m_boolValue)
403 : StringUtil::builderAppend(*output, trueValueString, 4);
404 : else
405 : StringUtil::builderAppend(*output, falseValueString, 5);
406 2001403 : } else if (type() == TypeDouble) {
407 303932 : if (!std::isfinite(m_doubleValue)) {
408 : StringUtil::builderAppend(*output, nullValueString, 4);
409 : return;
410 : }
411 151961 : StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
412 1849437 : } else if (type() == TypeInteger) {
413 3698874 : 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 0 : return;
422 : case TypeInteger:
423 0 : cbor::EncodeInt32(m_integerValue, bytes);
424 0 : 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 167741 : std::unique_ptr<Value> FundamentalValue::clone() const
434 : {
435 167741 : switch (type()) {
436 144907 : 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 268785 : bool StringValue::asString(String* output) const
446 : {
447 : *output = m_stringValue;
448 268785 : return true;
449 : }
450 :
451 16478558 : void StringValue::writeJSON(StringBuilder* output) const
452 : {
453 : DCHECK(type() == TypeString);
454 16478558 : StringUtil::builderAppendQuotedString(*output, m_stringValue);
455 16478558 : }
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 0 : 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 0 : 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 65960 : std::unique_ptr<Value> StringValue::clone() const
491 : {
492 131920 : 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 328812 : void SerializedValue::writeJSON(StringBuilder* output) const
518 : {
519 : DCHECK(type() == TypeSerialized);
520 328812 : StringUtil::builderAppend(*output, m_serializedJSON);
521 328812 : }
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 15902112 : DictionaryValue::~DictionaryValue()
535 : {
536 7951056 : }
537 :
538 26778 : void DictionaryValue::setBoolean(const String& name, bool value)
539 : {
540 26778 : setValue(name, FundamentalValue::create(value));
541 26778 : }
542 :
543 168023 : void DictionaryValue::setInteger(const String& name, int value)
544 : {
545 168023 : setValue(name, FundamentalValue::create(value));
546 168023 : }
547 :
548 5 : void DictionaryValue::setDouble(const String& name, double value)
549 : {
550 5 : setValue(name, FundamentalValue::create(value));
551 5 : }
552 :
553 176504 : void DictionaryValue::setString(const String& name, const String& value)
554 : {
555 176504 : setValue(name, StringValue::create(value));
556 176504 : }
557 :
558 32535669 : void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
559 : {
560 34061857 : set(name, value);
561 32535669 : }
562 :
563 23426 : void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
564 : {
565 24335 : set(name, value);
566 23426 : }
567 :
568 10 : void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
569 : {
570 10 : set(name, value);
571 10 : }
572 :
573 8341 : bool DictionaryValue::getBoolean(const String& name, bool* output) const
574 : {
575 : protocol::Value* value = get(name);
576 8341 : if (!value)
577 : return false;
578 214 : return value->asBoolean(output);
579 : }
580 :
581 187822 : bool DictionaryValue::getInteger(const String& name, int* output) const
582 : {
583 : Value* value = get(name);
584 187822 : if (!value)
585 : return false;
586 187758 : 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 173326 : DictionaryValue* DictionaryValue::getObject(const String& name) const
606 : {
607 173326 : 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 654676 : protocol::Value* DictionaryValue::get(const String& name) const
616 : {
617 : Dictionary::const_iterator it = m_data.find(name);
618 1333965 : if (it == m_data.end())
619 : return nullptr;
620 310069 : 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 4475 : bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
630 : {
631 4475 : bool result = defaultValue;
632 4475 : getBoolean(name, &result);
633 4475 : 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 18237 : void DictionaryValue::remove(const String& name)
651 : {
652 : m_data.erase(name);
653 18237 : m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
654 18237 : }
655 :
656 7550561 : void DictionaryValue::writeJSON(StringBuilder* output) const
657 : {
658 : StringUtil::builderAppend(*output, '{');
659 73950255 : for (size_t i = 0; i < m_order.size(); ++i) {
660 : Dictionary::const_iterator it = m_data.find(m_order[i]);
661 33199847 : CHECK(it != m_data.end());
662 33199847 : if (i)
663 : StringUtil::builderAppend(*output, ',');
664 33199847 : StringUtil::builderAppendQuotedString(*output, it->first);
665 : StringUtil::builderAppend(*output, ':');
666 33199847 : it->second->writeJSON(output);
667 : }
668 : StringUtil::builderAppend(*output, '}');
669 7550561 : }
670 :
671 0 : void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
672 0 : cbor::EnvelopeEncoder encoder;
673 0 : 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 7139745 : DictionaryValue::DictionaryValue()
699 7951056 : : Value(TypeObject)
700 : {
701 7139745 : }
702 :
703 810784 : ListValue::~ListValue()
704 : {
705 405392 : }
706 :
707 404457 : void ListValue::writeJSON(StringBuilder* output) const
708 : {
709 : StringUtil::builderAppend(*output, '[');
710 : bool first = true;
711 3541404 : for (const std::unique_ptr<protocol::Value>& value : m_data) {
712 3136947 : if (!first)
713 : StringUtil::builderAppend(*output, ',');
714 3136947 : value->writeJSON(output);
715 : first = false;
716 : }
717 : StringUtil::builderAppend(*output, ']');
718 404457 : }
719 :
720 0 : void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
721 0 : cbor::EnvelopeEncoder encoder;
722 0 : 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 404452 : ListValue::ListValue()
740 405392 : : Value(TypeArray)
741 : {
742 404452 : }
743 :
744 3136932 : void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
745 : {
746 : DCHECK(value);
747 3138507 : m_data.push_back(std::move(value));
748 3136932 : }
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 49487140 : void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
762 : {
763 49487140 : escapeStringForJSONInternal<uint16_t>(str, len, dst);
764 49487140 : }
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 10527586 : DispatchResponse DispatchResponse::OK()
824 : {
825 : DispatchResponse result;
826 10527586 : result.m_status = kSuccess;
827 10527586 : result.m_errorCode = kParseError;
828 10527586 : return result;
829 : }
830 :
831 : // static
832 1533 : DispatchResponse DispatchResponse::Error(const String& error)
833 : {
834 : DispatchResponse result;
835 1533 : result.m_status = kError;
836 1533 : result.m_errorCode = kServerError;
837 : result.m_errorMessage = error;
838 1533 : 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 164742 : DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
874 :
875 319524 : DispatcherBase::WeakPtr::~WeakPtr()
876 : {
877 164742 : if (m_dispatcher)
878 329464 : m_dispatcher->m_weakPtrs.erase(this);
879 154782 : }
880 :
881 9960 : 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 29880 : , 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 9960 : void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
895 : {
896 19920 : if (!m_backendImpl || !m_backendImpl->get())
897 : return;
898 19910 : 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 23196 : DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
911 46392 : : m_frontendChannel(frontendChannel) { }
912 :
913 46392 : DispatcherBase::~DispatcherBase()
914 : {
915 : clearFrontend();
916 23196 : }
917 :
918 154777 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
919 : {
920 154777 : if (!m_frontendChannel)
921 : return;
922 154777 : if (response.status() == DispatchResponse::kError) {
923 : reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
924 : return;
925 : }
926 923586 : m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
927 : }
928 :
929 57097 : void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
930 : {
931 114194 : sendResponse(callId, response, DictionaryValue::create());
932 57097 : }
933 :
934 : namespace {
935 :
936 : class ProtocolError : public Serializable {
937 : public:
938 909 : static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
939 : {
940 909 : std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
941 909 : protocolError->m_callId = callId;
942 909 : protocolError->m_hasCallId = true;
943 968 : if (errors && errors->hasErrors())
944 118 : protocolError->m_data = errors->errors();
945 909 : 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 909 : String serializeToJSON() override
954 : {
955 2727 : return serialize()->serializeToJSON();
956 : }
957 :
958 0 : std::vector<uint8_t> serializeToBinary() override
959 : {
960 0 : return serialize()->serializeToBinary();
961 : }
962 :
963 2727 : ~ProtocolError() override {}
964 :
965 : private:
966 909 : ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
967 : : m_code(code)
968 1818 : , m_errorMessage(errorMessage)
969 : {
970 909 : }
971 :
972 909 : std::unique_ptr<DictionaryValue> serialize() {
973 909 : std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
974 2727 : error->setInteger("code", m_code);
975 2727 : error->setString("message", m_errorMessage);
976 909 : if (m_data.length())
977 177 : error->setString("data", m_data);
978 909 : std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
979 2727 : message->setObject("error", std::move(error));
980 909 : if (m_hasCallId)
981 2727 : message->setInteger("id", m_callId);
982 909 : 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 909 : static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
995 : {
996 909 : if (frontendChannel)
997 2727 : frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
998 909 : }
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 905 : reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
1009 59 : }
1010 :
1011 0 : void DispatcherBase::clearFrontend()
1012 : {
1013 23196 : m_frontendChannel = nullptr;
1014 23206 : for (auto& weak : m_weakPtrs)
1015 10 : weak->dispose();
1016 : m_weakPtrs.clear();
1017 0 : }
1018 :
1019 164742 : std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
1020 : {
1021 164742 : std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
1022 329484 : m_weakPtrs.insert(weak.get());
1023 164742 : return weak;
1024 : }
1025 :
1026 3866 : UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
1027 7732 : : m_frontendChannel(frontendChannel) { }
1028 :
1029 23196 : void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
1030 : {
1031 : m_dispatchers[name] = std::move(dispatcher);
1032 23196 : }
1033 :
1034 23196 : void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
1035 : {
1036 27062 : for (const auto& pair : redirects)
1037 3866 : m_redirects[pair.first] = pair.second;
1038 23196 : }
1039 :
1040 154845 : bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
1041 154845 : 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 154845 : if (!messageObject) {
1047 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
1048 0 : return false;
1049 : }
1050 :
1051 154845 : int callId = 0;
1052 309690 : protocol::Value* callIdValue = messageObject->get("id");
1053 154845 : bool success = callIdValue && callIdValue->asInteger(&callId);
1054 154845 : if (!success) {
1055 0 : reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
1056 0 : return false;
1057 : }
1058 154845 : if (outCallId)
1059 154845 : *outCallId = callId;
1060 :
1061 309690 : protocol::Value* methodValue = messageObject->get("method");
1062 : String method;
1063 154845 : success = methodValue && methodValue->asString(&method);
1064 154845 : if (!success) {
1065 0 : reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
1066 0 : return false;
1067 : }
1068 154845 : if (outMethod)
1069 : *outMethod = method;
1070 : return true;
1071 : }
1072 :
1073 154845 : protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
1074 154845 : size_t dotIndex = StringUtil::find(method, ".");
1075 154845 : if (dotIndex == StringUtil::kNotFound)
1076 : return nullptr;
1077 : String domain = StringUtil::substring(method, 0, dotIndex);
1078 : auto it = m_dispatchers.find(domain);
1079 154845 : if (it == m_dispatchers.end())
1080 : return nullptr;
1081 154845 : if (!it->second->canDispatch(method))
1082 : return nullptr;
1083 154841 : 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 154845 : 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 154845 : if (redirectIt != m_redirects.end())
1100 : method = redirectIt->second;
1101 154845 : protocol::DispatcherBase* dispatcher = findDispatcher(method);
1102 154845 : 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 464523 : dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
1108 : }
1109 :
1110 : UberDispatcher::~UberDispatcher() = default;
1111 :
1112 : // static
1113 153931 : std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
1114 : {
1115 615724 : return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
1116 : }
1117 :
1118 : // static
1119 174881 : std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
1120 : {
1121 349762 : return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
1122 : }
1123 :
1124 328812 : String InternalResponse::serializeToJSON()
1125 : {
1126 328812 : std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
1127 768020 : std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
1128 328812 : if (m_notification.length()) {
1129 524643 : result->setString("method", m_notification);
1130 874405 : result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
1131 : } else {
1132 461793 : result->setInteger("id", m_callId);
1133 769655 : result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
1134 : }
1135 657624 : 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 328812 : InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
1153 : : m_callId(callId)
1154 : , m_notification(notification)
1155 657624 : , m_params(params ? std::move(params) : nullptr)
1156 : {
1157 328812 : }
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 5147798 : return !(c & ~0x7F);
1198 : }
1199 :
1200 : bool isSpaceOrNewLine(uint16_t c)
1201 : {
1202 4352585 : return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
1203 : }
1204 :
1205 349696 : double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
1206 : {
1207 : std::vector<char> buffer;
1208 349696 : buffer.reserve(length + 1);
1209 1940122 : for (size_t i = 0; i < length; ++i) {
1210 1590426 : if (!isASCII(characters[i])) {
1211 0 : *ok = false;
1212 0 : return 0;
1213 : }
1214 1590426 : buffer.push_back(static_cast<char>(characters[i]));
1215 : }
1216 699392 : buffer.push_back('\0');
1217 349696 : 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 419167 : while (start < end && *token != '\0' && *start++ == *token++) { }
1230 82430 : if (*token != '\0')
1231 : return false;
1232 82425 : *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 349701 : if (start == end)
1240 : return false;
1241 349696 : bool haveLeadingZero = '0' == *start;
1242 : int length = 0;
1243 1144896 : while (start < end && '0' <= *start && *start <= '9') {
1244 795195 : ++start;
1245 795195 : ++length;
1246 : }
1247 349701 : if (!length)
1248 : return false;
1249 349696 : if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
1250 : return false;
1251 : *tokenEnd = start;
1252 : return true;
1253 : }
1254 :
1255 : template<typename Char>
1256 349696 : 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 349696 : if (start == end)
1261 : return false;
1262 349696 : Char c = *start;
1263 349696 : if ('-' == c)
1264 13 : ++start;
1265 :
1266 349696 : if (!readInt(start, end, &start, false))
1267 : return false;
1268 349696 : if (start == end) {
1269 5 : *tokenEnd = start;
1270 5 : return true;
1271 : }
1272 :
1273 : // Optional fraction part
1274 349691 : c = *start;
1275 349691 : 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 349691 : 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 349691 : *tokenEnd = start;
1302 349691 : 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 1087201 : bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1321 : {
1322 13424361 : while (start < end) {
1323 13424361 : Char c = *start++;
1324 13424361 : if ('\\' == c) {
1325 334233 : if (start == end)
1326 : return false;
1327 334233 : c = *start++;
1328 : // Make sure the escaped char is valid.
1329 334233 : 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 13090128 : } else if ('"' == c) {
1352 1087201 : *tokenEnd = start;
1353 1087201 : 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 4601444 : void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1400 : {
1401 4601444 : while (start < end) {
1402 8705170 : if (isSpaceOrNewLine(*start)) {
1403 0 : ++start;
1404 4352585 : } 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 4601444 : *whitespaceEnd = start;
1414 4601444 : }
1415 :
1416 : template<typename Char>
1417 3533963 : Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1418 : {
1419 3533963 : skipWhitespaceAndComments(start, end, tokenStart);
1420 3533963 : start = *tokenStart;
1421 :
1422 3533963 : if (start == end)
1423 : return InvalidToken;
1424 :
1425 3533963 : switch (*start) {
1426 : case 'n':
1427 5 : if (parseConstToken(start, end, tokenEnd, nullString))
1428 : return NullToken;
1429 : break;
1430 : case 't':
1431 75393 : if (parseConstToken(start, end, tokenEnd, trueString))
1432 : return BoolTrue;
1433 : break;
1434 : case 'f':
1435 7032 : 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 464047 : *tokenEnd = start + 1;
1446 464047 : return ListSeparator;
1447 : case '{':
1448 366111 : *tokenEnd = start + 1;
1449 366111 : return ObjectBegin;
1450 : case '}':
1451 365376 : *tokenEnd = start + 1;
1452 365376 : return ObjectEnd;
1453 : case ':':
1454 817762 : *tokenEnd = start + 1;
1455 817762 : 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 349696 : if (parseNumberToken(start, end, tokenEnd))
1468 : return Number;
1469 : break;
1470 : case '"':
1471 1087201 : 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 1086870 : bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1493 : {
1494 13422935 : while (start < end) {
1495 12336065 : uint16_t c = *start++;
1496 12336065 : if ('\\' != c) {
1497 : StringUtil::builderAppend(*output, c);
1498 : continue;
1499 : }
1500 334233 : if (start == end)
1501 : return false;
1502 334233 : c = *start++;
1503 :
1504 334233 : if (c == 'x') {
1505 : // \x is not supported.
1506 : return false;
1507 : }
1508 :
1509 334233 : 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 7143 : 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 1087076 : bool decodeString(const Char* start, const Char* end, String* output)
1549 : {
1550 1087076 : if (start == end) {
1551 412 : *output = "";
1552 206 : return true;
1553 : }
1554 1086870 : if (start > end)
1555 : return false;
1556 1086870 : StringBuilder buffer;
1557 1086870 : StringUtil::builderReserve(buffer, end - start);
1558 1086870 : if (!decodeString(start, end, &buffer))
1559 : return false;
1560 1086870 : *output = StringUtil::builderToString(buffer);
1561 1086870 : return true;
1562 : }
1563 :
1564 : template<typename Char>
1565 1067486 : std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1566 : {
1567 1067486 : if (depth > stackLimit)
1568 : return nullptr;
1569 :
1570 : std::unique_ptr<Value> result;
1571 : const Char* tokenStart;
1572 : const Char* tokenEnd;
1573 1067486 : Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1574 1067486 : 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 75393 : break;
1583 : case BoolFalse:
1584 : result = FundamentalValue::create(false);
1585 7027 : break;
1586 : case Number: {
1587 : bool ok;
1588 349696 : double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1589 349696 : if (!ok)
1590 0 : return nullptr;
1591 349696 : if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
1592 349691 : result = FundamentalValue::create(static_cast<int>(value));
1593 : else
1594 : result = FundamentalValue::create(value);
1595 349696 : break;
1596 : }
1597 : case StringLiteral: {
1598 : String value;
1599 269314 : bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1600 269314 : 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 365376 : std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1635 365376 : start = tokenEnd;
1636 365376 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1637 1183138 : while (token != ObjectEnd) {
1638 817762 : if (token != StringLiteral)
1639 0 : return nullptr;
1640 : String key;
1641 817762 : if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1642 : return nullptr;
1643 817762 : start = tokenEnd;
1644 :
1645 817762 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1646 817762 : if (token != ObjectPairSeparator)
1647 : return nullptr;
1648 817762 : start = tokenEnd;
1649 :
1650 817762 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
1651 817762 : if (!value)
1652 : return nullptr;
1653 817762 : object->setValue(key, std::move(value));
1654 817762 : start = tokenEnd;
1655 :
1656 : // After a key/value pair, we expect a comma or the end of the
1657 : // object.
1658 817762 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1659 817762 : if (token == ListSeparator) {
1660 463789 : start = tokenEnd;
1661 463789 : token = parseToken(start, end, &tokenStart, &tokenEnd);
1662 463789 : if (token == ObjectEnd)
1663 : return nullptr;
1664 353973 : } else if (token != ObjectEnd) {
1665 : // Unexpected value after last object value. Bail out.
1666 : return nullptr;
1667 : }
1668 : }
1669 365376 : 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 1067481 : skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1681 : return result;
1682 : }
1683 :
1684 : template<typename Char>
1685 248864 : std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1686 : {
1687 248864 : const Char* end = start + length;
1688 : const Char *tokenEnd;
1689 248864 : std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1690 248864 : if (!value || tokenEnd != end)
1691 : return nullptr;
1692 : return value;
1693 : }
1694 :
1695 : } // anonymous namespace
1696 :
1697 248864 : std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1698 : {
1699 248864 : 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 <cstring>
1720 : #include <limits>
1721 : #include <stack>
1722 :
1723 : namespace v8_inspector {
1724 : namespace protocol {
1725 :
1726 : // ===== encoding/encoding.cc =====
1727 :
1728 : namespace cbor {
1729 : namespace {
1730 : // Indicates the number of bits the "initial byte" needs to be shifted to the
1731 : // right after applying |kMajorTypeMask| to produce the major type in the
1732 : // lowermost bits.
1733 : static constexpr uint8_t kMajorTypeBitShift = 5u;
1734 : // Mask selecting the low-order 5 bits of the "initial byte", which is where
1735 : // the additional information is encoded.
1736 : static constexpr uint8_t kAdditionalInformationMask = 0x1f;
1737 : // Mask selecting the high-order 3 bits of the "initial byte", which indicates
1738 : // the major type of the encoded value.
1739 : static constexpr uint8_t kMajorTypeMask = 0xe0;
1740 : // Indicates the integer is in the following byte.
1741 : static constexpr uint8_t kAdditionalInformation1Byte = 24u;
1742 : // Indicates the integer is in the next 2 bytes.
1743 : static constexpr uint8_t kAdditionalInformation2Bytes = 25u;
1744 : // Indicates the integer is in the next 4 bytes.
1745 : static constexpr uint8_t kAdditionalInformation4Bytes = 26u;
1746 : // Indicates the integer is in the next 8 bytes.
1747 : static constexpr uint8_t kAdditionalInformation8Bytes = 27u;
1748 :
1749 : // Encodes the initial byte, consisting of the |type| in the first 3 bits
1750 : // followed by 5 bits of |additional_info|.
1751 : constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) {
1752 0 : return (static_cast<uint8_t>(type) << kMajorTypeBitShift) |
1753 0 : (additional_info & kAdditionalInformationMask);
1754 : }
1755 :
1756 : // TAG 24 indicates that what follows is a byte string which is
1757 : // encoded in CBOR format. We use this as a wrapper for
1758 : // maps and arrays, allowing us to skip them, because the
1759 : // byte string carries its size (byte length).
1760 : // https://tools.ietf.org/html/rfc7049#section-2.4.4.1
1761 : static constexpr uint8_t kInitialByteForEnvelope =
1762 : EncodeInitialByte(MajorType::TAG, 24);
1763 : // The initial byte for a byte string with at most 2^32 bytes
1764 : // of payload. This is used for envelope encoding, even if
1765 : // the byte string is shorter.
1766 : static constexpr uint8_t kInitialByteFor32BitLengthByteString =
1767 : EncodeInitialByte(MajorType::BYTE_STRING, 26);
1768 :
1769 : // See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional
1770 : // info = 31.
1771 : static constexpr uint8_t kInitialByteIndefiniteLengthArray =
1772 : EncodeInitialByte(MajorType::ARRAY, 31);
1773 : static constexpr uint8_t kInitialByteIndefiniteLengthMap =
1774 : EncodeInitialByte(MajorType::MAP, 31);
1775 : // See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite
1776 : // length maps / arrays.
1777 : static constexpr uint8_t kStopByte =
1778 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 31);
1779 :
1780 : // See RFC 7049 Section 2.3, Table 2.
1781 : static constexpr uint8_t kEncodedTrue =
1782 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
1783 : static constexpr uint8_t kEncodedFalse =
1784 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
1785 : static constexpr uint8_t kEncodedNull =
1786 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
1787 : static constexpr uint8_t kInitialByteForDouble =
1788 : EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
1789 :
1790 : // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
1791 : // arbitrary binary data encoded as BYTE_STRING.
1792 : static constexpr uint8_t kExpectedConversionToBase64Tag =
1793 : EncodeInitialByte(MajorType::TAG, 22);
1794 :
1795 : // Writes the bytes for |v| to |out|, starting with the most significant byte.
1796 : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1797 : template <typename T>
1798 : void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) {
1799 0 : for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
1800 0 : out->push_back(0xff & (v >> (shift_bytes * 8)));
1801 : }
1802 :
1803 : // Extracts sizeof(T) bytes from |in| to extract a value of type T
1804 : // (e.g. uint64_t, uint32_t, ...), most significant byte first.
1805 : // See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1806 : template <typename T>
1807 : T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
1808 : assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
1809 : T result = 0;
1810 0 : for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
1811 0 : result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
1812 : return result;
1813 : }
1814 : } // namespace
1815 :
1816 : namespace internals {
1817 : // Reads the start of a token with definitive size from |bytes|.
1818 : // |type| is the major type as specified in RFC 7049 Section 2.1.
1819 : // |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size
1820 : // (e.g. for BYTE_STRING).
1821 : // If successful, returns the number of bytes read. Otherwise returns -1.
1822 0 : int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
1823 0 : if (bytes.empty())
1824 : return -1;
1825 0 : uint8_t initial_byte = bytes[0];
1826 0 : *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
1827 :
1828 0 : uint8_t additional_information = initial_byte & kAdditionalInformationMask;
1829 0 : if (additional_information < 24) {
1830 : // Values 0-23 are encoded directly into the additional info of the
1831 : // initial byte.
1832 0 : *value = additional_information;
1833 0 : return 1;
1834 : }
1835 0 : if (additional_information == kAdditionalInformation1Byte) {
1836 : // Values 24-255 are encoded with one initial byte, followed by the value.
1837 0 : if (bytes.size() < 2)
1838 : return -1;
1839 0 : *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
1840 0 : return 2;
1841 : }
1842 0 : if (additional_information == kAdditionalInformation2Bytes) {
1843 : // Values 256-65535: 1 initial byte + 2 bytes payload.
1844 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
1845 : return -1;
1846 0 : *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
1847 0 : return 3;
1848 : }
1849 0 : if (additional_information == kAdditionalInformation4Bytes) {
1850 : // 32 bit uint: 1 initial byte + 4 bytes payload.
1851 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
1852 : return -1;
1853 0 : *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
1854 0 : return 5;
1855 : }
1856 0 : if (additional_information == kAdditionalInformation8Bytes) {
1857 : // 64 bit uint: 1 initial byte + 8 bytes payload.
1858 0 : if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
1859 : return -1;
1860 0 : *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
1861 0 : return 9;
1862 : }
1863 : return -1;
1864 : }
1865 :
1866 : // Writes the start of a token with |type|. The |value| may indicate the size,
1867 : // or it may be the payload if the value is an unsigned integer.
1868 0 : void WriteTokenStart(MajorType type,
1869 : uint64_t value,
1870 : std::vector<uint8_t>* 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 : } // namespace internals
1901 :
1902 : // =============================================================================
1903 : // Detecting CBOR content
1904 : // =============================================================================
1905 :
1906 0 : uint8_t InitialByteForEnvelope() {
1907 0 : return kInitialByteForEnvelope;
1908 : }
1909 0 : uint8_t InitialByteFor32BitLengthByteString() {
1910 0 : return kInitialByteFor32BitLengthByteString;
1911 : }
1912 0 : bool IsCBORMessage(span<uint8_t> msg) {
1913 0 : return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() &&
1914 0 : msg[1] == InitialByteFor32BitLengthByteString();
1915 : }
1916 :
1917 : // =============================================================================
1918 : // Encoding invidiual CBOR items
1919 : // =============================================================================
1920 :
1921 0 : uint8_t EncodeTrue() {
1922 0 : return kEncodedTrue;
1923 : }
1924 0 : uint8_t EncodeFalse() {
1925 0 : return kEncodedFalse;
1926 : }
1927 0 : uint8_t EncodeNull() {
1928 0 : return kEncodedNull;
1929 : }
1930 :
1931 0 : uint8_t EncodeIndefiniteLengthArrayStart() {
1932 0 : return kInitialByteIndefiniteLengthArray;
1933 : }
1934 :
1935 0 : uint8_t EncodeIndefiniteLengthMapStart() {
1936 0 : return kInitialByteIndefiniteLengthMap;
1937 : }
1938 :
1939 0 : uint8_t EncodeStop() {
1940 0 : return kStopByte;
1941 : }
1942 :
1943 0 : void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
1944 0 : if (value >= 0) {
1945 0 : internals::WriteTokenStart(MajorType::UNSIGNED, value, out);
1946 : } else {
1947 0 : uint64_t representation = static_cast<uint64_t>(-(value + 1));
1948 0 : internals::WriteTokenStart(MajorType::NEGATIVE, representation, out);
1949 : }
1950 0 : }
1951 :
1952 0 : void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
1953 : uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
1954 0 : internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
1955 : // When emitting UTF16 characters, we always write the least significant byte
1956 : // first; this is because it's the native representation for X86.
1957 : // TODO(johannes): Implement a more efficient thing here later, e.g.
1958 : // casting *iff* the machine has this byte order.
1959 : // The wire format for UTF16 chars will probably remain the same
1960 : // (least significant byte first) since this way we can have
1961 : // golden files, unittests, etc. that port easily and universally.
1962 : // See also:
1963 : // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1964 0 : for (const uint16_t two_bytes : in) {
1965 0 : out->push_back(two_bytes);
1966 0 : out->push_back(two_bytes >> 8);
1967 : }
1968 0 : }
1969 :
1970 0 : void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
1971 0 : internals::WriteTokenStart(MajorType::STRING,
1972 0 : static_cast<uint64_t>(in.size_bytes()), out);
1973 : out->insert(out->end(), in.begin(), in.end());
1974 0 : }
1975 :
1976 0 : void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) {
1977 0 : for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) {
1978 0 : if (latin1[ii] <= 127)
1979 0 : continue;
1980 : // If there's at least one non-ASCII char, convert to UTF8.
1981 : std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii);
1982 0 : for (; ii < latin1.size(); ++ii) {
1983 0 : if (latin1[ii] <= 127) {
1984 0 : utf8.push_back(latin1[ii]);
1985 : } else {
1986 : // 0xC0 means it's a UTF8 sequence with 2 bytes.
1987 0 : utf8.push_back((latin1[ii] >> 6) | 0xc0);
1988 0 : utf8.push_back((latin1[ii] | 0x80) & 0xbf);
1989 : }
1990 : }
1991 0 : EncodeString8(SpanFromVector(utf8), out);
1992 : return;
1993 : }
1994 0 : EncodeString8(latin1, out);
1995 : }
1996 :
1997 0 : void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) {
1998 : // If there's at least one non-ASCII char, encode as STRING16 (UTF16).
1999 0 : for (uint16_t ch : utf16) {
2000 0 : if (ch <= 127)
2001 : continue;
2002 0 : EncodeString16(utf16, out);
2003 0 : return;
2004 : }
2005 : // It's all US-ASCII, strip out every second byte and encode as UTF8.
2006 : internals::WriteTokenStart(MajorType::STRING,
2007 0 : static_cast<uint64_t>(utf16.size()), out);
2008 : out->insert(out->end(), utf16.begin(), utf16.end());
2009 : }
2010 :
2011 0 : void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
2012 0 : out->push_back(kExpectedConversionToBase64Tag);
2013 0 : uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
2014 0 : internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
2015 : out->insert(out->end(), in.begin(), in.end());
2016 0 : }
2017 :
2018 : // A double is encoded with a specific initial byte
2019 : // (kInitialByteForDouble) plus the 64 bits of payload for its value.
2020 : constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
2021 :
2022 : // An envelope is encoded with a specific initial byte
2023 : // (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
2024 : // bit wide length, plus a 32 bit length for that string.
2025 : constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
2026 :
2027 0 : void EncodeDouble(double value, std::vector<uint8_t>* out) {
2028 : // The additional_info=27 indicates 64 bits for the double follow.
2029 : // See RFC 7049 Section 2.3, Table 1.
2030 0 : out->push_back(kInitialByteForDouble);
2031 : union {
2032 : double from_double;
2033 : uint64_t to_uint64;
2034 : } reinterpret;
2035 : reinterpret.from_double = value;
2036 0 : WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
2037 0 : }
2038 :
2039 : // =============================================================================
2040 : // cbor::EnvelopeEncoder - for wrapping submessages
2041 : // =============================================================================
2042 :
2043 0 : void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
2044 : assert(byte_size_pos_ == 0);
2045 0 : out->push_back(kInitialByteForEnvelope);
2046 0 : out->push_back(kInitialByteFor32BitLengthByteString);
2047 0 : byte_size_pos_ = out->size();
2048 0 : out->resize(out->size() + sizeof(uint32_t));
2049 0 : }
2050 :
2051 0 : bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
2052 : assert(byte_size_pos_ != 0);
2053 : // The byte size is the size of the payload, that is, all the
2054 : // bytes that were written past the byte size position itself.
2055 0 : uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t));
2056 : // We store exactly 4 bytes, so at most INT32MAX, with most significant
2057 : // byte first.
2058 0 : if (byte_size > std::numeric_limits<uint32_t>::max())
2059 : return false;
2060 0 : for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
2061 : --shift_bytes) {
2062 0 : (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8));
2063 : }
2064 : return true;
2065 : }
2066 :
2067 : // =============================================================================
2068 : // cbor::NewCBOREncoder - for encoding from a streaming parser
2069 : // =============================================================================
2070 :
2071 : namespace {
2072 0 : class CBOREncoder : public StreamingParserHandler {
2073 : public:
2074 : CBOREncoder(std::vector<uint8_t>* out, Status* status)
2075 0 : : out_(out), status_(status) {
2076 0 : *status_ = Status();
2077 : }
2078 :
2079 0 : void HandleMapBegin() override {
2080 0 : envelopes_.emplace_back();
2081 0 : envelopes_.back().EncodeStart(out_);
2082 0 : out_->push_back(kInitialByteIndefiniteLengthMap);
2083 0 : }
2084 :
2085 0 : void HandleMapEnd() override {
2086 0 : out_->push_back(kStopByte);
2087 : assert(!envelopes_.empty());
2088 0 : envelopes_.back().EncodeStop(out_);
2089 : envelopes_.pop_back();
2090 0 : }
2091 :
2092 0 : void HandleArrayBegin() override {
2093 0 : envelopes_.emplace_back();
2094 0 : envelopes_.back().EncodeStart(out_);
2095 0 : out_->push_back(kInitialByteIndefiniteLengthArray);
2096 0 : }
2097 :
2098 0 : void HandleArrayEnd() override {
2099 0 : out_->push_back(kStopByte);
2100 : assert(!envelopes_.empty());
2101 0 : envelopes_.back().EncodeStop(out_);
2102 : envelopes_.pop_back();
2103 0 : }
2104 :
2105 0 : void HandleString8(span<uint8_t> chars) override {
2106 0 : EncodeString8(chars, out_);
2107 0 : }
2108 :
2109 0 : void HandleString16(span<uint16_t> chars) override {
2110 0 : EncodeFromUTF16(chars, out_);
2111 0 : }
2112 :
2113 0 : void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); }
2114 :
2115 0 : void HandleDouble(double value) override { EncodeDouble(value, out_); }
2116 :
2117 0 : void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
2118 :
2119 0 : void HandleBool(bool value) override {
2120 : // See RFC 7049 Section 2.3, Table 2.
2121 0 : out_->push_back(value ? kEncodedTrue : kEncodedFalse);
2122 0 : }
2123 :
2124 0 : void HandleNull() override {
2125 : // See RFC 7049 Section 2.3, Table 2.
2126 0 : out_->push_back(kEncodedNull);
2127 0 : }
2128 :
2129 0 : void HandleError(Status error) override {
2130 : assert(!error.ok());
2131 0 : *status_ = error;
2132 0 : out_->clear();
2133 0 : }
2134 :
2135 : private:
2136 : std::vector<uint8_t>* out_;
2137 : std::vector<EnvelopeEncoder> envelopes_;
2138 : Status* status_;
2139 : };
2140 : } // namespace
2141 :
2142 0 : std::unique_ptr<StreamingParserHandler> NewCBOREncoder(
2143 : std::vector<uint8_t>* out,
2144 : Status* status) {
2145 0 : return std::unique_ptr<StreamingParserHandler>(new CBOREncoder(out, status));
2146 : }
2147 :
2148 : // =============================================================================
2149 : // cbor::CBORTokenizer - for parsing individual CBOR items
2150 : // =============================================================================
2151 :
2152 0 : CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
2153 0 : ReadNextToken(/*enter_envelope=*/false);
2154 0 : }
2155 0 : CBORTokenizer::~CBORTokenizer() {}
2156 :
2157 0 : CBORTokenTag CBORTokenizer::TokenTag() const {
2158 0 : return token_tag_;
2159 : }
2160 :
2161 0 : void CBORTokenizer::Next() {
2162 0 : if (token_tag_ == CBORTokenTag::ERROR_VALUE ||
2163 : token_tag_ == CBORTokenTag::DONE)
2164 : return;
2165 0 : ReadNextToken(/*enter_envelope=*/false);
2166 : }
2167 :
2168 0 : void CBORTokenizer::EnterEnvelope() {
2169 : assert(token_tag_ == CBORTokenTag::ENVELOPE);
2170 0 : ReadNextToken(/*enter_envelope=*/true);
2171 0 : }
2172 :
2173 0 : Status CBORTokenizer::Status() const {
2174 0 : return status_;
2175 : }
2176 :
2177 0 : int32_t CBORTokenizer::GetInt32() const {
2178 : assert(token_tag_ == CBORTokenTag::INT32);
2179 : // The range checks happen in ::ReadNextToken().
2180 : return static_cast<uint32_t>(
2181 0 : token_start_type_ == MajorType::UNSIGNED
2182 0 : ? token_start_internal_value_
2183 0 : : -static_cast<int64_t>(token_start_internal_value_) - 1);
2184 : }
2185 :
2186 0 : double CBORTokenizer::GetDouble() const {
2187 : assert(token_tag_ == CBORTokenTag::DOUBLE);
2188 : union {
2189 : uint64_t from_uint64;
2190 : double to_double;
2191 : } reinterpret;
2192 0 : reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
2193 0 : bytes_.subspan(status_.pos + 1));
2194 0 : return reinterpret.to_double;
2195 : }
2196 :
2197 0 : span<uint8_t> CBORTokenizer::GetString8() const {
2198 : assert(token_tag_ == CBORTokenTag::STRING8);
2199 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2200 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2201 : }
2202 :
2203 0 : span<uint8_t> CBORTokenizer::GetString16WireRep() const {
2204 : assert(token_tag_ == CBORTokenTag::STRING16);
2205 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2206 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2207 : }
2208 :
2209 0 : span<uint8_t> CBORTokenizer::GetBinary() const {
2210 : assert(token_tag_ == CBORTokenTag::BINARY);
2211 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2212 0 : return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2213 : }
2214 :
2215 0 : span<uint8_t> CBORTokenizer::GetEnvelopeContents() const {
2216 : assert(token_tag_ == CBORTokenTag::ENVELOPE);
2217 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2218 0 : return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length);
2219 : }
2220 :
2221 0 : void CBORTokenizer::ReadNextToken(bool enter_envelope) {
2222 0 : if (enter_envelope) {
2223 0 : status_.pos += kEncodedEnvelopeHeaderSize;
2224 : } else {
2225 : status_.pos =
2226 0 : status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
2227 : }
2228 0 : status_.error = Error::OK;
2229 0 : if (status_.pos >= bytes_.size()) {
2230 0 : token_tag_ = CBORTokenTag::DONE;
2231 0 : return;
2232 : }
2233 0 : switch (bytes_[status_.pos]) {
2234 : case kStopByte:
2235 : SetToken(CBORTokenTag::STOP, 1);
2236 : return;
2237 : case kInitialByteIndefiniteLengthMap:
2238 : SetToken(CBORTokenTag::MAP_START, 1);
2239 : return;
2240 : case kInitialByteIndefiniteLengthArray:
2241 : SetToken(CBORTokenTag::ARRAY_START, 1);
2242 : return;
2243 : case kEncodedTrue:
2244 : SetToken(CBORTokenTag::TRUE_VALUE, 1);
2245 : return;
2246 : case kEncodedFalse:
2247 : SetToken(CBORTokenTag::FALSE_VALUE, 1);
2248 : return;
2249 : case kEncodedNull:
2250 : SetToken(CBORTokenTag::NULL_VALUE, 1);
2251 : return;
2252 : case kExpectedConversionToBase64Tag: { // BINARY
2253 0 : int8_t bytes_read = internals::ReadTokenStart(
2254 : bytes_.subspan(status_.pos + 1), &token_start_type_,
2255 0 : &token_start_internal_value_);
2256 0 : int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
2257 0 : if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
2258 0 : status_.pos + token_byte_length > bytes_.size()) {
2259 : SetError(Error::CBOR_INVALID_BINARY);
2260 : return;
2261 : }
2262 : SetToken(CBORTokenTag::BINARY,
2263 : static_cast<std::ptrdiff_t>(token_byte_length));
2264 : return;
2265 : }
2266 : case kInitialByteForDouble: { // DOUBLE
2267 0 : if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
2268 : SetError(Error::CBOR_INVALID_DOUBLE);
2269 : return;
2270 : }
2271 : SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
2272 : return;
2273 : }
2274 : case kInitialByteForEnvelope: { // ENVELOPE
2275 0 : if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
2276 : SetError(Error::CBOR_INVALID_ENVELOPE);
2277 : return;
2278 : }
2279 : // The envelope must be a byte string with 32 bit length.
2280 0 : if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
2281 : SetError(Error::CBOR_INVALID_ENVELOPE);
2282 : return;
2283 : }
2284 : // Read the length of the byte string.
2285 0 : token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
2286 0 : bytes_.subspan(status_.pos + 2));
2287 : // Make sure the payload is contained within the message.
2288 0 : if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
2289 0 : status_.pos >
2290 : static_cast<std::size_t>(bytes_.size())) {
2291 : SetError(Error::CBOR_INVALID_ENVELOPE);
2292 : return;
2293 : }
2294 0 : auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2295 0 : SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length);
2296 : return;
2297 : }
2298 : default: {
2299 : span<uint8_t> remainder =
2300 0 : bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
2301 : assert(!remainder.empty());
2302 0 : int8_t token_start_length = internals::ReadTokenStart(
2303 0 : remainder, &token_start_type_, &token_start_internal_value_);
2304 : bool success = token_start_length != -1;
2305 0 : switch (token_start_type_) {
2306 : case MajorType::UNSIGNED: // INT32.
2307 0 : if (!success || std::numeric_limits<int32_t>::max() <
2308 0 : token_start_internal_value_) {
2309 : SetError(Error::CBOR_INVALID_INT32);
2310 0 : return;
2311 : }
2312 0 : SetToken(CBORTokenTag::INT32, token_start_length);
2313 : return;
2314 : case MajorType::NEGATIVE: // INT32.
2315 0 : if (!success ||
2316 : std::numeric_limits<int32_t>::min() >
2317 0 : -static_cast<int64_t>(token_start_internal_value_) - 1) {
2318 : SetError(Error::CBOR_INVALID_INT32);
2319 : return;
2320 : }
2321 0 : SetToken(CBORTokenTag::INT32, token_start_length);
2322 : return;
2323 : case MajorType::STRING: { // STRING8.
2324 0 : if (!success || remainder.size() < static_cast<int64_t>(
2325 0 : token_start_internal_value_)) {
2326 : SetError(Error::CBOR_INVALID_STRING8);
2327 : return;
2328 : }
2329 : auto length =
2330 0 : static_cast<std::ptrdiff_t>(token_start_internal_value_);
2331 0 : SetToken(CBORTokenTag::STRING8, token_start_length + length);
2332 : return;
2333 : }
2334 : case MajorType::BYTE_STRING: { // STRING16.
2335 0 : if (!success ||
2336 0 : remainder.size() <
2337 0 : static_cast<int64_t>(token_start_internal_value_) ||
2338 : // Must be divisible by 2 since UTF16 is 2 bytes per character.
2339 0 : token_start_internal_value_ & 1) {
2340 : SetError(Error::CBOR_INVALID_STRING16);
2341 : return;
2342 : }
2343 : auto length =
2344 0 : static_cast<std::ptrdiff_t>(token_start_internal_value_);
2345 0 : SetToken(CBORTokenTag::STRING16, token_start_length + length);
2346 : return;
2347 : }
2348 : case MajorType::ARRAY:
2349 : case MajorType::MAP:
2350 : case MajorType::TAG:
2351 : case MajorType::SIMPLE_VALUE:
2352 : SetError(Error::CBOR_UNSUPPORTED_VALUE);
2353 : return;
2354 : }
2355 : }
2356 : }
2357 : }
2358 :
2359 0 : void CBORTokenizer::SetToken(CBORTokenTag token_tag,
2360 : std::ptrdiff_t token_byte_length) {
2361 0 : token_tag_ = token_tag;
2362 0 : token_byte_length_ = token_byte_length;
2363 0 : }
2364 :
2365 0 : void CBORTokenizer::SetError(Error error) {
2366 0 : token_tag_ = CBORTokenTag::ERROR_VALUE;
2367 0 : status_.error = error;
2368 0 : }
2369 :
2370 : // =============================================================================
2371 : // cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
2372 : // =============================================================================
2373 :
2374 : namespace {
2375 : // When parsing CBOR, we limit recursion depth for objects and arrays
2376 : // to this constant.
2377 : static constexpr int kStackLimit = 1000;
2378 :
2379 : // Below are three parsing routines for CBOR, which cover enough
2380 : // to roundtrip JSON messages.
2381 : bool ParseMap(int32_t stack_depth,
2382 : CBORTokenizer* tokenizer,
2383 : StreamingParserHandler* out);
2384 : bool ParseArray(int32_t stack_depth,
2385 : CBORTokenizer* tokenizer,
2386 : StreamingParserHandler* out);
2387 : bool ParseValue(int32_t stack_depth,
2388 : CBORTokenizer* tokenizer,
2389 : StreamingParserHandler* out);
2390 :
2391 0 : void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
2392 : std::vector<uint16_t> value;
2393 : span<uint8_t> rep = tokenizer->GetString16WireRep();
2394 0 : for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
2395 0 : value.push_back((rep[ii + 1] << 8) | rep[ii]);
2396 0 : out->HandleString16(span<uint16_t>(value.data(), value.size()));
2397 : tokenizer->Next();
2398 0 : }
2399 :
2400 0 : bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
2401 : assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
2402 0 : out->HandleString8(tokenizer->GetString8());
2403 : tokenizer->Next();
2404 0 : return true;
2405 : }
2406 :
2407 0 : bool ParseValue(int32_t stack_depth,
2408 : CBORTokenizer* tokenizer,
2409 : StreamingParserHandler* out) {
2410 0 : if (stack_depth > kStackLimit) {
2411 0 : out->HandleError(
2412 0 : Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
2413 0 : return false;
2414 : }
2415 : // Skip past the envelope to get to what's inside.
2416 0 : if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
2417 : tokenizer->EnterEnvelope();
2418 0 : switch (tokenizer->TokenTag()) {
2419 : case CBORTokenTag::ERROR_VALUE:
2420 0 : out->HandleError(tokenizer->Status());
2421 0 : return false;
2422 : case CBORTokenTag::DONE:
2423 0 : out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
2424 0 : tokenizer->Status().pos});
2425 0 : return false;
2426 : case CBORTokenTag::TRUE_VALUE:
2427 0 : out->HandleBool(true);
2428 : tokenizer->Next();
2429 : return true;
2430 : case CBORTokenTag::FALSE_VALUE:
2431 0 : out->HandleBool(false);
2432 : tokenizer->Next();
2433 : return true;
2434 : case CBORTokenTag::NULL_VALUE:
2435 0 : out->HandleNull();
2436 : tokenizer->Next();
2437 : return true;
2438 : case CBORTokenTag::INT32:
2439 0 : out->HandleInt32(tokenizer->GetInt32());
2440 : tokenizer->Next();
2441 : return true;
2442 : case CBORTokenTag::DOUBLE:
2443 0 : out->HandleDouble(tokenizer->GetDouble());
2444 : tokenizer->Next();
2445 : return true;
2446 : case CBORTokenTag::STRING8:
2447 0 : return ParseUTF8String(tokenizer, out);
2448 : case CBORTokenTag::STRING16:
2449 0 : ParseUTF16String(tokenizer, out);
2450 0 : return true;
2451 : case CBORTokenTag::BINARY: {
2452 0 : out->HandleBinary(tokenizer->GetBinary());
2453 : tokenizer->Next();
2454 : return true;
2455 : }
2456 : case CBORTokenTag::MAP_START:
2457 0 : return ParseMap(stack_depth + 1, tokenizer, out);
2458 : case CBORTokenTag::ARRAY_START:
2459 0 : return ParseArray(stack_depth + 1, tokenizer, out);
2460 : default:
2461 0 : out->HandleError(
2462 0 : Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
2463 0 : return false;
2464 : }
2465 : }
2466 :
2467 : // |bytes| must start with the indefinite length array byte, so basically,
2468 : // ParseArray may only be called after an indefinite length array has been
2469 : // detected.
2470 0 : bool ParseArray(int32_t stack_depth,
2471 : CBORTokenizer* tokenizer,
2472 : StreamingParserHandler* out) {
2473 : assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
2474 : tokenizer->Next();
2475 0 : out->HandleArrayBegin();
2476 0 : while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2477 0 : if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2478 0 : out->HandleError(
2479 0 : Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
2480 0 : return false;
2481 : }
2482 0 : if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2483 0 : out->HandleError(tokenizer->Status());
2484 0 : return false;
2485 : }
2486 : // Parse value.
2487 0 : if (!ParseValue(stack_depth, tokenizer, out))
2488 : return false;
2489 : }
2490 0 : out->HandleArrayEnd();
2491 : tokenizer->Next();
2492 : return true;
2493 : }
2494 :
2495 : // |bytes| must start with the indefinite length array byte, so basically,
2496 : // ParseArray may only be called after an indefinite length array has been
2497 : // detected.
2498 0 : bool ParseMap(int32_t stack_depth,
2499 : CBORTokenizer* tokenizer,
2500 : StreamingParserHandler* out) {
2501 : assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
2502 0 : out->HandleMapBegin();
2503 : tokenizer->Next();
2504 0 : while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2505 0 : if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2506 0 : out->HandleError(
2507 0 : Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
2508 0 : return false;
2509 : }
2510 0 : if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2511 0 : out->HandleError(tokenizer->Status());
2512 0 : return false;
2513 : }
2514 : // Parse key.
2515 0 : if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
2516 0 : if (!ParseUTF8String(tokenizer, out))
2517 : return false;
2518 0 : } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
2519 0 : ParseUTF16String(tokenizer, out);
2520 : } else {
2521 0 : out->HandleError(
2522 0 : Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
2523 0 : return false;
2524 : }
2525 : // Parse value.
2526 0 : if (!ParseValue(stack_depth, tokenizer, out))
2527 : return false;
2528 : }
2529 0 : out->HandleMapEnd();
2530 : tokenizer->Next();
2531 : return true;
2532 : }
2533 : } // namespace
2534 :
2535 0 : void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) {
2536 0 : if (bytes.empty()) {
2537 0 : out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
2538 0 : return;
2539 : }
2540 0 : if (bytes[0] != kInitialByteForEnvelope) {
2541 0 : out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
2542 0 : return;
2543 : }
2544 : CBORTokenizer tokenizer(bytes);
2545 0 : if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2546 0 : out->HandleError(tokenizer.Status());
2547 0 : return;
2548 : }
2549 : // We checked for the envelope start byte above, so the tokenizer
2550 : // must agree here, since it's not an error.
2551 : assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
2552 : tokenizer.EnterEnvelope();
2553 0 : if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
2554 0 : out->HandleError(
2555 0 : Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
2556 0 : return;
2557 : }
2558 0 : if (!ParseMap(/*stack_depth=*/1, &tokenizer, out))
2559 : return;
2560 0 : if (tokenizer.TokenTag() == CBORTokenTag::DONE)
2561 : return;
2562 0 : if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2563 0 : out->HandleError(tokenizer.Status());
2564 0 : return;
2565 : }
2566 0 : out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
2567 : }
2568 : } // namespace cbor
2569 :
2570 : namespace json {
2571 :
2572 : // =============================================================================
2573 : // json::NewJSONEncoder - for encoding streaming parser events as JSON
2574 : // =============================================================================
2575 :
2576 : namespace {
2577 : // Prints |value| to |out| with 4 hex digits, most significant chunk first.
2578 0 : void PrintHex(uint16_t value, std::string* out) {
2579 0 : for (int ii = 3; ii >= 0; --ii) {
2580 0 : int four_bits = 0xf & (value >> (4 * ii));
2581 0 : out->append(1, four_bits + ((four_bits <= 9) ? '0' : ('a' - 10)));
2582 : }
2583 0 : }
2584 :
2585 : // In the writer below, we maintain a stack of State instances.
2586 : // It is just enough to emit the appropriate delimiters and brackets
2587 : // in JSON.
2588 : enum class Container {
2589 : // Used for the top-level, initial state.
2590 : NONE,
2591 : // Inside a JSON object.
2592 : MAP,
2593 : // Inside a JSON array.
2594 : ARRAY
2595 : };
2596 : class State {
2597 : public:
2598 0 : explicit State(Container container) : container_(container) {}
2599 0 : void StartElement(std::string* out) {
2600 : assert(container_ != Container::NONE || size_ == 0);
2601 0 : if (size_ != 0) {
2602 0 : char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':';
2603 : out->append(1, delim);
2604 : }
2605 0 : ++size_;
2606 0 : }
2607 : Container container() const { return container_; }
2608 :
2609 : private:
2610 : Container container_ = Container::NONE;
2611 : int size_ = 0;
2612 : };
2613 :
2614 : constexpr char kBase64Table[] =
2615 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2616 : "abcdefghijklmnopqrstuvwxyz0123456789+/";
2617 :
2618 0 : void Base64Encode(const span<uint8_t>& in, std::string* out) {
2619 : // The following three cases are based on the tables in the example
2620 : // section in https://en.wikipedia.org/wiki/Base64. We process three
2621 : // input bytes at a time, emitting 4 output bytes at a time.
2622 : std::ptrdiff_t ii = 0;
2623 :
2624 : // While possible, process three input bytes.
2625 0 : for (; ii + 3 <= in.size(); ii += 3) {
2626 0 : uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2];
2627 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2628 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2629 0 : out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
2630 0 : out->push_back(kBase64Table[twentyfour_bits & 0x3f]);
2631 : }
2632 0 : if (ii + 2 <= in.size()) { // Process two input bytes.
2633 0 : uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8);
2634 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2635 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2636 0 : out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]);
2637 0 : out->push_back('='); // Emit padding.
2638 0 : return;
2639 : }
2640 0 : if (ii + 1 <= in.size()) { // Process a single input byte.
2641 0 : uint32_t twentyfour_bits = (in[ii] << 16);
2642 0 : out->push_back(kBase64Table[(twentyfour_bits >> 18)]);
2643 0 : out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]);
2644 0 : out->push_back('='); // Emit padding.
2645 0 : out->push_back('='); // Emit padding.
2646 : }
2647 : }
2648 :
2649 : // Implements a handler for JSON parser events to emit a JSON string.
2650 0 : class JSONEncoder : public StreamingParserHandler {
2651 : public:
2652 0 : JSONEncoder(const Platform* platform, std::string* out, Status* status)
2653 0 : : platform_(platform), out_(out), status_(status) {
2654 0 : *status_ = Status();
2655 0 : state_.emplace(Container::NONE);
2656 0 : }
2657 :
2658 0 : void HandleMapBegin() override {
2659 0 : if (!status_->ok())
2660 : return;
2661 : assert(!state_.empty());
2662 0 : state_.top().StartElement(out_);
2663 0 : state_.emplace(Container::MAP);
2664 0 : out_->append("{");
2665 : }
2666 :
2667 0 : void HandleMapEnd() override {
2668 0 : if (!status_->ok())
2669 : return;
2670 : assert(state_.size() >= 2 && state_.top().container() == Container::MAP);
2671 : state_.pop();
2672 0 : out_->append("}");
2673 : }
2674 :
2675 0 : void HandleArrayBegin() override {
2676 0 : if (!status_->ok())
2677 : return;
2678 0 : state_.top().StartElement(out_);
2679 0 : state_.emplace(Container::ARRAY);
2680 0 : out_->append("[");
2681 : }
2682 :
2683 0 : void HandleArrayEnd() override {
2684 0 : if (!status_->ok())
2685 : return;
2686 : assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY);
2687 : state_.pop();
2688 0 : out_->append("]");
2689 : }
2690 :
2691 0 : void HandleString16(span<uint16_t> chars) override {
2692 0 : if (!status_->ok())
2693 : return;
2694 0 : state_.top().StartElement(out_);
2695 0 : out_->append("\"");
2696 0 : for (const uint16_t ch : chars) {
2697 0 : if (ch == '"') {
2698 0 : out_->append("\\\"");
2699 0 : } else if (ch == '\\') {
2700 0 : out_->append("\\\\");
2701 0 : } else if (ch == '\b') {
2702 0 : out_->append("\\b");
2703 0 : } else if (ch == '\f') {
2704 0 : out_->append("\\f");
2705 0 : } else if (ch == '\n') {
2706 0 : out_->append("\\n");
2707 0 : } else if (ch == '\r') {
2708 0 : out_->append("\\r");
2709 0 : } else if (ch == '\t') {
2710 0 : out_->append("\\t");
2711 0 : } else if (ch >= 32 && ch <= 126) {
2712 0 : out_->append(1, ch);
2713 : } else {
2714 0 : out_->append("\\u");
2715 0 : PrintHex(ch, out_);
2716 : }
2717 : }
2718 0 : out_->append("\"");
2719 : }
2720 :
2721 0 : void HandleString8(span<uint8_t> chars) override {
2722 0 : if (!status_->ok())
2723 : return;
2724 0 : state_.top().StartElement(out_);
2725 0 : out_->append("\"");
2726 0 : for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) {
2727 0 : uint8_t c = chars[ii];
2728 0 : if (c == '"') {
2729 0 : out_->append("\\\"");
2730 0 : } else if (c == '\\') {
2731 0 : out_->append("\\\\");
2732 0 : } else if (c == '\b') {
2733 0 : out_->append("\\b");
2734 0 : } else if (c == '\f') {
2735 0 : out_->append("\\f");
2736 0 : } else if (c == '\n') {
2737 0 : out_->append("\\n");
2738 0 : } else if (c == '\r') {
2739 0 : out_->append("\\r");
2740 0 : } else if (c == '\t') {
2741 0 : out_->append("\\t");
2742 0 : } else if (c >= 32 && c <= 126) {
2743 0 : out_->append(1, c);
2744 0 : } else if (c < 32) {
2745 0 : out_->append("\\u");
2746 0 : PrintHex(static_cast<uint16_t>(c), out_);
2747 : } else {
2748 : // Inspect the leading byte to figure out how long the utf8
2749 : // byte sequence is; while doing this initialize |codepoint|
2750 : // with the first few bits.
2751 : // See table in: https://en.wikipedia.org/wiki/UTF-8
2752 : // byte one is 110x xxxx -> 2 byte utf8 sequence
2753 : // byte one is 1110 xxxx -> 3 byte utf8 sequence
2754 : // byte one is 1111 0xxx -> 4 byte utf8 sequence
2755 : uint32_t codepoint;
2756 : int num_bytes_left;
2757 0 : if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence
2758 : num_bytes_left = 1;
2759 0 : codepoint = c & 0x1f;
2760 0 : } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence
2761 : num_bytes_left = 2;
2762 0 : codepoint = c & 0x0f;
2763 0 : } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence
2764 0 : codepoint = c & 0x07;
2765 : num_bytes_left = 3;
2766 : } else {
2767 : continue; // invalid leading byte
2768 : }
2769 :
2770 : // If we have enough bytes in our input, decode the remaining ones
2771 : // belonging to this Unicode character into |codepoint|.
2772 0 : if (ii + num_bytes_left > chars.size())
2773 : continue;
2774 0 : while (num_bytes_left > 0) {
2775 0 : c = chars[++ii];
2776 0 : --num_bytes_left;
2777 : // Check the next byte is a continuation byte, that is 10xx xxxx.
2778 0 : if ((c & 0xc0) != 0x80)
2779 : continue;
2780 0 : codepoint = (codepoint << 6) | (c & 0x3f);
2781 : }
2782 :
2783 : // Disallow overlong encodings for ascii characters, as these
2784 : // would include " and other characters significant to JSON
2785 : // string termination / control.
2786 0 : if (codepoint < 0x7f)
2787 : continue;
2788 : // Invalid in UTF8, and can't be represented in UTF16 anyway.
2789 0 : if (codepoint > 0x10ffff)
2790 : continue;
2791 :
2792 : // So, now we transcode to UTF16,
2793 : // using the math described at https://en.wikipedia.org/wiki/UTF-16,
2794 : // for either one or two 16 bit characters.
2795 0 : if (codepoint < 0xffff) {
2796 0 : out_->append("\\u");
2797 0 : PrintHex(static_cast<uint16_t>(codepoint), out_);
2798 0 : continue;
2799 : }
2800 0 : codepoint -= 0x10000;
2801 : // high surrogate
2802 0 : out_->append("\\u");
2803 0 : PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_);
2804 : // low surrogate
2805 0 : out_->append("\\u");
2806 0 : PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_);
2807 : }
2808 : }
2809 0 : out_->append("\"");
2810 : }
2811 :
2812 0 : void HandleBinary(span<uint8_t> bytes) override {
2813 0 : if (!status_->ok())
2814 : return;
2815 0 : state_.top().StartElement(out_);
2816 0 : out_->append("\"");
2817 0 : Base64Encode(bytes, out_);
2818 0 : out_->append("\"");
2819 : }
2820 :
2821 0 : void HandleDouble(double value) override {
2822 0 : if (!status_->ok())
2823 0 : return;
2824 0 : state_.top().StartElement(out_);
2825 0 : std::unique_ptr<char[]> str_value = platform_->DToStr(value);
2826 :
2827 : // DToStr may fail to emit a 0 before the decimal dot. E.g. this is
2828 : // the case in base::NumberToString in Chromium (which is based on
2829 : // dmg_fp). So, much like
2830 : // https://cs.chromium.org/chromium/src/base/json/json_writer.cc
2831 : // we probe for this and emit the leading 0 anyway if necessary.
2832 : const char* chars = str_value.get();
2833 0 : if (chars[0] == '.') {
2834 0 : out_->append("0");
2835 0 : } else if (chars[0] == '-' && chars[1] == '.') {
2836 0 : out_->append("-0");
2837 0 : ++chars;
2838 : }
2839 0 : out_->append(chars);
2840 : }
2841 :
2842 0 : void HandleInt32(int32_t value) override {
2843 0 : if (!status_->ok())
2844 : return;
2845 0 : state_.top().StartElement(out_);
2846 0 : out_->append(std::to_string(value));
2847 : }
2848 :
2849 0 : void HandleBool(bool value) override {
2850 0 : if (!status_->ok())
2851 : return;
2852 0 : state_.top().StartElement(out_);
2853 0 : out_->append(value ? "true" : "false");
2854 : }
2855 :
2856 0 : void HandleNull() override {
2857 0 : if (!status_->ok())
2858 : return;
2859 0 : state_.top().StartElement(out_);
2860 0 : out_->append("null");
2861 : }
2862 :
2863 0 : void HandleError(Status error) override {
2864 : assert(!error.ok());
2865 0 : *status_ = error;
2866 0 : out_->clear();
2867 0 : }
2868 :
2869 : private:
2870 : const Platform* platform_;
2871 : std::string* out_;
2872 : Status* status_;
2873 : std::stack<State> state_;
2874 : };
2875 : } // namespace
2876 :
2877 0 : std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform,
2878 : std::string* out,
2879 : Status* status) {
2880 : return std::unique_ptr<StreamingParserHandler>(
2881 0 : new JSONEncoder(platform, out, status));
2882 : }
2883 :
2884 : // =============================================================================
2885 : // json::ParseJSON - for receiving streaming parser events for JSON.
2886 : // =============================================================================
2887 :
2888 : namespace {
2889 : const int kStackLimit = 1000;
2890 :
2891 : enum Token {
2892 : ObjectBegin,
2893 : ObjectEnd,
2894 : ArrayBegin,
2895 : ArrayEnd,
2896 : StringLiteral,
2897 : Number,
2898 : BoolTrue,
2899 : BoolFalse,
2900 : NullToken,
2901 : ListSeparator,
2902 : ObjectPairSeparator,
2903 : InvalidToken,
2904 : NoInput
2905 : };
2906 :
2907 : const char* const kNullString = "null";
2908 : const char* const kTrueString = "true";
2909 : const char* const kFalseString = "false";
2910 :
2911 : template <typename Char>
2912 : class JsonParser {
2913 : public:
2914 : JsonParser(const Platform* platform, StreamingParserHandler* handler)
2915 0 : : platform_(platform), handler_(handler) {}
2916 :
2917 0 : void Parse(const Char* start, std::size_t length) {
2918 0 : start_pos_ = start;
2919 0 : const Char* end = start + length;
2920 : const Char* tokenEnd;
2921 0 : ParseValue(start, end, &tokenEnd, 0);
2922 0 : if (tokenEnd != end) {
2923 : HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd);
2924 : }
2925 0 : }
2926 :
2927 : private:
2928 0 : bool CharsToDouble(const uint16_t* chars,
2929 : std::size_t length,
2930 : double* result) {
2931 : std::string buffer;
2932 0 : buffer.reserve(length + 1);
2933 0 : for (std::size_t ii = 0; ii < length; ++ii) {
2934 0 : bool is_ascii = !(chars[ii] & ~0x7F);
2935 0 : if (!is_ascii)
2936 : return false;
2937 0 : buffer.push_back(static_cast<char>(chars[ii]));
2938 : }
2939 0 : return platform_->StrToD(buffer.c_str(), result);
2940 : }
2941 :
2942 0 : bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) {
2943 : std::string buffer(reinterpret_cast<const char*>(chars), length);
2944 0 : return platform_->StrToD(buffer.c_str(), result);
2945 : }
2946 :
2947 : static bool ParseConstToken(const Char* start,
2948 : const Char* end,
2949 : const Char** token_end,
2950 : const char* token) {
2951 : // |token| is \0 terminated, it's one of the constants at top of the file.
2952 0 : while (start < end && *token != '\0' && *start++ == *token++) {
2953 : }
2954 0 : if (*token != '\0')
2955 : return false;
2956 0 : *token_end = start;
2957 : return true;
2958 : }
2959 :
2960 : static bool ReadInt(const Char* start,
2961 : const Char* end,
2962 : const Char** token_end,
2963 : bool allow_leading_zeros) {
2964 0 : if (start == end)
2965 : return false;
2966 0 : bool has_leading_zero = '0' == *start;
2967 : int length = 0;
2968 0 : while (start < end && '0' <= *start && *start <= '9') {
2969 0 : ++start;
2970 0 : ++length;
2971 : }
2972 0 : if (!length)
2973 : return false;
2974 0 : if (!allow_leading_zeros && length > 1 && has_leading_zero)
2975 : return false;
2976 : *token_end = start;
2977 : return true;
2978 : }
2979 :
2980 0 : static bool ParseNumberToken(const Char* start,
2981 : const Char* end,
2982 : const Char** token_end) {
2983 : // We just grab the number here. We validate the size in DecodeNumber.
2984 : // According to RFC4627, a valid number is: [minus] int [frac] [exp]
2985 0 : if (start == end)
2986 : return false;
2987 0 : Char c = *start;
2988 0 : if ('-' == c)
2989 0 : ++start;
2990 :
2991 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false))
2992 : return false;
2993 0 : if (start == end) {
2994 0 : *token_end = start;
2995 0 : return true;
2996 : }
2997 :
2998 : // Optional fraction part
2999 0 : c = *start;
3000 0 : if ('.' == c) {
3001 0 : ++start;
3002 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
3003 : return false;
3004 0 : if (start == end) {
3005 0 : *token_end = start;
3006 0 : return true;
3007 : }
3008 0 : c = *start;
3009 : }
3010 :
3011 : // Optional exponent part
3012 0 : if ('e' == c || 'E' == c) {
3013 0 : ++start;
3014 0 : if (start == end)
3015 : return false;
3016 0 : c = *start;
3017 0 : if ('-' == c || '+' == c) {
3018 0 : ++start;
3019 0 : if (start == end)
3020 : return false;
3021 : }
3022 0 : if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true))
3023 : return false;
3024 : }
3025 :
3026 0 : *token_end = start;
3027 0 : return true;
3028 : }
3029 :
3030 : static bool ReadHexDigits(const Char* start,
3031 : const Char* end,
3032 : const Char** token_end,
3033 : int digits) {
3034 0 : if (end - start < digits)
3035 : return false;
3036 0 : for (int i = 0; i < digits; ++i) {
3037 0 : Char c = *start++;
3038 0 : if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||
3039 : ('A' <= c && c <= 'F')))
3040 : return false;
3041 : }
3042 : *token_end = start;
3043 : return true;
3044 : }
3045 :
3046 0 : static bool ParseStringToken(const Char* start,
3047 : const Char* end,
3048 : const Char** token_end) {
3049 0 : while (start < end) {
3050 0 : Char c = *start++;
3051 0 : if ('\\' == c) {
3052 0 : if (start == end)
3053 : return false;
3054 0 : c = *start++;
3055 : // Make sure the escaped char is valid.
3056 0 : switch (c) {
3057 : case 'x':
3058 0 : if (!ReadHexDigits(start, end, &start, 2))
3059 : return false;
3060 : break;
3061 : case 'u':
3062 0 : if (!ReadHexDigits(start, end, &start, 4))
3063 : return false;
3064 : break;
3065 : case '\\':
3066 : case '/':
3067 : case 'b':
3068 : case 'f':
3069 : case 'n':
3070 : case 'r':
3071 : case 't':
3072 : case 'v':
3073 : case '"':
3074 : break;
3075 : default:
3076 : return false;
3077 : }
3078 0 : } else if ('"' == c) {
3079 0 : *token_end = start;
3080 0 : return true;
3081 : }
3082 : }
3083 : return false;
3084 : }
3085 :
3086 0 : static bool SkipComment(const Char* start,
3087 : const Char* end,
3088 : const Char** comment_end) {
3089 0 : if (start == end)
3090 : return false;
3091 :
3092 0 : if (*start != '/' || start + 1 >= end)
3093 : return false;
3094 : ++start;
3095 :
3096 0 : if (*start == '/') {
3097 : // Single line comment, read to newline.
3098 0 : for (++start; start < end; ++start) {
3099 0 : if (*start == '\n' || *start == '\r') {
3100 0 : *comment_end = start + 1;
3101 0 : return true;
3102 : }
3103 : }
3104 0 : *comment_end = end;
3105 : // Comment reaches end-of-input, which is fine.
3106 0 : return true;
3107 : }
3108 :
3109 0 : if (*start == '*') {
3110 : Char previous = '\0';
3111 : // Block comment, read until end marker.
3112 0 : for (++start; start < end; previous = *start++) {
3113 0 : if (previous == '*' && *start == '/') {
3114 0 : *comment_end = start + 1;
3115 0 : return true;
3116 : }
3117 : }
3118 : // Block comment must close before end-of-input.
3119 : return false;
3120 : }
3121 :
3122 : return false;
3123 : }
3124 :
3125 : static bool IsSpaceOrNewLine(Char c) {
3126 : // \v = vertial tab; \f = form feed page break.
3127 : return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' ||
3128 0 : c == '\t';
3129 : }
3130 :
3131 0 : static void SkipWhitespaceAndComments(const Char* start,
3132 : const Char* end,
3133 : const Char** whitespace_end) {
3134 0 : while (start < end) {
3135 0 : if (IsSpaceOrNewLine(*start)) {
3136 0 : ++start;
3137 0 : } else if (*start == '/') {
3138 : const Char* comment_end;
3139 0 : if (!SkipComment(start, end, &comment_end))
3140 : break;
3141 0 : start = comment_end;
3142 : } else {
3143 : break;
3144 : }
3145 : }
3146 0 : *whitespace_end = start;
3147 0 : }
3148 :
3149 0 : static Token ParseToken(const Char* start,
3150 : const Char* end,
3151 : const Char** tokenStart,
3152 : const Char** token_end) {
3153 0 : SkipWhitespaceAndComments(start, end, tokenStart);
3154 0 : start = *tokenStart;
3155 :
3156 0 : if (start == end)
3157 : return NoInput;
3158 :
3159 0 : switch (*start) {
3160 : case 'n':
3161 0 : if (ParseConstToken(start, end, token_end, kNullString))
3162 : return NullToken;
3163 : break;
3164 : case 't':
3165 0 : if (ParseConstToken(start, end, token_end, kTrueString))
3166 : return BoolTrue;
3167 : break;
3168 : case 'f':
3169 0 : if (ParseConstToken(start, end, token_end, kFalseString))
3170 : return BoolFalse;
3171 : break;
3172 : case '[':
3173 0 : *token_end = start + 1;
3174 0 : return ArrayBegin;
3175 : case ']':
3176 0 : *token_end = start + 1;
3177 0 : return ArrayEnd;
3178 : case ',':
3179 0 : *token_end = start + 1;
3180 0 : return ListSeparator;
3181 : case '{':
3182 0 : *token_end = start + 1;
3183 0 : return ObjectBegin;
3184 : case '}':
3185 0 : *token_end = start + 1;
3186 0 : return ObjectEnd;
3187 : case ':':
3188 0 : *token_end = start + 1;
3189 0 : return ObjectPairSeparator;
3190 : case '0':
3191 : case '1':
3192 : case '2':
3193 : case '3':
3194 : case '4':
3195 : case '5':
3196 : case '6':
3197 : case '7':
3198 : case '8':
3199 : case '9':
3200 : case '-':
3201 0 : if (ParseNumberToken(start, end, token_end))
3202 : return Number;
3203 : break;
3204 : case '"':
3205 0 : if (ParseStringToken(start + 1, end, token_end))
3206 : return StringLiteral;
3207 : break;
3208 : }
3209 : return InvalidToken;
3210 : }
3211 :
3212 : static int HexToInt(Char c) {
3213 0 : if ('0' <= c && c <= '9')
3214 0 : return c - '0';
3215 0 : if ('A' <= c && c <= 'F')
3216 0 : return c - 'A' + 10;
3217 0 : if ('a' <= c && c <= 'f')
3218 0 : return c - 'a' + 10;
3219 : assert(false); // Unreachable.
3220 : return 0;
3221 : }
3222 :
3223 0 : static bool DecodeString(const Char* start,
3224 : const Char* end,
3225 : std::vector<uint16_t>* output) {
3226 0 : if (start == end)
3227 : return true;
3228 0 : if (start > end)
3229 : return false;
3230 0 : output->reserve(end - start);
3231 0 : while (start < end) {
3232 0 : uint16_t c = *start++;
3233 : // If the |Char| we're dealing with is really a byte, then
3234 : // we have utf8 here, and we need to check for multibyte characters
3235 : // and transcode them to utf16 (either one or two utf16 chars).
3236 0 : if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) {
3237 : // Inspect the leading byte to figure out how long the utf8
3238 : // byte sequence is; while doing this initialize |codepoint|
3239 : // with the first few bits.
3240 : // See table in: https://en.wikipedia.org/wiki/UTF-8
3241 : // byte one is 110x xxxx -> 2 byte utf8 sequence
3242 : // byte one is 1110 xxxx -> 3 byte utf8 sequence
3243 : // byte one is 1111 0xxx -> 4 byte utf8 sequence
3244 : uint32_t codepoint;
3245 : int num_bytes_left;
3246 0 : if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence
3247 : num_bytes_left = 1;
3248 0 : codepoint = c & 0x1f;
3249 0 : } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence
3250 : num_bytes_left = 2;
3251 0 : codepoint = c & 0x0f;
3252 0 : } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence
3253 0 : codepoint = c & 0x07;
3254 : num_bytes_left = 3;
3255 : } else {
3256 0 : return false; // invalid leading byte
3257 : }
3258 :
3259 : // If we have enough bytes in our inpput, decode the remaining ones
3260 : // belonging to this Unicode character into |codepoint|.
3261 0 : if (start + num_bytes_left > end)
3262 : return false;
3263 0 : while (num_bytes_left > 0) {
3264 0 : c = *start++;
3265 0 : --num_bytes_left;
3266 : // Check the next byte is a continuation byte, that is 10xx xxxx.
3267 0 : if ((c & 0xc0) != 0x80)
3268 : return false;
3269 0 : codepoint = (codepoint << 6) | (c & 0x3f);
3270 : }
3271 :
3272 : // Disallow overlong encodings for ascii characters, as these
3273 : // would include " and other characters significant to JSON
3274 : // string termination / control.
3275 0 : if (codepoint < 0x7f)
3276 : return false;
3277 : // Invalid in UTF8, and can't be represented in UTF16 anyway.
3278 0 : if (codepoint > 0x10ffff)
3279 : return false;
3280 :
3281 : // So, now we transcode to UTF16,
3282 : // using the math described at https://en.wikipedia.org/wiki/UTF-16,
3283 : // for either one or two 16 bit characters.
3284 0 : if (codepoint < 0xffff) {
3285 0 : output->push_back(codepoint);
3286 0 : continue;
3287 : }
3288 0 : codepoint -= 0x10000;
3289 0 : output->push_back((codepoint >> 10) + 0xd800); // high surrogate
3290 0 : output->push_back((codepoint & 0x3ff) + 0xdc00); // low surrogate
3291 0 : continue;
3292 : }
3293 0 : if ('\\' != c) {
3294 0 : output->push_back(c);
3295 0 : continue;
3296 : }
3297 0 : if (start == end)
3298 : return false;
3299 0 : c = *start++;
3300 :
3301 0 : if (c == 'x') {
3302 : // \x is not supported.
3303 : return false;
3304 : }
3305 :
3306 0 : switch (c) {
3307 : case '"':
3308 : case '/':
3309 : case '\\':
3310 : break;
3311 : case 'b':
3312 0 : c = '\b';
3313 0 : break;
3314 : case 'f':
3315 0 : c = '\f';
3316 0 : break;
3317 : case 'n':
3318 0 : c = '\n';
3319 0 : break;
3320 : case 'r':
3321 0 : c = '\r';
3322 0 : break;
3323 : case 't':
3324 0 : c = '\t';
3325 0 : break;
3326 : case 'v':
3327 0 : c = '\v';
3328 0 : break;
3329 : case 'u':
3330 0 : c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) +
3331 0 : (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3));
3332 0 : start += 4;
3333 0 : break;
3334 : default:
3335 : return false;
3336 : }
3337 0 : output->push_back(c);
3338 : }
3339 : return true;
3340 : }
3341 :
3342 0 : void ParseValue(const Char* start,
3343 : const Char* end,
3344 : const Char** value_token_end,
3345 : int depth) {
3346 0 : if (depth > kStackLimit) {
3347 : HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start);
3348 0 : return;
3349 : }
3350 : const Char* token_start;
3351 : const Char* token_end;
3352 0 : Token token = ParseToken(start, end, &token_start, &token_end);
3353 0 : switch (token) {
3354 : case NoInput:
3355 0 : HandleError(Error::JSON_PARSER_NO_INPUT, token_start);
3356 : return;
3357 : case InvalidToken:
3358 0 : HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start);
3359 : return;
3360 : case NullToken:
3361 0 : handler_->HandleNull();
3362 0 : break;
3363 : case BoolTrue:
3364 0 : handler_->HandleBool(true);
3365 0 : break;
3366 : case BoolFalse:
3367 0 : handler_->HandleBool(false);
3368 0 : break;
3369 : case Number: {
3370 : double value;
3371 0 : if (!CharsToDouble(token_start, token_end - token_start, &value)) {
3372 0 : HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start);
3373 0 : return;
3374 : }
3375 0 : if (value >= std::numeric_limits<int32_t>::min() &&
3376 : value <= std::numeric_limits<int32_t>::max() &&
3377 : static_cast<int32_t>(value) == value)
3378 0 : handler_->HandleInt32(static_cast<int32_t>(value));
3379 : else
3380 0 : handler_->HandleDouble(value);
3381 0 : break;
3382 : }
3383 : case StringLiteral: {
3384 : std::vector<uint16_t> value;
3385 0 : bool ok = DecodeString(token_start + 1, token_end - 1, &value);
3386 0 : if (!ok) {
3387 0 : HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
3388 : return;
3389 : }
3390 0 : handler_->HandleString16(span<uint16_t>(value.data(), value.size()));
3391 : break;
3392 : }
3393 : case ArrayBegin: {
3394 0 : handler_->HandleArrayBegin();
3395 0 : start = token_end;
3396 0 : token = ParseToken(start, end, &token_start, &token_end);
3397 0 : while (token != ArrayEnd) {
3398 0 : ParseValue(start, end, &token_end, depth + 1);
3399 0 : if (error_)
3400 : return;
3401 :
3402 : // After a list value, we expect a comma or the end of the list.
3403 0 : start = token_end;
3404 0 : token = ParseToken(start, end, &token_start, &token_end);
3405 0 : if (token == ListSeparator) {
3406 0 : start = token_end;
3407 0 : token = ParseToken(start, end, &token_start, &token_end);
3408 0 : if (token == ArrayEnd) {
3409 0 : HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start);
3410 : return;
3411 : }
3412 0 : } else if (token != ArrayEnd) {
3413 : // Unexpected value after list value. Bail out.
3414 0 : HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED,
3415 : token_start);
3416 : return;
3417 : }
3418 : }
3419 0 : handler_->HandleArrayEnd();
3420 0 : break;
3421 : }
3422 : case ObjectBegin: {
3423 0 : handler_->HandleMapBegin();
3424 0 : start = token_end;
3425 0 : token = ParseToken(start, end, &token_start, &token_end);
3426 0 : while (token != ObjectEnd) {
3427 0 : if (token != StringLiteral) {
3428 0 : HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED,
3429 : token_start);
3430 0 : return;
3431 : }
3432 : std::vector<uint16_t> key;
3433 0 : if (!DecodeString(token_start + 1, token_end - 1, &key)) {
3434 0 : HandleError(Error::JSON_PARSER_INVALID_STRING, token_start);
3435 : return;
3436 : }
3437 0 : handler_->HandleString16(span<uint16_t>(key.data(), key.size()));
3438 0 : start = token_end;
3439 :
3440 0 : token = ParseToken(start, end, &token_start, &token_end);
3441 0 : if (token != ObjectPairSeparator) {
3442 0 : HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start);
3443 : return;
3444 : }
3445 0 : start = token_end;
3446 :
3447 0 : ParseValue(start, end, &token_end, depth + 1);
3448 0 : if (error_)
3449 : return;
3450 0 : start = token_end;
3451 :
3452 : // After a key/value pair, we expect a comma or the end of the
3453 : // object.
3454 0 : token = ParseToken(start, end, &token_start, &token_end);
3455 0 : if (token == ListSeparator) {
3456 0 : start = token_end;
3457 0 : token = ParseToken(start, end, &token_start, &token_end);
3458 0 : if (token == ObjectEnd) {
3459 0 : HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start);
3460 : return;
3461 : }
3462 0 : } else if (token != ObjectEnd) {
3463 : // Unexpected value after last object value. Bail out.
3464 0 : HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED,
3465 : token_start);
3466 : return;
3467 : }
3468 : }
3469 0 : handler_->HandleMapEnd();
3470 0 : break;
3471 : }
3472 :
3473 : default:
3474 : // We got a token that's not a value.
3475 0 : HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start);
3476 : return;
3477 : }
3478 :
3479 0 : SkipWhitespaceAndComments(token_end, end, value_token_end);
3480 : }
3481 :
3482 : void HandleError(Error error, const Char* pos) {
3483 : assert(error != Error::OK);
3484 0 : if (!error_) {
3485 0 : handler_->HandleError(Status{error, pos - start_pos_});
3486 0 : error_ = true;
3487 : }
3488 : }
3489 :
3490 : const Char* start_pos_ = nullptr;
3491 : bool error_ = false;
3492 : const Platform* platform_;
3493 : StreamingParserHandler* handler_;
3494 : };
3495 : } // namespace
3496 :
3497 0 : void ParseJSON(const Platform* platform,
3498 : span<uint8_t> chars,
3499 : StreamingParserHandler* handler) {
3500 : JsonParser<uint8_t> parser(platform, handler);
3501 0 : parser.Parse(chars.data(), chars.size());
3502 0 : }
3503 :
3504 0 : void ParseJSON(const Platform* platform,
3505 : span<uint16_t> chars,
3506 : StreamingParserHandler* handler) {
3507 : JsonParser<uint16_t> parser(platform, handler);
3508 0 : parser.Parse(chars.data(), chars.size());
3509 0 : }
3510 : } // namespace json
3511 :
3512 : } // namespace v8_inspector
3513 : } // namespace protocol
3514 :
|