Bug Summary

File:out/Release/obj/gen/src/node/inspector/protocol/Protocol.h
Warning:line 235, column 16
Potential leak of memory pointed to by 'value._M_t._M_t._M_head_impl'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Protocol.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D NODE_ARCH="x64" -D NODE_PLATFORM="linux" -D NODE_WANT_INTERNALS=1 -D V8_DEPRECATION_WARNINGS=1 -D NODE_OPENSSL_SYSTEM_CERT_PATH="" -D NODE_USE_NODE_CODE_CACHE=1 -D HAVE_INSPECTOR=1 -D NODE_ENABLE_LARGE_CODE_PAGES=1 -D __POSIX__ -D NODE_USE_V8_PLATFORM=1 -D NODE_HAVE_I18N_SUPPORT=1 -D HAVE_OPENSSL=1 -D OPENSSL_API_COMPAT=0x10100000L -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -D _LARGEFILE_SOURCE -D _FILE_OFFSET_BITS=64 -D _POSIX_C_SOURCE=200112 -D NGHTTP2_STATICLIB -D NDEBUG -D OPENSSL_USE_NODELETE -D L_ENDIAN -D OPENSSL_BUILDING_OPENSSL -D AES_ASM -D BSAES_ASM -D CMLL_ASM -D ECP_NISTZ256_ASM -D GHASH_ASM -D KECCAK1600_ASM -D MD5_ASM -D OPENSSL_BN_ASM_GF2m -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D OPENSSL_CPUID_OBJ -D OPENSSL_IA32_SSE2 -D PADLOCK_ASM -D POLY1305_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D VPAES_ASM -D WHIRLPOOL_ASM -D X25519_ASM -D OPENSSL_PIC -D NGTCP2_STATICLIB -D NGHTTP3_STATICLIB -I ../src -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/src -I ../deps/googletest/include -I ../deps/histogram/src -I ../deps/uvwasi/include -I ../deps/v8/include -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/zlib -I ../deps/llhttp/include -I ../deps/cares/include -I ../deps/uv/include -I ../deps/nghttp2/lib/includes -I ../deps/brotli/c/include -I ../deps/openssl/openssl/include -I ../deps/openssl/openssl/crypto/include -I ../deps/openssl/config/archs/linux-x86_64/asm/include -I ../deps/openssl/config/archs/linux-x86_64/asm -I ../deps/ngtcp2 -I ../deps/ngtcp2/ngtcp2/lib/includes -I ../deps/ngtcp2/ngtcp2/crypto/includes -I ../deps/ngtcp2/nghttp3/lib/includes -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-unused-parameter -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ /home/maurizio/node-v18.6.0/out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp

/home/maurizio/node-v18.6.0/out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp

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

/home/maurizio/node-v18.6.0/out/Release/obj/gen/src/node/inspector/protocol/Protocol.h

1// This file is generated by ErrorSupport_h.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#ifndef node_inspector_protocol_ErrorSupport_h
8#define node_inspector_protocol_ErrorSupport_h
9
10#include "src/node/inspector/protocol/Forward.h"
11
12namespace node {
13namespace inspector {
14namespace protocol {
15
16class ErrorSupport {
17public:
18 ErrorSupport();
19 ~ErrorSupport();
20
21 void push();
22 void setName(const char*);
23 void setName(const String&);
24 void pop();
25 void addError(const char*);
26 void addError(const String&);
27 bool hasErrors();
28 String errors();
29
30private:
31 std::vector<String> m_path;
32 std::vector<String> m_errors;
33};
34
35} // namespace node
36} // namespace inspector
37} // namespace protocol
38
39#endif // !defined(node_inspector_protocol_ErrorSupport_h)
40
41
42// This file is generated by Values_h.template.
43
44// Copyright 2016 The Chromium Authors. All rights reserved.
45// Use of this source code is governed by a BSD-style license that can be
46// found in the LICENSE file.
47
48#ifndef node_inspector_protocol_Values_h
49#define node_inspector_protocol_Values_h
50
51//#include "Allocator.h"
52//#include "Forward.h"
53
54namespace node {
55namespace inspector {
56namespace protocol {
57
58class ListValue;
59class DictionaryValue;
60class Value;
61
62class Value : public Serializable {
63 PROTOCOL_DISALLOW_COPY(Value)private: Value(const Value&) = delete; Value& operator
=(const Value&) = delete
;
64public:
65 virtual ~Value() override { }
66
67 static std::unique_ptr<Value> null()
68 {
69 return std::unique_ptr<Value>(new Value());
70 }
71
72 static std::unique_ptr<Value> parseBinary(const uint8_t* data, size_t size);
73
74 enum ValueType {
75 TypeNull = 0,
76 TypeBoolean,
77 TypeInteger,
78 TypeDouble,
79 TypeString,
80 TypeBinary,
81 TypeObject,
82 TypeArray,
83 TypeSerialized,
84 TypeImported
85 };
86
87 ValueType type() const { return m_type; }
88
89 bool isNull() const { return m_type == TypeNull; }
90
91 virtual bool asBoolean(bool* output) const;
92 virtual bool asDouble(double* output) const;
93 virtual bool asInteger(int* output) const;
94 virtual bool asString(String* output) const;
95 virtual bool asBinary(Binary* output) const;
96
97 virtual void writeJSON(StringBuilder* output) const;
98 virtual void writeBinary(std::vector<uint8_t>* bytes) const;
99 virtual std::unique_ptr<Value> clone() const;
100 String toJSONString() const;
101 String serializeToJSON() override;
102 std::vector<uint8_t> serializeToBinary() override;
103
104protected:
105 Value() : m_type(TypeNull) { }
106 explicit Value(ValueType type) : m_type(type) { }
107
108private:
109 friend class DictionaryValue;
110 friend class ListValue;
111
112 ValueType m_type;
113};
114
115class FundamentalValue : public Value {
116public:
117 static std::unique_ptr<FundamentalValue> create(bool value)
118 {
119 return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
120 }
121
122 static std::unique_ptr<FundamentalValue> create(int value)
123 {
124 return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
125 }
126
127 static std::unique_ptr<FundamentalValue> create(double value)
128 {
129 return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
130 }
131
132 bool asBoolean(bool* output) const override;
133 bool asDouble(double* output) const override;
134 bool asInteger(int* output) const override;
135 void writeJSON(StringBuilder* output) const override;
136 void writeBinary(std::vector<uint8_t>* bytes) const override;
137 std::unique_ptr<Value> clone() const override;
138
139private:
140 explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { }
141 explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { }
142 explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { }
143
144 union {
145 bool m_boolValue;
146 double m_doubleValue;
147 int m_integerValue;
148 };
149};
150
151class StringValue : public Value {
152public:
153 static std::unique_ptr<StringValue> create(const String& value)
154 {
155 return std::unique_ptr<StringValue>(new StringValue(value));
156 }
157
158 static std::unique_ptr<StringValue> create(const char* value)
159 {
160 return std::unique_ptr<StringValue>(new StringValue(value));
161 }
162
163 bool asString(String* output) const override;
164 void writeJSON(StringBuilder* output) const override;
165 void writeBinary(std::vector<uint8_t>* bytes) const override;
166 std::unique_ptr<Value> clone() const override;
167
168private:
169 explicit StringValue(const String& value) : Value(TypeString), m_stringValue(value) { }
170 explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { }
171
172 String m_stringValue;
173};
174
175class BinaryValue : public Value {
176public:
177 static std::unique_ptr<BinaryValue> create(const Binary& value)
178 {
179 return std::unique_ptr<BinaryValue>(new BinaryValue(value));
180 }
181
182 bool asBinary(Binary* output) const override;
183 void writeJSON(StringBuilder* output) const override;
184 void writeBinary(std::vector<uint8_t>* bytes) const override;
185 std::unique_ptr<Value> clone() const override;
186
187private:
188 explicit BinaryValue(const Binary& value) : Value(TypeBinary), m_binaryValue(value) { }
189
190 Binary m_binaryValue;
191};
192
193class SerializedValue : public Value {
194public:
195 static std::unique_ptr<SerializedValue> fromJSON(const String& value)
196 {
197 return std::unique_ptr<SerializedValue>(new SerializedValue(value));
198 }
199
200 static std::unique_ptr<SerializedValue> fromBinary(std::vector<uint8_t> value)
201 {
202 return std::unique_ptr<SerializedValue>(new SerializedValue(std::move(value)));
203 }
204
205 void writeJSON(StringBuilder* output) const override;
206 void writeBinary(std::vector<uint8_t>* bytes) const override;
207 std::unique_ptr<Value> clone() const override;
208
209private:
210 explicit SerializedValue(const String& json) : Value(TypeSerialized), m_serializedJSON(json) { }
211 explicit SerializedValue(std::vector<uint8_t> binary) : Value(TypeSerialized), m_serializedBinary(std::move(binary)) { }
212 SerializedValue(const String& json, const std::vector<uint8_t>& binary)
213 : Value(TypeSerialized), m_serializedJSON(json), m_serializedBinary(binary) { }
214 String m_serializedJSON;
215 std::vector<uint8_t> m_serializedBinary;
216};
217
218class DictionaryValue : public Value {
219public:
220 using Entry = std::pair<String, Value*>;
221 static std::unique_ptr<DictionaryValue> create()
222 {
223 return std::unique_ptr<DictionaryValue>(new DictionaryValue());
3
Memory is allocated
224 }
225
226 static DictionaryValue* cast(Value* value)
227 {
228 if (!value || value->type() != TypeObject)
229 return nullptr;
230 return static_cast<DictionaryValue*>(value);
231 }
232
233 static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value)
234 {
235 return std::unique_ptr<DictionaryValue>(DictionaryValue::cast(value.release()));
9
Potential leak of memory pointed to by 'value._M_t._M_t._M_head_impl'
236 }
237
238 void writeJSON(StringBuilder* output) const override;
239 void writeBinary(std::vector<uint8_t>* bytes) const override;
240 std::unique_ptr<Value> clone() const override;
241
242 size_t size() const { return m_data.size(); }
243
244 void setBoolean(const String& name, bool);
245 void setInteger(const String& name, int);
246 void setDouble(const String& name, double);
247 void setString(const String& name, const String&);
248 void setValue(const String& name, std::unique_ptr<Value>);
249 void setObject(const String& name, std::unique_ptr<DictionaryValue>);
250 void setArray(const String& name, std::unique_ptr<ListValue>);
251
252 bool getBoolean(const String& name, bool* output) const;
253 bool getInteger(const String& name, int* output) const;
254 bool getDouble(const String& name, double* output) const;
255 bool getString(const String& name, String* output) const;
256
257 DictionaryValue* getObject(const String& name) const;
258 ListValue* getArray(const String& name) const;
259 Value* get(const String& name) const;
260 Entry at(size_t index) const;
261
262 bool booleanProperty(const String& name, bool defaultValue) const;
263 int integerProperty(const String& name, int defaultValue) const;
264 double doubleProperty(const String& name, double defaultValue) const;
265 void remove(const String& name);
266
267 ~DictionaryValue() override;
268
269private:
270 DictionaryValue();
271 template<typename T>
272 void set(const String& key, std::unique_ptr<T>& value)
273 {
274 DCHECK(value);
275 bool isNew = m_data.find(key) == m_data.end();
276 m_data[key] = std::move(value);
277 if (isNew)
278 m_order.push_back(key);
279 }
280
281 using Dictionary = std::unordered_map<String, std::unique_ptr<Value>>;
282 Dictionary m_data;
283 std::vector<String> m_order;
284};
285
286class ListValue : public Value {
287public:
288 static std::unique_ptr<ListValue> create()
289 {
290 return std::unique_ptr<ListValue>(new ListValue());
291 }
292
293 static ListValue* cast(Value* value)
294 {
295 if (!value || value->type() != TypeArray)
296 return nullptr;
297 return static_cast<ListValue*>(value);
298 }
299
300 static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value)
301 {
302 return std::unique_ptr<ListValue>(ListValue::cast(value.release()));
303 }
304
305 ~ListValue() override;
306
307 void writeJSON(StringBuilder* output) const override;
308 void writeBinary(std::vector<uint8_t>* bytes) const override;
309 std::unique_ptr<Value> clone() const override;
310
311 void pushValue(std::unique_ptr<Value>);
312
313 Value* at(size_t index);
314 size_t size() const { return m_data.size(); }
315
316private:
317 ListValue();
318 std::vector<std::unique_ptr<Value>> m_data;
319};
320
321void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst);
322void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst);
323
324} // namespace node
325} // namespace inspector
326} // namespace protocol
327
328#endif // node_inspector_protocol_Values_h
329
330
331// This file is generated by Object_h.template.
332
333// Copyright 2016 The Chromium Authors. All rights reserved.
334// Use of this source code is governed by a BSD-style license that can be
335// found in the LICENSE file.
336
337#ifndef node_inspector_protocol_Object_h
338#define node_inspector_protocol_Object_h
339
340//#include "ErrorSupport.h"
341//#include "Forward.h"
342//#include "Values.h"
343
344namespace node {
345namespace inspector {
346namespace protocol {
347
348class Object {
349public:
350 static std::unique_ptr<Object> fromValue(protocol::Value*, ErrorSupport*);
351 explicit Object(std::unique_ptr<protocol::DictionaryValue>);
352 ~Object();
353
354 std::unique_ptr<protocol::DictionaryValue> toValue() const;
355 std::unique_ptr<Object> clone() const;
356private:
357 std::unique_ptr<protocol::DictionaryValue> m_object;
358};
359
360} // namespace node
361} // namespace inspector
362} // namespace protocol
363
364#endif // !defined(node_inspector_protocol_Object_h)
365
366
367// This file is generated by ValueConversions_h.template.
368
369// Copyright 2016 The Chromium Authors. All rights reserved.
370// Use of this source code is governed by a BSD-style license that can be
371// found in the LICENSE file.
372
373#ifndef node_inspector_protocol_ValueConversions_h
374#define node_inspector_protocol_ValueConversions_h
375
376//#include "ErrorSupport.h"
377//#include "Forward.h"
378//#include "Values.h"
379
380namespace node {
381namespace inspector {
382namespace protocol {
383
384template<typename T>
385struct ValueConversions {
386 static std::unique_ptr<T> fromValue(protocol::Value* value, ErrorSupport* errors)
387 {
388 return T::fromValue(value, errors);
389 }
390
391 static std::unique_ptr<protocol::Value> toValue(T* value)
392 {
393 return value->toValue();
394 }
395
396 static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<T>& value)
397 {
398 return value->toValue();
399 }
400};
401
402template<>
403struct ValueConversions<bool> {
404 static bool fromValue(protocol::Value* value, ErrorSupport* errors)
405 {
406 bool result = false;
407 bool success = value ? value->asBoolean(&result) : false;
408 if (!success)
409 errors->addError("boolean value expected");
410 return result;
411 }
412
413 static std::unique_ptr<protocol::Value> toValue(bool value)
414 {
415 return FundamentalValue::create(value);
416 }
417};
418
419template<>
420struct ValueConversions<int> {
421 static int fromValue(protocol::Value* value, ErrorSupport* errors)
422 {
423 int result = 0;
424 bool success = value ? value->asInteger(&result) : false;
425 if (!success)
426 errors->addError("integer value expected");
427 return result;
428 }
429
430 static std::unique_ptr<protocol::Value> toValue(int value)
431 {
432 return FundamentalValue::create(value);
433 }
434};
435
436template<>
437struct ValueConversions<double> {
438 static double fromValue(protocol::Value* value, ErrorSupport* errors)
439 {
440 double result = 0;
441 bool success = value ? value->asDouble(&result) : false;
442 if (!success)
443 errors->addError("double value expected");
444 return result;
445 }
446
447 static std::unique_ptr<protocol::Value> toValue(double value)
448 {
449 return FundamentalValue::create(value);
450 }
451};
452
453template<>
454struct ValueConversions<String> {
455 static String fromValue(protocol::Value* value, ErrorSupport* errors)
456 {
457 String result;
458 bool success = value ? value->asString(&result) : false;
459 if (!success)
460 errors->addError("string value expected");
461 return result;
462 }
463
464 static std::unique_ptr<protocol::Value> toValue(const String& value)
465 {
466 return StringValue::create(value);
467 }
468};
469
470template<>
471struct ValueConversions<Binary> {
472 static Binary fromValue(protocol::Value* value, ErrorSupport* errors)
473 {
474 if (!value ||
475 (value->type() != Value::TypeBinary && value->type() != Value::TypeString)) {
476 errors->addError("Either string base64 or binary value expected");
477 return Binary();
478 }
479 Binary binary;
480 if (value->asBinary(&binary))
481 return binary;
482 String result;
483 value->asString(&result);
484 bool success;
485 Binary out = Binary::fromBase64(result, &success);
486 if (!success)
487 errors->addError("base64 decoding error");
488 return out;
489 }
490
491 static std::unique_ptr<protocol::Value> toValue(const Binary& value)
492 {
493 return BinaryValue::create(value);
494 }
495};
496
497template<>
498struct ValueConversions<Value> {
499 static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors)
500 {
501 bool success = !!value;
502 if (!success) {
503 errors->addError("value expected");
504 return nullptr;
505 }
506 return value->clone();
507 }
508
509 static std::unique_ptr<protocol::Value> toValue(Value* value)
510 {
511 return value->clone();
512 }
513
514 static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<Value>& value)
515 {
516 return value->clone();
517 }
518};
519
520template<>
521struct ValueConversions<DictionaryValue> {
522 static std::unique_ptr<DictionaryValue> fromValue(protocol::Value* value, ErrorSupport* errors)
523 {
524 bool success = value && value->type() == protocol::Value::TypeObject;
525 if (!success)
526 errors->addError("object expected");
527 return DictionaryValue::cast(value->clone());
528 }
529
530 static std::unique_ptr<protocol::Value> toValue(DictionaryValue* value)
531 {
532 return value->clone();
533 }
534
535 static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<DictionaryValue>& value)
536 {
537 return value->clone();
538 }
539};
540
541template<>
542struct ValueConversions<ListValue> {
543 static std::unique_ptr<ListValue> fromValue(protocol::Value* value, ErrorSupport* errors)
544 {
545 bool success = value && value->type() == protocol::Value::TypeArray;
546 if (!success)
547 errors->addError("list expected");
548 return ListValue::cast(value->clone());
549 }
550
551 static std::unique_ptr<protocol::Value> toValue(ListValue* value)
552 {
553 return value->clone();
554 }
555
556 static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<ListValue>& value)
557 {
558 return value->clone();
559 }
560};
561
562} // namespace node
563} // namespace inspector
564} // namespace protocol
565
566#endif // !defined(node_inspector_protocol_ValueConversions_h)
567
568
569// This file is generated by Maybe_h.template.
570
571// Copyright 2016 The Chromium Authors. All rights reserved.
572// Use of this source code is governed by a BSD-style license that can be
573// found in the LICENSE file.
574
575#ifndef node_inspector_protocol_Maybe_h
576#define node_inspector_protocol_Maybe_h
577
578// This macro allows to test for the version of the GNU C++ compiler.
579// Note that this also applies to compilers that masquerade as GCC,
580// for example clang and the Intel C++ compiler for Linux.
581// Use like:
582// #if IP_GNUC_PREREQ(4, 3, 1)
583// ...
584// #endif
585#if defined(__GNUC__4) && defined(__GNUC_MINOR__2) && defined(__GNUC_PATCHLEVEL__1)
586#define IP_GNUC_PREREQ(major, minor, patchlevel) \
587 ((__GNUC__4 * 10000 + __GNUC_MINOR__2 * 100 + __GNUC_PATCHLEVEL__1) >= \
588 ((major)*10000 + (minor)*100 + (patchlevel)))
589#elif defined(__GNUC__4) && defined(__GNUC_MINOR__2)
590#define IP_GNUC_PREREQ(major, minor, patchlevel) \
591 ((__GNUC__4 * 10000 + __GNUC_MINOR__2 * 100) >= \
592 ((major)*10000 + (minor)*100 + (patchlevel)))
593#else
594#define IP_GNUC_PREREQ(major, minor, patchlevel) 0
595#endif
596
597#if defined(__mips64)
598#define IP_TARGET_ARCH_MIPS64 1
599#elif defined(__MIPSEB__) || defined(__MIPSEL__)
600#define IP_TARGET_ARCH_MIPS 1
601#endif
602
603// Allowing the use of noexcept by removing the keyword on older compilers that
604// do not support adding noexcept to default members.
605#if ((IP_GNUC_PREREQ(4, 9, 0) && !defined(IP_TARGET_ARCH_MIPS) && \
606 !defined(IP_TARGET_ARCH_MIPS64)) || \
607 (defined(__clang__1) && __cplusplus201703L > 201300L))
608#define IP_NOEXCEPT noexcept
609#else
610#define IP_NOEXCEPT
611#endif
612
613//#include "Forward.h"
614
615namespace node {
616namespace inspector {
617namespace protocol {
618
619template<typename T>
620class Maybe {
621public:
622 Maybe() : m_value() { }
623 Maybe(std::unique_ptr<T> value) : m_value(std::move(value)) { }
624 Maybe(Maybe&& other) IP_NOEXCEPT : m_value(std::move(other.m_value)) {}
625 void operator=(std::unique_ptr<T> value) { m_value = std::move(value); }
626 T* fromJust() const { DCHECK(m_value); return m_value.get(); }
627 T* fromMaybe(T* defaultValue) const { return m_value ? m_value.get() : defaultValue; }
628 bool isJust() const { return !!m_value; }
629 std::unique_ptr<T> takeJust() { DCHECK(m_value); return std::move(m_value); }
630private:
631 std::unique_ptr<T> m_value;
632};
633
634template<typename T>
635class MaybeBase {
636public:
637 MaybeBase() : m_isJust(false) { }
638 MaybeBase(T value) : m_isJust(true), m_value(value) { }
639 MaybeBase(MaybeBase&& other) IP_NOEXCEPT
640 : m_isJust(other.m_isJust),
641 m_value(std::move(other.m_value)) {}
642 void operator=(T value) { m_value = value; m_isJust = true; }
643 T fromJust() const { DCHECK(m_isJust); return m_value; }
644 T fromMaybe(const T& defaultValue) const { return m_isJust ? m_value : defaultValue; }
645 bool isJust() const { return m_isJust; }
646 T takeJust() { DCHECK(m_isJust); return m_value; }
647
648protected:
649 bool m_isJust;
650 T m_value;
651};
652
653template<>
654class Maybe<bool> : public MaybeBase<bool> {
655public:
656 Maybe() { m_value = false; }
657 Maybe(bool value) : MaybeBase(value) { }
658 Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {}
659 using MaybeBase::operator=;
660};
661
662template<>
663class Maybe<int> : public MaybeBase<int> {
664public:
665 Maybe() { m_value = 0; }
666 Maybe(int value) : MaybeBase(value) { }
667 Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {}
668 using MaybeBase::operator=;
669};
670
671template<>
672class Maybe<double> : public MaybeBase<double> {
673public:
674 Maybe() { m_value = 0; }
675 Maybe(double value) : MaybeBase(value) { }
676 Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {}
677 using MaybeBase::operator=;
678};
679
680template<>
681class Maybe<String> : public MaybeBase<String> {
682public:
683 Maybe() { }
684 Maybe(const String& value) : MaybeBase(value) { }
685 Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {}
686 using MaybeBase::operator=;
687};
688
689template<>
690class Maybe<Binary> : public MaybeBase<Binary> {
691public:
692 Maybe() { }
693 Maybe(Binary value) : MaybeBase(value) { }
694 Maybe(Maybe&& other) IP_NOEXCEPT : MaybeBase(std::move(other)) {}
695 using MaybeBase::operator=;
696};
697
698} // namespace node
699} // namespace inspector
700} // namespace protocol
701
702#undef IP_GNUC_PREREQ
703#undef IP_TARGET_ARCH_MIPS64
704#undef IP_TARGET_ARCH_MIPS
705#undef IP_NOEXCEPT
706
707#endif // !defined(node_inspector_protocol_Maybe_h)
708
709
710// This file is generated by Array_h.template.
711
712// Copyright 2016 The Chromium Authors. All rights reserved.
713// Use of this source code is governed by a BSD-style license that can be
714// found in the LICENSE file.
715
716#ifndef node_inspector_protocol_Array_h
717#define node_inspector_protocol_Array_h
718
719//#include "ErrorSupport.h"
720//#include "Forward.h"
721//#include "ValueConversions.h"
722//#include "Values.h"
723
724namespace node {
725namespace inspector {
726namespace protocol {
727
728template<typename T>
729class Array {
730public:
731 static std::unique_ptr<Array<T>> create()
732 {
733 return std::unique_ptr<Array<T>>(new Array<T>());
734 }
735
736 static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors)
737 {
738 protocol::ListValue* array = ListValue::cast(value);
739 if (!array) {
740 errors->addError("array expected");
741 return nullptr;
742 }
743 std::unique_ptr<Array<T>> result(new Array<T>());
744 errors->push();
745 for (size_t i = 0; i < array->size(); ++i) {
746 errors->setName(StringUtil::fromInteger(i));
747 std::unique_ptr<T> item = ValueConversions<T>::fromValue(array->at(i), errors);
748 result->m_vector.push_back(std::move(item));
749 }
750 errors->pop();
751 if (errors->hasErrors())
752 return nullptr;
753 return result;
754 }
755
756 void addItem(std::unique_ptr<T> value)
757 {
758 m_vector.push_back(std::move(value));
759 }
760
761 size_t length()
762 {
763 return m_vector.size();
764 }
765
766 T* get(size_t index)
767 {
768 return m_vector[index].get();
769 }
770
771 std::unique_ptr<protocol::ListValue> toValue()
772 {
773 std::unique_ptr<protocol::ListValue> result = ListValue::create();
774 for (auto& item : m_vector)
775 result->pushValue(ValueConversions<T>::toValue(item));
776 return result;
777 }
778
779private:
780 std::vector<std::unique_ptr<T>> m_vector;
781};
782
783template<typename T>
784class ArrayBase {
785public:
786 static std::unique_ptr<Array<T>> create()
787 {
788 return std::unique_ptr<Array<T>>(new Array<T>());
789 }
790
791 static std::unique_ptr<Array<T>> fromValue(protocol::Value* value, ErrorSupport* errors)
792 {
793 protocol::ListValue* array = ListValue::cast(value);
794 if (!array) {
795 errors->addError("array expected");
796 return nullptr;
797 }
798 errors->push();
799 std::unique_ptr<Array<T>> result(new Array<T>());
800 for (size_t i = 0; i < array->size(); ++i) {
801 errors->setName(StringUtil::fromInteger(i));
802 T item = ValueConversions<T>::fromValue(array->at(i), errors);
803 result->m_vector.push_back(item);
804 }
805 errors->pop();
806 if (errors->hasErrors())
807 return nullptr;
808 return result;
809 }
810
811 void addItem(const T& value)
812 {
813 m_vector.push_back(value);
814 }
815
816 size_t length()
817 {
818 return m_vector.size();
819 }
820
821 T get(size_t index)
822 {
823 return m_vector[index];
824 }
825
826 std::unique_ptr<protocol::ListValue> toValue()
827 {
828 std::unique_ptr<protocol::ListValue> result = ListValue::create();
829 for (auto& item : m_vector)
830 result->pushValue(ValueConversions<T>::toValue(item));
831 return result;
832 }
833
834private:
835 std::vector<T> m_vector;
836};
837
838template<> class Array<String> : public ArrayBase<String> {};
839template<> class Array<int> : public ArrayBase<int> {};
840template<> class Array<double> : public ArrayBase<double> {};
841template<> class Array<bool> : public ArrayBase<bool> {};
842
843} // namespace node
844} // namespace inspector
845} // namespace protocol
846
847#endif // !defined(node_inspector_protocol_Array_h)
848
849
850// This file is generated by DispatcherBase_h.template.
851
852// Copyright 2016 The Chromium Authors. All rights reserved.
853// Use of this source code is governed by a BSD-style license that can be
854// found in the LICENSE file.
855
856#ifndef node_inspector_protocol_DispatcherBase_h
857#define node_inspector_protocol_DispatcherBase_h
858
859//#include "Forward.h"
860//#include "ErrorSupport.h"
861//#include "Values.h"
862
863namespace node {
864namespace inspector {
865namespace protocol {
866
867class WeakPtr;
868
869class DispatchResponse {
870public:
871 enum Status {
872 kSuccess = 0,
873 kError = 1,
874 kFallThrough = 2,
875 };
876
877 enum ErrorCode {
878 kParseError = -32700,
879 kInvalidRequest = -32600,
880 kMethodNotFound = -32601,
881 kInvalidParams = -32602,
882 kInternalError = -32603,
883 kServerError = -32000,
884 };
885
886 Status status() const { return m_status; }
887 const String& errorMessage() const { return m_errorMessage; }
888 ErrorCode errorCode() const { return m_errorCode; }
889 bool isSuccess() const { return m_status == kSuccess; }
890
891 static DispatchResponse OK();
892 static DispatchResponse Error(const String&);
893 static DispatchResponse InternalError();
894 static DispatchResponse InvalidParams(const String&);
895 static DispatchResponse FallThrough();
896
897private:
898 Status m_status;
899 String m_errorMessage;
900 ErrorCode m_errorCode;
901};
902
903class DispatcherBase {
904 PROTOCOL_DISALLOW_COPY(DispatcherBase)private: DispatcherBase(const DispatcherBase&) = delete; DispatcherBase
& operator=(const DispatcherBase&) = delete
;
905public:
906 static const char kInvalidParamsString[];
907 class WeakPtr {
908 public:
909 explicit WeakPtr(DispatcherBase*);
910 ~WeakPtr();
911 DispatcherBase* get() { return m_dispatcher; }
912 void dispose() { m_dispatcher = nullptr; }
913
914 private:
915 DispatcherBase* m_dispatcher;
916 };
917
918 class Callback {
919 public:
920 Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message);
921 virtual ~Callback();
922 void dispose();
923
924 protected:
925 void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response);
926 void fallThroughIfActive();
927
928 private:
929 std::unique_ptr<WeakPtr> m_backendImpl;
930 int m_callId;
931 String m_method;
932 ProtocolMessage m_message;
933 };
934
935 explicit DispatcherBase(FrontendChannel*);
936 virtual ~DispatcherBase();
937
938 virtual bool canDispatch(const String& method) = 0;
939 virtual void dispatch(int callId, const String& method, const ProtocolMessage& rawMessage, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0;
940 FrontendChannel* channel() { return m_frontendChannel; }
941
942 void sendResponse(int callId, const DispatchResponse&, std::unique_ptr<protocol::DictionaryValue> result);
943 void sendResponse(int callId, const DispatchResponse&);
944
945 void reportProtocolError(int callId, DispatchResponse::ErrorCode, const String& errorMessage, ErrorSupport* errors);
946 void clearFrontend();
947
948 std::unique_ptr<WeakPtr> weakPtr();
949
950private:
951 FrontendChannel* m_frontendChannel;
952 std::unordered_set<WeakPtr*> m_weakPtrs;
953};
954
955class UberDispatcher {
956 PROTOCOL_DISALLOW_COPY(UberDispatcher)private: UberDispatcher(const UberDispatcher&) = delete; UberDispatcher
& operator=(const UberDispatcher&) = delete
;
957public:
958 explicit UberDispatcher(FrontendChannel*);
959 void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
960 void setupRedirects(const std::unordered_map<String, String>&);
961 bool parseCommand(Value* message, int* callId, String* method);
962 bool canDispatch(const String& method);
963 void dispatch(int callId, const String& method, std::unique_ptr<Value> message, const ProtocolMessage& rawMessage);
964 FrontendChannel* channel() { return m_frontendChannel; }
965 virtual ~UberDispatcher();
966
967private:
968 protocol::DispatcherBase* findDispatcher(const String& method);
969 FrontendChannel* m_frontendChannel;
970 std::unordered_map<String, String> m_redirects;
971 std::unordered_map<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
972};
973
974class InternalResponse : public Serializable {
975 PROTOCOL_DISALLOW_COPY(InternalResponse)private: InternalResponse(const InternalResponse&) = delete
; InternalResponse& operator=(const InternalResponse&
) = delete
;
976public:
977 static std::unique_ptr<InternalResponse> createResponse(int callId, std::unique_ptr<Serializable> params);
978 static std::unique_ptr<InternalResponse> createNotification(const String& notification, std::unique_ptr<Serializable> params = nullptr);
979
980 String serializeToJSON() override;
981 std::vector<uint8_t> serializeToBinary() override;
982
983 ~InternalResponse() override {}
984
985private:
986 InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params);
987
988 int m_callId;
989 String m_notification;
990 std::unique_ptr<Serializable> m_params;
991};
992
993class InternalRawNotification : public Serializable {
994public:
995 static std::unique_ptr<InternalRawNotification> fromJSON(String notification)
996 {
997 return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification)));
998 }
999
1000 static std::unique_ptr<InternalRawNotification> fromBinary(std::vector<uint8_t> notification)
1001 {
1002 return std::unique_ptr<InternalRawNotification>(new InternalRawNotification(std::move(notification)));
1003 }
1004
1005 ~InternalRawNotification() override {}
1006
1007 String serializeToJSON() override
1008 {
1009 return std::move(m_jsonNotification);
1010 }
1011
1012 std::vector<uint8_t> serializeToBinary() override
1013 {
1014 return std::move(m_binaryNotification);
1015 }
1016
1017private:
1018 explicit InternalRawNotification(String notification)
1019 : m_jsonNotification(std::move(notification)) { }
1020 explicit InternalRawNotification(std::vector<uint8_t> notification)
1021 : m_binaryNotification(std::move(notification)) { }
1022
1023 String m_jsonNotification;
1024 std::vector<uint8_t> m_binaryNotification;
1025};
1026
1027} // namespace node
1028} // namespace inspector
1029} // namespace protocol
1030
1031#endif // !defined(node_inspector_protocol_DispatcherBase_h)
1032
1033
1034// This file is generated by Parser_h.template.
1035
1036// Copyright 2016 The Chromium Authors. All rights reserved.
1037// Use of this source code is governed by a BSD-style license that can be
1038// found in the LICENSE file.
1039
1040#ifndef node_inspector_protocol_Parser_h
1041#define node_inspector_protocol_Parser_h
1042
1043//#include "Forward.h"
1044//#include "Values.h"
1045
1046namespace node {
1047namespace inspector {
1048namespace protocol {
1049
1050 std::unique_ptr<Value> parseJSONCharacters(const uint8_t*, unsigned);
1051 std::unique_ptr<Value> parseJSONCharacters(const uint16_t*, unsigned);
1052
1053} // namespace node
1054} // namespace inspector
1055} // namespace protocol
1056
1057#endif // !defined(node_inspector_protocol_Parser_h)
1058
1059
1060// Generated by lib/encoding_h.template.
1061
1062// Copyright 2019 The Chromium Authors. All rights reserved.
1063// Use of this source code is governed by a BSD-style license that can be
1064// found in the LICENSE file.
1065
1066#ifndef node_inspector_protocol_encoding_h
1067#define node_inspector_protocol_encoding_h
1068
1069#include <cstddef>
1070#include <cstdint>
1071#include <cstring>
1072#include <limits>
1073#include <memory>
1074#include <string>
1075#include <vector>
1076
1077namespace node {
1078namespace inspector {
1079namespace protocol {
1080
1081// ===== encoding/encoding.h =====
1082
1083
1084// =============================================================================
1085// span - sequence of bytes
1086// =============================================================================
1087
1088// This template is similar to std::span, which will be included in C++20.
1089template <typename T>
1090class span {
1091 public:
1092 using index_type = size_t;
1093
1094 span() : data_(nullptr), size_(0) {}
1095 span(const T* data, index_type size) : data_(data), size_(size) {}
1096
1097 const T* data() const { return data_; }
1098
1099 const T* begin() const { return data_; }
1100 const T* end() const { return data_ + size_; }
1101
1102 const T& operator[](index_type idx) const { return data_[idx]; }
1103
1104 span<T> subspan(index_type offset, index_type count) const {
1105 return span(data_ + offset, count);
1106 }
1107
1108 span<T> subspan(index_type offset) const {
1109 return span(data_ + offset, size_ - offset);
1110 }
1111
1112 bool empty() const { return size_ == 0; }
1113
1114 index_type size() const { return size_; }
1115 index_type size_bytes() const { return size_ * sizeof(T); }
1116
1117 private:
1118 const T* data_;
1119 index_type size_;
1120};
1121
1122template <typename T>
1123span<T> SpanFrom(const std::vector<T>& v) {
1124 return span<T>(v.data(), v.size());
1125}
1126
1127template <size_t N>
1128span<uint8_t> SpanFrom(const char (&str)[N]) {
1129 return span<uint8_t>(reinterpret_cast<const uint8_t*>(str), N - 1);
1130}
1131
1132inline span<uint8_t> SpanFrom(const char* str) {
1133 return str ? span<uint8_t>(reinterpret_cast<const uint8_t*>(str), strlen(str))
1134 : span<uint8_t>();
1135}
1136
1137inline span<uint8_t> SpanFrom(const std::string& v) {
1138 return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size());
1139}
1140
1141// =============================================================================
1142// Status and Error codes
1143// =============================================================================
1144enum class Error {
1145 OK = 0,
1146 // JSON parsing errors - json_parser.{h,cc}.
1147 JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01,
1148 JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02,
1149 JSON_PARSER_NO_INPUT = 0x03,
1150 JSON_PARSER_INVALID_TOKEN = 0x04,
1151 JSON_PARSER_INVALID_NUMBER = 0x05,
1152 JSON_PARSER_INVALID_STRING = 0x06,
1153 JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07,
1154 JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08,
1155 JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09,
1156 JSON_PARSER_COLON_EXPECTED = 0x0a,
1157 JSON_PARSER_UNEXPECTED_MAP_END = 0x0b,
1158 JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c,
1159 JSON_PARSER_VALUE_EXPECTED = 0x0d,
1160
1161 CBOR_INVALID_INT32 = 0x0e,
1162 CBOR_INVALID_DOUBLE = 0x0f,
1163 CBOR_INVALID_ENVELOPE = 0x10,
1164 CBOR_INVALID_STRING8 = 0x11,
1165 CBOR_INVALID_STRING16 = 0x12,
1166 CBOR_INVALID_BINARY = 0x13,
1167 CBOR_UNSUPPORTED_VALUE = 0x14,
1168 CBOR_NO_INPUT = 0x15,
1169 CBOR_INVALID_START_BYTE = 0x16,
1170 CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17,
1171 CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18,
1172 CBOR_UNEXPECTED_EOF_IN_MAP = 0x19,
1173 CBOR_INVALID_MAP_KEY = 0x1a,
1174 CBOR_STACK_LIMIT_EXCEEDED = 0x1b,
1175 CBOR_TRAILING_JUNK = 0x1c,
1176 CBOR_MAP_START_EXPECTED = 0x1d,
1177 CBOR_MAP_STOP_EXPECTED = 0x1e,
1178 CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x1f,
1179};
1180
1181// A status value with position that can be copied. The default status
1182// is OK. Usually, error status values should come with a valid position.
1183struct Status {
1184 static constexpr size_t npos() { return std::numeric_limits<size_t>::max(); }
1185
1186 bool ok() const { return error == Error::OK; }
1187
1188 Error error = Error::OK;
1189 size_t pos = npos();
1190 Status(Error error, size_t pos) : error(error), pos(pos) {}
1191 Status() = default;
1192
1193 // Returns a 7 bit US-ASCII string, either "OK" or an error message
1194 // that includes the position.
1195 std::string ToASCIIString() const;
1196
1197 private:
1198 std::string ToASCIIString(const char* msg) const;
1199};
1200
1201// Handler interface for parser events emitted by a streaming parser.
1202// See cbor::NewCBOREncoder, cbor::ParseCBOR, json::NewJSONEncoder,
1203// json::ParseJSON.
1204class StreamingParserHandler {
1205 public:
1206 virtual ~StreamingParserHandler() = default;
1207 virtual void HandleMapBegin() = 0;
1208 virtual void HandleMapEnd() = 0;
1209 virtual void HandleArrayBegin() = 0;
1210 virtual void HandleArrayEnd() = 0;
1211 virtual void HandleString8(span<uint8_t> chars) = 0;
1212 virtual void HandleString16(span<uint16_t> chars) = 0;
1213 virtual void HandleBinary(span<uint8_t> bytes) = 0;
1214 virtual void HandleDouble(double value) = 0;
1215 virtual void HandleInt32(int32_t value) = 0;
1216 virtual void HandleBool(bool value) = 0;
1217 virtual void HandleNull() = 0;
1218
1219 // The parser may send one error even after other events have already
1220 // been received. Client code is reponsible to then discard the
1221 // already processed events.
1222 // |error| must be an eror, as in, |error.is_ok()| can't be true.
1223 virtual void HandleError(Status error) = 0;
1224};
1225
1226namespace cbor {
1227// The binary encoding for the inspector protocol follows the CBOR specification
1228// (RFC 7049). Additional constraints:
1229// - Only indefinite length maps and arrays are supported.
1230// - Maps and arrays are wrapped with an envelope, that is, a
1231// CBOR tag with value 24 followed by a byte string specifying
1232// the byte length of the enclosed map / array. The byte string
1233// must use a 32 bit wide length.
1234// - At the top level, a message must be an indefinite length map
1235// wrapped by an envelope.
1236// - Maximal size for messages is 2^32 (4 GiB).
1237// - For scalars, we support only the int32_t range, encoded as
1238// UNSIGNED/NEGATIVE (major types 0 / 1).
1239// - UTF16 strings, including with unbalanced surrogate pairs, are encoded
1240// as CBOR BYTE_STRING (major type 2). For such strings, the number of
1241// bytes encoded must be even.
1242// - UTF8 strings (major type 3) are supported.
1243// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, never
1244// as UTF16 strings.
1245// - Arbitrary byte arrays, in the inspector protocol called 'binary',
1246// are encoded as BYTE_STRING (major type 2), prefixed with a byte
1247// indicating base64 when rendered as JSON.
1248
1249// =============================================================================
1250// Detecting CBOR content
1251// =============================================================================
1252
1253// The first byte for an envelope, which we use for wrapping dictionaries
1254// and arrays; and the byte that indicates a byte string with 32 bit length.
1255// These two bytes start an envelope, and thereby also any CBOR message
1256// produced or consumed by this protocol. See also |EnvelopeEncoder| below.
1257uint8_t InitialByteForEnvelope();
1258uint8_t InitialByteFor32BitLengthByteString();
1259
1260// Checks whether |msg| is a cbor message.
1261bool IsCBORMessage(span<uint8_t> msg);
1262
1263// =============================================================================
1264// Encoding individual CBOR items
1265// =============================================================================
1266
1267// Some constants for CBOR tokens that only take a single byte on the wire.
1268uint8_t EncodeTrue();
1269uint8_t EncodeFalse();
1270uint8_t EncodeNull();
1271uint8_t EncodeIndefiniteLengthArrayStart();
1272uint8_t EncodeIndefiniteLengthMapStart();
1273uint8_t EncodeStop();
1274
1275// Encodes |value| as |UNSIGNED| (major type 0) iff >= 0, or |NEGATIVE|
1276// (major type 1) iff < 0.
1277void EncodeInt32(int32_t value, std::vector<uint8_t>* out);
1278void EncodeInt32(int32_t value, std::string* out);
1279
1280// Encodes a UTF16 string as a BYTE_STRING (major type 2). Each utf16
1281// character in |in| is emitted with most significant byte first,
1282// appending to |out|.
1283void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out);
1284void EncodeString16(span<uint16_t> in, std::string* out);
1285
1286// Encodes a UTF8 string |in| as STRING (major type 3).
1287void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out);
1288void EncodeString8(span<uint8_t> in, std::string* out);
1289
1290// Encodes the given |latin1| string as STRING8.
1291// If any non-ASCII character is present, it will be represented
1292// as a 2 byte UTF8 sequence.
1293void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out);
1294void EncodeFromLatin1(span<uint8_t> latin1, std::string* out);
1295
1296// Encodes the given |utf16| string as STRING8 if it's entirely US-ASCII.
1297// Otherwise, encodes as STRING16.
1298void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out);
1299void EncodeFromUTF16(span<uint16_t> utf16, std::string* out);
1300
1301// Encodes arbitrary binary data in |in| as a BYTE_STRING (major type 2) with
1302// definitive length, prefixed with tag 22 indicating expected conversion to
1303// base64 (see RFC 7049, Table 3 and Section 2.4.4.2).
1304void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out);
1305void EncodeBinary(span<uint8_t> in, std::string* out);
1306
1307// Encodes / decodes a double as Major type 7 (SIMPLE_VALUE),
1308// with additional info = 27, followed by 8 bytes in big endian.
1309void EncodeDouble(double value, std::vector<uint8_t>* out);
1310void EncodeDouble(double value, std::string* out);
1311
1312// =============================================================================
1313// cbor::EnvelopeEncoder - for wrapping submessages
1314// =============================================================================
1315
1316// An envelope indicates the byte length of a wrapped item.
1317// We use this for maps and array, which allows the decoder
1318// to skip such (nested) values whole sale.
1319// It's implemented as a CBOR tag (major type 6) with additional
1320// info = 24, followed by a byte string with a 32 bit length value;
1321// so the maximal structure that we can wrap is 2^32 bits long.
1322// See also: https://tools.ietf.org/html/rfc7049#section-2.4.4.1
1323class EnvelopeEncoder {
1324 public:
1325 // Emits the envelope start bytes and records the position for the
1326 // byte size in |byte_size_pos_|. Also emits empty bytes for the
1327 // byte sisze so that encoding can continue.
1328 void EncodeStart(std::vector<uint8_t>* out);
1329 void EncodeStart(std::string* out);
1330 // This records the current size in |out| at position byte_size_pos_.
1331 // Returns true iff successful.
1332 bool EncodeStop(std::vector<uint8_t>* out);
1333 bool EncodeStop(std::string* out);
1334
1335 private:
1336 size_t byte_size_pos_ = 0;
1337};
1338
1339// =============================================================================
1340// cbor::NewCBOREncoder - for encoding from a streaming parser
1341// =============================================================================
1342
1343// This can be used to convert to CBOR, by passing the return value to a parser
1344// that drives it. The handler will encode into |out|, and iff an error occurs
1345// it will set |status| to an error and clear |out|. Otherwise, |status.ok()|
1346// will be |true|.
1347std::unique_ptr<StreamingParserHandler> NewCBOREncoder(
1348 std::vector<uint8_t>* out,
1349 Status* status);
1350std::unique_ptr<StreamingParserHandler> NewCBOREncoder(std::string* out,
1351 Status* status);
1352
1353// =============================================================================
1354// cbor::CBORTokenizer - for parsing individual CBOR items
1355// =============================================================================
1356
1357// Tags for the tokens within a CBOR message that CBORTokenizer understands.
1358// Note that this is not the same terminology as the CBOR spec (RFC 7049),
1359// but rather, our adaptation. For instance, we lump unsigned and signed
1360// major type into INT32 here (and disallow values outside the int32_t range).
1361enum class CBORTokenTag {
1362 // Encountered an error in the structure of the message. Consult
1363 // status() for details.
1364 ERROR_VALUE,
1365 // Booleans and NULL.
1366 TRUE_VALUE,
1367 FALSE_VALUE,
1368 NULL_VALUE,
1369 // An int32_t (signed 32 bit integer).
1370 INT32,
1371 // A double (64 bit floating point).
1372 DOUBLE,
1373 // A UTF8 string.
1374 STRING8,
1375 // A UTF16 string.
1376 STRING16,
1377 // A binary string.
1378 BINARY,
1379 // Starts an indefinite length map; after the map start we expect
1380 // alternating keys and values, followed by STOP.
1381 MAP_START,
1382 // Starts an indefinite length array; after the array start we
1383 // expect values, followed by STOP.
1384 ARRAY_START,
1385 // Ends a map or an array.
1386 STOP,
1387 // An envelope indicator, wrapping a map or array.
1388 // Internally this carries the byte length of the wrapped
1389 // map or array. While CBORTokenizer::Next() will read / skip the entire
1390 // envelope, CBORTokenizer::EnterEnvelope() reads the tokens
1391 // inside of it.
1392 ENVELOPE,
1393 // We've reached the end there is nothing else to read.
1394 DONE,
1395};
1396
1397// The major types from RFC 7049 Section 2.1.
1398enum class MajorType {
1399 UNSIGNED = 0,
1400 NEGATIVE = 1,
1401 BYTE_STRING = 2,
1402 STRING = 3,
1403 ARRAY = 4,
1404 MAP = 5,
1405 TAG = 6,
1406 SIMPLE_VALUE = 7
1407};
1408
1409// CBORTokenizer segments a CBOR message, presenting the tokens therein as
1410// numbers, strings, etc. This is not a complete CBOR parser, but makes it much
1411// easier to implement one (e.g. ParseCBOR, above). It can also be used to parse
1412// messages partially.
1413class CBORTokenizer {
1414 public:
1415 explicit CBORTokenizer(span<uint8_t> bytes);
1416 ~CBORTokenizer();
1417
1418 // Identifies the current token that we're looking at,
1419 // or ERROR_VALUE (in which ase ::Status() has details)
1420 // or DONE (if we're past the last token).
1421 CBORTokenTag TokenTag() const;
1422
1423 // Advances to the next token.
1424 void Next();
1425 // Can only be called if TokenTag() == CBORTokenTag::ENVELOPE.
1426 // While Next() would skip past the entire envelope / what it's
1427 // wrapping, EnterEnvelope positions the cursor inside of the envelope,
1428 // letting the client explore the nested structure.
1429 void EnterEnvelope();
1430
1431 // If TokenTag() is CBORTokenTag::ERROR_VALUE, then Status().error describes
1432 // the error more precisely; otherwise it'll be set to Error::OK.
1433 // In either case, Status().pos is the current position.
1434 struct Status Status() const;
1435
1436 // The following methods retrieve the token values. They can only
1437 // be called if TokenTag() matches.
1438
1439 // To be called only if ::TokenTag() == CBORTokenTag::INT32.
1440 int32_t GetInt32() const;
1441
1442 // To be called only if ::TokenTag() == CBORTokenTag::DOUBLE.
1443 double GetDouble() const;
1444
1445 // To be called only if ::TokenTag() == CBORTokenTag::STRING8.
1446 span<uint8_t> GetString8() const;
1447
1448 // Wire representation for STRING16 is low byte first (little endian).
1449 // To be called only if ::TokenTag() == CBORTokenTag::STRING16.
1450 span<uint8_t> GetString16WireRep() const;
1451
1452 // To be called only if ::TokenTag() == CBORTokenTag::BINARY.
1453 span<uint8_t> GetBinary() const;
1454
1455 // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE.
1456 span<uint8_t> GetEnvelopeContents() const;
1457
1458 private:
1459 void ReadNextToken(bool enter_envelope);
1460 void SetToken(CBORTokenTag token, size_t token_byte_length);
1461 void SetError(Error error);
1462
1463 span<uint8_t> bytes_;
1464 CBORTokenTag token_tag_;
1465 struct Status status_;
1466 size_t token_byte_length_;
1467 MajorType token_start_type_;
1468 uint64_t token_start_internal_value_;
1469};
1470
1471// =============================================================================
1472// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages
1473// =============================================================================
1474
1475// Parses a CBOR encoded message from |bytes|, sending events to
1476// |out|. If an error occurs, sends |out->HandleError|, and parsing stops.
1477// The client is responsible for discarding the already received information in
1478// that case.
1479void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out);
1480
1481// =============================================================================
1482// cbor::AppendString8EntryToMap - for limited in-place editing of messages
1483// =============================================================================
1484
1485// Modifies the |cbor| message by appending a new key/value entry at the end
1486// of the map. Patches up the envelope size; Status.ok() iff successful.
1487// If not successful, |cbor| may be corrupted after this call.
1488Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
1489 span<uint8_t> string8_value,
1490 std::vector<uint8_t>* cbor);
1491Status AppendString8EntryToCBORMap(span<uint8_t> string8_key,
1492 span<uint8_t> string8_value,
1493 std::string* cbor);
1494
1495namespace internals { // Exposed only for writing tests.
1496size_t ReadTokenStart(span<uint8_t> bytes,
1497 cbor::MajorType* type,
1498 uint64_t* value);
1499
1500void WriteTokenStart(cbor::MajorType type,
1501 uint64_t value,
1502 std::vector<uint8_t>* encoded);
1503void WriteTokenStart(cbor::MajorType type,
1504 uint64_t value,
1505 std::string* encoded);
1506} // namespace internals
1507} // namespace cbor
1508
1509namespace json {
1510// Client code must provide an instance. Implementation should delegate
1511// to whatever is appropriate.
1512class Platform {
1513 public:
1514 virtual ~Platform() = default;
1515 // Parses |str| into |result|. Returns false iff there are
1516 // leftover characters or parsing errors.
1517 virtual bool StrToD(const char* str, double* result) const = 0;
1518
1519 // Prints |value| in a format suitable for JSON.
1520 virtual std::unique_ptr<char[]> DToStr(double value) const = 0;
1521};
1522
1523// =============================================================================
1524// json::NewJSONEncoder - for encoding streaming parser events as JSON
1525// =============================================================================
1526
1527// Returns a handler object which will write ascii characters to |out|.
1528// |status->ok()| will be false iff the handler routine HandleError() is called.
1529// In that case, we'll stop emitting output.
1530// Except for calling the HandleError routine at any time, the client
1531// code must call the Handle* methods in an order in which they'd occur
1532// in valid JSON; otherwise we may crash (the code uses assert).
1533std::unique_ptr<StreamingParserHandler> NewJSONEncoder(
1534 const Platform* platform,
1535 std::vector<uint8_t>* out,
1536 Status* status);
1537std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform,
1538 std::string* out,
1539 Status* status);
1540
1541// =============================================================================
1542// json::ParseJSON - for receiving streaming parser events for JSON
1543// =============================================================================
1544
1545void ParseJSON(const Platform& platform,
1546 span<uint8_t> chars,
1547 StreamingParserHandler* handler);
1548void ParseJSON(const Platform& platform,
1549 span<uint16_t> chars,
1550 StreamingParserHandler* handler);
1551
1552// =============================================================================
1553// json::ConvertCBORToJSON, json::ConvertJSONToCBOR - for transcoding
1554// =============================================================================
1555Status ConvertCBORToJSON(const Platform& platform,
1556 span<uint8_t> cbor,
1557 std::string* json);
1558Status ConvertCBORToJSON(const Platform& platform,
1559 span<uint8_t> cbor,
1560 std::vector<uint8_t>* json);
1561Status ConvertJSONToCBOR(const Platform& platform,
1562 span<uint8_t> json,
1563 std::vector<uint8_t>* cbor);
1564Status ConvertJSONToCBOR(const Platform& platform,
1565 span<uint16_t> json,
1566 std::vector<uint8_t>* cbor);
1567Status ConvertJSONToCBOR(const Platform& platform,
1568 span<uint8_t> json,
1569 std::string* cbor);
1570Status ConvertJSONToCBOR(const Platform& platform,
1571 span<uint16_t> json,
1572 std::string* cbor);
1573} // namespace json
1574
1575} // namespace node
1576} // namespace inspector
1577} // namespace protocol
1578#endif // !defined(node_inspector_protocol_encoding_h)