GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp Lines: 424 1274 33.3 %
Date: 2019-05-05 22:32:45 Branches: 179 972 18.4 %

Line Branch Exec Source
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
23
namespace node {
24
namespace inspector {
25
namespace protocol {
26
27
17
ErrorSupport::ErrorSupport() { }
28
17
ErrorSupport::~ErrorSupport() { }
29
30
21
void ErrorSupport::setName(const char* name)
31
{
32
21
    setName(String(name));
33
21
}
34
35
24
void ErrorSupport::setName(const String& name)
36
{
37
    DCHECK(m_path.size());
38
24
    m_path[m_path.size() - 1] = name;
39
24
}
40
41
18
void ErrorSupport::push()
42
{
43
18
    m_path.push_back(String());
44
18
}
45
46
18
void ErrorSupport::pop()
47
{
48
18
    m_path.pop_back();
49
18
}
50
51
void ErrorSupport::addError(const char* error)
52
{
53
    addError(String(error));
54
}
55
56
void 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
69
18
bool ErrorSupport::hasErrors()
70
{
71
18
    return !!m_errors.size();
72
}
73
74
String 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
namespace node {
99
namespace inspector {
100
namespace protocol {
101
102
namespace {
103
104
const char* const nullValueString = "null";
105
const char* const trueValueString = "true";
106
const char* const falseValueString = "false";
107
108
69788
inline bool escapeChar(uint16_t c, StringBuilder* dst)
109
{
110


69788
    switch (c) {
111
    case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
112
    case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
113
    case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
114
    case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
115
    case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
116
396
    case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
117
8466
    case '"': StringUtil::builderAppend(*dst, "\\\""); break;
118
    default:
119
60926
        return false;
120
    }
121
8862
    return true;
122
}
123
124
const char hexDigits[17] = "0123456789ABCDEF";
125
126
void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
127
{
128
    StringUtil::builderAppend(*dst, "\\u");
129
    for (size_t i = 0; i < 4; ++i) {
130
        uint16_t c = hexDigits[(number & 0xF000) >> 12];
131
        StringUtil::builderAppend(*dst, c);
132
        number <<= 4;
133
    }
134
}
135
136
template <typename Char>
137
762
void escapeStringForJSONInternal(const Char* str, unsigned len,
138
                                 StringBuilder* dst)
139
{
140

70550
    for (unsigned i = 0; i < len; ++i) {
141
69788
        Char c = str[i];
142

69788
        if (escapeChar(c, dst))
143
8862
            continue;
144


60926
        if (c < 32 || c > 126) {
145
            appendUnsignedAsHex(c, dst);
146
        } else {
147
60926
            StringUtil::builderAppend(*dst, c);
148
        }
149
    }
150
762
}
151
152
// When parsing CBOR, we limit recursion depth for objects and arrays
153
// to this constant.
154
static constexpr int kStackLimitValues = 1000;
155
156
// Below are three parsing routines for CBOR, which cover enough
157
// to roundtrip JSON messages.
158
std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, CBORTokenizer* tokenizer);
159
std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer);
160
std::unique_ptr<Value> parseValue(int32_t stack_depth, CBORTokenizer* tokenizer);
161
162
// |bytes| must start with the indefinite length array byte, so basically,
163
// ParseArray may only be called after an indefinite length array has been
164
// detected.
165
std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer) {
166
  DCHECK(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
167
  tokenizer->Next();
168
  auto list = ListValue::create();
169
  while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
170
    // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY
171
    if (tokenizer->TokenTag() == CBORTokenTag::DONE) return nullptr;
172
    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
173
    // Parse value.
174
    auto value = parseValue(stack_depth, tokenizer);
175
    if (!value) return nullptr;
176
    list->pushValue(std::move(value));
177
  }
178
  tokenizer->Next();
179
  return list;
180
}
181
182
std::unique_ptr<Value> parseValue(
183
    int32_t stack_depth, CBORTokenizer* tokenizer) {
184
  // Error::CBOR_STACK_LIMIT_EXCEEDED
185
  if (stack_depth > kStackLimitValues) return nullptr;
186
  // Skip past the envelope to get to what's inside.
187
  if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
188
    tokenizer->EnterEnvelope();
189
  switch (tokenizer->TokenTag()) {
190
    case CBORTokenTag::ERROR_VALUE:
191
      return nullptr;
192
    case CBORTokenTag::DONE:
193
      // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE
194
      return nullptr;
195
    case CBORTokenTag::TRUE_VALUE: {
196
      std::unique_ptr<Value> value = FundamentalValue::create(true);
197
      tokenizer->Next();
198
      return value;
199
    }
200
    case CBORTokenTag::FALSE_VALUE: {
201
      std::unique_ptr<Value> value = FundamentalValue::create(false);
202
      tokenizer->Next();
203
      return value;
204
    }
205
    case CBORTokenTag::NULL_VALUE: {
206
      std::unique_ptr<Value> value = FundamentalValue::null();
207
      tokenizer->Next();
208
      return value;
209
    }
210
    case CBORTokenTag::INT32: {
211
      std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32());
212
      tokenizer->Next();
213
      return value;
214
    }
215
    case CBORTokenTag::DOUBLE: {
216
      std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble());
217
      tokenizer->Next();
218
      return value;
219
    }
220
    case CBORTokenTag::STRING8: {
221
      span<uint8_t> str = tokenizer->GetString8();
222
      std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF8(str.data(), str.size()));
223
      tokenizer->Next();
224
      return value;
225
    }
226
    case CBORTokenTag::STRING16:
227
      // NOT SUPPORTED YET.
228
      return nullptr;
229
    case CBORTokenTag::BINARY: {
230
      span<uint8_t> payload = tokenizer->GetBinary();
231
      tokenizer->Next();
232
      return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size()));
233
    }
234
    case CBORTokenTag::MAP_START:
235
      return parseMap(stack_depth + 1, tokenizer);
236
    case CBORTokenTag::ARRAY_START:
237
      return parseArray(stack_depth + 1, tokenizer);
238
    default:
239
      // Error::CBOR_UNSUPPORTED_VALUE
240
      return nullptr;
241
  }
242
}
243
244
// |bytes| must start with the indefinite length array byte, so basically,
245
// ParseArray may only be called after an indefinite length array has been
246
// detected.
247
std::unique_ptr<DictionaryValue> parseMap(
248
    int32_t stack_depth, CBORTokenizer* tokenizer) {
249
  auto dict = DictionaryValue::create();
250
  tokenizer->Next();
251
  while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
252
    if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
253
      // Error::CBOR_UNEXPECTED_EOF_IN_MAP
254
      return nullptr;
255
    }
256
    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
257
    // Parse key.
258
    String key;
259
    if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
260
      span<uint8_t> key_span = tokenizer->GetString8();
261
      key = StringUtil::fromUTF8(key_span.data(), key_span.size());
262
      tokenizer->Next();
263
    } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
264
      return nullptr;  // STRING16 not supported yet.
265
    } else {
266
      // Error::CBOR_INVALID_MAP_KEY
267
      return nullptr;
268
    }
269
    // Parse value.
270
    auto value = parseValue(stack_depth, tokenizer);
271
    if (!value) return nullptr;
272
    dict->setValue(key, std::move(value));
273
  }
274
  tokenizer->Next();
275
  return dict;
276
}
277
278
} // anonymous namespace
279
280
// static
281
std::unique_ptr<Value> Value::parseBinary(const uint8_t* data, size_t size) {
282
  span<uint8_t> bytes(data, size);
283
284
  // Error::CBOR_NO_INPUT
285
  if (bytes.empty()) return nullptr;
286
287
  // Error::CBOR_INVALID_START_BYTE
288
  // TODO(johannes): EncodeInitialByteForEnvelope() method.
289
  if (bytes[0] != 0xd8) return nullptr;
290
291
  CBORTokenizer tokenizer(bytes);
292
  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
293
294
  // We checked for the envelope start byte above, so the tokenizer
295
  // must agree here, since it's not an error.
296
  DCHECK(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
297
  tokenizer.EnterEnvelope();
298
  // Error::MAP_START_EXPECTED
299
  if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) return nullptr;
300
  std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer);
301
  if (!result) return nullptr;
302
  if (tokenizer.TokenTag() == CBORTokenTag::DONE) return result;
303
  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr;
304
  // Error::CBOR_TRAILING_JUNK
305
  return nullptr;
306
}
307
308
bool Value::asBoolean(bool*) const
309
{
310
    return false;
311
}
312
313
bool Value::asDouble(double*) const
314
{
315
    return false;
316
}
317
318
bool Value::asInteger(int*) const
319
{
320
    return false;
321
}
322
323
bool Value::asString(String*) const
324
{
325
    return false;
326
}
327
328
bool Value::asBinary(Binary*) const
329
{
330
    return false;
331
}
332
333
void Value::writeJSON(StringBuilder* output) const
334
{
335
    DCHECK(m_type == TypeNull);
336
    StringUtil::builderAppend(*output, nullValueString, 4);
337
}
338
339
void Value::writeBinary(std::vector<uint8_t>* bytes) const {
340
    DCHECK(m_type == TypeNull);
341
    bytes->push_back(EncodeNull());
342
}
343
344
std::unique_ptr<Value> Value::clone() const
345
{
346
    return Value::null();
347
}
348
349
233
String Value::toJSONString() const
350
{
351
233
    StringBuilder result;
352
233
    StringUtil::builderReserve(result, 512);
353
233
    writeJSON(&result);
354
233
    return StringUtil::builderToString(result);
355
}
356
357
233
String Value::serializeToJSON() {
358
233
    return toJSONString();
359
}
360
361
std::vector<uint8_t> Value::serializeToBinary() {
362
    std::vector<uint8_t> bytes;
363
    writeBinary(&bytes);
364
    return bytes;
365
}
366
367
3
bool FundamentalValue::asBoolean(bool* output) const
368
{
369
3
    if (type() != TypeBoolean)
370
        return false;
371
3
    *output = m_boolValue;
372
3
    return true;
373
}
374
375
bool FundamentalValue::asDouble(double* output) const
376
{
377
    if (type() == TypeDouble) {
378
        *output = m_doubleValue;
379
        return true;
380
    }
381
    if (type() == TypeInteger) {
382
        *output = m_integerValue;
383
        return true;
384
    }
385
    return false;
386
}
387
388
14320
bool FundamentalValue::asInteger(int* output) const
389
{
390
14320
    if (type() != TypeInteger)
391
        return false;
392
14320
    *output = m_integerValue;
393
14320
    return true;
394
}
395
396
22
void FundamentalValue::writeJSON(StringBuilder* output) const
397
{
398
    DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
399
22
    if (type() == TypeBoolean) {
400
4
        if (m_boolValue)
401
2
            StringUtil::builderAppend(*output, trueValueString, 4);
402
        else
403
2
            StringUtil::builderAppend(*output, falseValueString, 5);
404
18
    } else if (type() == TypeDouble) {
405
        if (!std::isfinite(m_doubleValue)) {
406
            StringUtil::builderAppend(*output, nullValueString, 4);
407
22
            return;
408
        }
409
        StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
410
18
    } else if (type() == TypeInteger) {
411
18
        StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
412
    }
413
}
414
415
void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const {
416
    switch (type()) {
417
    case TypeDouble:
418
        EncodeDouble(m_doubleValue, bytes);
419
        return;
420
    case TypeInteger:
421
        EncodeInt32(m_integerValue, bytes);
422
        return;
423
    case TypeBoolean:
424
        bytes->push_back(m_boolValue ? EncodeTrue() : EncodeFalse());
425
        return;
426
    default:
427
        DCHECK(false);
428
    }
429
}
430
431
std::unique_ptr<Value> FundamentalValue::clone() const
432
{
433
    switch (type()) {
434
    case TypeDouble: return FundamentalValue::create(m_doubleValue);
435
    case TypeInteger: return FundamentalValue::create(m_integerValue);
436
    case TypeBoolean: return FundamentalValue::create(m_boolValue);
437
    default:
438
        DCHECK(false);
439
    }
440
    return nullptr;
441
}
442
443
14335
bool StringValue::asString(String* output) const
444
{
445
14335
    *output = m_stringValue;
446
14334
    return true;
447
}
448
449
313
void StringValue::writeJSON(StringBuilder* output) const
450
{
451
    DCHECK(type() == TypeString);
452
313
    StringUtil::builderAppendQuotedString(*output, m_stringValue);
453
313
}
454
455
void StringValue::writeBinary(std::vector<uint8_t>* bytes) const {
456
    StringUTF8Adapter utf8(m_stringValue);
457
    EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
458
                  utf8.length()), bytes);
459
}
460
461
std::unique_ptr<Value> StringValue::clone() const
462
{
463
    return StringValue::create(m_stringValue);
464
}
465
466
bool BinaryValue::asBinary(Binary* output) const
467
{
468
    *output = m_binaryValue;
469
    return true;
470
}
471
472
void BinaryValue::writeJSON(StringBuilder* output) const
473
{
474
    DCHECK(type() == TypeBinary);
475
    StringUtil::builderAppendQuotedString(*output, m_binaryValue.toBase64());
476
}
477
478
void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
479
    EncodeBinary(span<uint8_t>(m_binaryValue.data(), m_binaryValue.size()), bytes);
480
}
481
482
std::unique_ptr<Value> BinaryValue::clone() const
483
{
484
    return BinaryValue::create(m_binaryValue);
485
}
486
487
116
void SerializedValue::writeJSON(StringBuilder* output) const
488
{
489
    DCHECK(type() == TypeSerialized);
490
116
    StringUtil::builderAppend(*output, m_serializedJSON);
491
116
}
492
493
void SerializedValue::writeBinary(std::vector<uint8_t>* output) const
494
{
495
    DCHECK(type() == TypeSerialized);
496
    output->insert(output->end(), m_serializedBinary.begin(), m_serializedBinary.end());
497
}
498
499
std::unique_ptr<Value> SerializedValue::clone() const
500
{
501
    return std::unique_ptr<SerializedValue>(new SerializedValue(m_serializedJSON, m_serializedBinary));
502
}
503
504
38634
DictionaryValue::~DictionaryValue()
505
{
506
38634
}
507
508
void DictionaryValue::setBoolean(const String& name, bool value)
509
{
510
    setValue(name, FundamentalValue::create(value));
511
}
512
513
18
void DictionaryValue::setInteger(const String& name, int value)
514
{
515
18
    setValue(name, FundamentalValue::create(value));
516
18
}
517
518
void DictionaryValue::setDouble(const String& name, double value)
519
{
520
    setValue(name, FundamentalValue::create(value));
521
}
522
523
101
void DictionaryValue::setString(const String& name, const String& value)
524
{
525
101
    setValue(name, StringValue::create(value));
526
101
}
527
528
43342
void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
529
{
530
43342
    set(name, value);
531
43341
}
532
533
1
void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
534
{
535
1
    set(name, value);
536
1
}
537
538
void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
539
{
540
    set(name, value);
541
}
542
543
bool DictionaryValue::getBoolean(const String& name, bool* output) const
544
{
545
    protocol::Value* value = get(name);
546
    if (!value)
547
        return false;
548
    return value->asBoolean(output);
549
}
550
551
bool DictionaryValue::getInteger(const String& name, int* output) const
552
{
553
    Value* value = get(name);
554
    if (!value)
555
        return false;
556
    return value->asInteger(output);
557
}
558
559
bool DictionaryValue::getDouble(const String& name, double* output) const
560
{
561
    Value* value = get(name);
562
    if (!value)
563
        return false;
564
    return value->asDouble(output);
565
}
566
567
bool DictionaryValue::getString(const String& name, String* output) const
568
{
569
    protocol::Value* value = get(name);
570
    if (!value)
571
        return false;
572
    return value->asString(output);
573
}
574
575
DictionaryValue* DictionaryValue::getObject(const String& name) const
576
{
577
    return DictionaryValue::cast(get(name));
578
}
579
580
protocol::ListValue* DictionaryValue::getArray(const String& name) const
581
{
582
    return ListValue::cast(get(name));
583
}
584
585
28676
protocol::Value* DictionaryValue::get(const String& name) const
586
{
587
28676
    Dictionary::const_iterator it = m_data.find(name);
588
28676
    if (it == m_data.end())
589
3
        return nullptr;
590
28673
    return it->second.get();
591
}
592
593
DictionaryValue::Entry DictionaryValue::at(size_t index) const
594
{
595
    const String key = m_order[index];
596
    return std::make_pair(key, m_data.find(key)->second.get());
597
}
598
599
bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
600
{
601
    bool result = defaultValue;
602
    getBoolean(name, &result);
603
    return result;
604
}
605
606
int DictionaryValue::integerProperty(const String& name, int defaultValue) const
607
{
608
    int result = defaultValue;
609
    getInteger(name, &result);
610
    return result;
611
}
612
613
double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
614
{
615
    double result = defaultValue;
616
    getDouble(name, &result);
617
    return result;
618
}
619
620
void DictionaryValue::remove(const String& name)
621
{
622
    m_data.erase(name);
623
    m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
624
}
625
626
238
void DictionaryValue::writeJSON(StringBuilder* output) const
627
{
628
238
    StringUtil::builderAppend(*output, '{');
629
687
    for (size_t i = 0; i < m_order.size(); ++i) {
630
449
        Dictionary::const_iterator it = m_data.find(m_order[i]);
631
449
        CHECK(it != m_data.end());
632
449
        if (i)
633
228
            StringUtil::builderAppend(*output, ',');
634
449
        StringUtil::builderAppendQuotedString(*output, it->first);
635
449
        StringUtil::builderAppend(*output, ':');
636
449
        it->second->writeJSON(output);
637
    }
638
238
    StringUtil::builderAppend(*output, '}');
639
238
}
640
641
void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const {
642
    EnvelopeEncoder encoder;
643
    encoder.EncodeStart(bytes);
644
    bytes->push_back(EncodeIndefiniteLengthMapStart());
645
    for (size_t i = 0; i < m_order.size(); ++i) {
646
        const String& key = m_order[i];
647
        Dictionary::const_iterator value = m_data.find(key);
648
        DCHECK(value != m_data.cend() && value->second);
649
        StringUTF8Adapter utf8(key);
650
        EncodeString8(span<uint8_t>(reinterpret_cast<const uint8_t*>(utf8.Data()),
651
	                            utf8.length()), bytes);
652
        value->second->writeBinary(bytes);
653
    }
654
    bytes->push_back(EncodeStop());
655
    encoder.EncodeStop(bytes);
656
}
657
658
std::unique_ptr<Value> DictionaryValue::clone() const
659
{
660
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
661
    for (size_t i = 0; i < m_order.size(); ++i) {
662
        String key = m_order[i];
663
        Dictionary::const_iterator value = m_data.find(key);
664
        DCHECK(value != m_data.cend() && value->second);
665
        result->setValue(key, value->second->clone());
666
    }
667
    return std::move(result);
668
}
669
670
19317
DictionaryValue::DictionaryValue()
671
19317
    : Value(TypeObject)
672
{
673
19316
}
674
675
26
ListValue::~ListValue()
676
{
677
26
}
678
679
1
void ListValue::writeJSON(StringBuilder* output) const
680
{
681
1
    StringUtil::builderAppend(*output, '[');
682
1
    bool first = true;
683
9
    for (const std::unique_ptr<protocol::Value>& value : m_data) {
684
8
        if (!first)
685
7
            StringUtil::builderAppend(*output, ',');
686
8
        value->writeJSON(output);
687
8
        first = false;
688
    }
689
1
    StringUtil::builderAppend(*output, ']');
690
1
}
691
692
void ListValue::writeBinary(std::vector<uint8_t>* bytes) const {
693
    EnvelopeEncoder encoder;
694
    encoder.EncodeStart(bytes);
695
    bytes->push_back(EncodeIndefiniteLengthArrayStart());
696
    for (size_t i = 0; i < m_data.size(); ++i) {
697
        m_data[i]->writeBinary(bytes);
698
    }
699
    bytes->push_back(EncodeStop());
700
    encoder.EncodeStop(bytes);
701
}
702
703
std::unique_ptr<Value> ListValue::clone() const
704
{
705
    std::unique_ptr<ListValue> result = ListValue::create();
706
    for (const std::unique_ptr<protocol::Value>& value : m_data)
707
        result->pushValue(value->clone());
708
    return std::move(result);
709
}
710
711
13
ListValue::ListValue()
712
13
    : Value(TypeArray)
713
{
714
13
}
715
716
13
void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
717
{
718
    DCHECK(value);
719
13
    m_data.push_back(std::move(value));
720
13
}
721
722
3
protocol::Value* ListValue::at(size_t index)
723
{
724
    DCHECK_LT(index, m_data.size());
725
3
    return m_data[index].get();
726
}
727
728
void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
729
{
730
    escapeStringForJSONInternal<uint8_t>(str, len, dst);
731
}
732
733
762
void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
734
{
735
762
    escapeStringForJSONInternal<uint16_t>(str, len, dst);
736
762
}
737
738
} // namespace node
739
} // namespace inspector
740
} // namespace protocol
741
742
743
// This file is generated by Object_cpp.template.
744
745
// Copyright 2016 The Chromium Authors. All rights reserved.
746
// Use of this source code is governed by a BSD-style license that can be
747
// found in the LICENSE file.
748
749
//#include "Object.h"
750
751
namespace node {
752
namespace inspector {
753
namespace protocol {
754
755
std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
756
{
757
    protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
758
    if (!dictionary) {
759
        errors->addError("object expected");
760
        return nullptr;
761
    }
762
    dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
763
    return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
764
}
765
766
std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
767
{
768
    return DictionaryValue::cast(m_object->clone());
769
}
770
771
std::unique_ptr<Object> Object::clone() const
772
{
773
    return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
774
}
775
776
Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
777
778
Object::~Object() { }
779
780
} // namespace node
781
} // namespace inspector
782
} // namespace protocol
783
784
785
// This file is generated by DispatcherBase_cpp.template.
786
787
// Copyright 2016 The Chromium Authors. All rights reserved.
788
// Use of this source code is governed by a BSD-style license that can be
789
// found in the LICENSE file.
790
791
//#include "DispatcherBase.h"
792
//#include "Parser.h"
793
794
namespace node {
795
namespace inspector {
796
namespace protocol {
797
798
// static
799
8988
DispatchResponse DispatchResponse::OK()
800
{
801
8988
    DispatchResponse result;
802
8988
    result.m_status = kSuccess;
803
8988
    result.m_errorCode = kParseError;
804
8988
    return result;
805
}
806
807
// static
808
1
DispatchResponse DispatchResponse::Error(const String& error)
809
{
810
1
    DispatchResponse result;
811
1
    result.m_status = kError;
812
1
    result.m_errorCode = kServerError;
813
1
    result.m_errorMessage = error;
814
1
    return result;
815
}
816
817
// static
818
DispatchResponse DispatchResponse::InternalError()
819
{
820
    DispatchResponse result;
821
    result.m_status = kError;
822
    result.m_errorCode = kInternalError;
823
    result.m_errorMessage = "Internal error";
824
    return result;
825
}
826
827
// static
828
DispatchResponse DispatchResponse::InvalidParams(const String& error)
829
{
830
    DispatchResponse result;
831
    result.m_status = kError;
832
    result.m_errorCode = kInvalidParams;
833
    result.m_errorMessage = error;
834
    return result;
835
}
836
837
// static
838
DispatchResponse DispatchResponse::FallThrough()
839
{
840
    DispatchResponse result;
841
    result.m_status = kFallThrough;
842
    result.m_errorCode = kParseError;
843
    return result;
844
}
845
846
// static
847
const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
848
849
17
DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
850
851
17
DispatcherBase::WeakPtr::~WeakPtr()
852
{
853
17
    if (m_dispatcher)
854
17
        m_dispatcher->m_weakPtrs.erase(this);
855
17
}
856
857
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
858
    : m_backendImpl(std::move(backendImpl))
859
    , m_callId(callId)
860
    , m_method(method)
861
    , m_message(message) { }
862
863
DispatcherBase::Callback::~Callback() = default;
864
865
void DispatcherBase::Callback::dispose()
866
{
867
    m_backendImpl = nullptr;
868
}
869
870
void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
871
{
872
    if (!m_backendImpl || !m_backendImpl->get())
873
        return;
874
    m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
875
    m_backendImpl = nullptr;
876
}
877
878
void DispatcherBase::Callback::fallThroughIfActive()
879
{
880
    if (!m_backendImpl || !m_backendImpl->get())
881
        return;
882
    m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
883
    m_backendImpl = nullptr;
884
}
885
886
9734
DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
887
9734
    : m_frontendChannel(frontendChannel) { }
888
889
17944
DispatcherBase::~DispatcherBase()
890
{
891
8972
    clearFrontend();
892
8972
}
893
894
17
void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
895
{
896
17
    if (!m_frontendChannel)
897
        return;
898
17
    if (response.status() == DispatchResponse::kError) {
899
1
        reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
900
1
        return;
901
    }
902
16
    m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
903
}
904
905
16
void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
906
{
907
16
    sendResponse(callId, response, DictionaryValue::create());
908
16
}
909
910
namespace {
911
912
class ProtocolError : public Serializable {
913
public:
914
1
    static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
915
    {
916
1
        std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
917
1
        protocolError->m_callId = callId;
918
1
        protocolError->m_hasCallId = true;
919

1
        if (errors && errors->hasErrors())
920
            protocolError->m_data = errors->errors();
921
1
        return protocolError;
922
    }
923
924
    static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
925
    {
926
        return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
927
    }
928
929
1
    String serializeToJSON() override
930
    {
931
1
        return serialize()->serializeToJSON();
932
    }
933
934
    std::vector<uint8_t> serializeToBinary() override
935
    {
936
        return serialize()->serializeToBinary();
937
    }
938
939
2
    ~ProtocolError() override {}
940
941
private:
942
1
    ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
943
        : m_code(code)
944
1
        , m_errorMessage(errorMessage)
945
    {
946
1
    }
947
948
1
    std::unique_ptr<DictionaryValue> serialize() {
949
1
        std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
950
1
        error->setInteger("code", m_code);
951
1
        error->setString("message", m_errorMessage);
952
1
        if (m_data.length())
953
            error->setString("data", m_data);
954
1
        std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
955
1
        message->setObject("error", std::move(error));
956
1
        if (m_hasCallId)
957
1
            message->setInteger("id", m_callId);
958
1
        return message;
959
    }
960
961
    DispatchResponse::ErrorCode m_code;
962
    String m_errorMessage;
963
    String m_data;
964
    int m_callId = 0;
965
    bool m_hasCallId = false;
966
};
967
968
} // namespace
969
970
1
static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
971
{
972
1
    if (frontendChannel)
973
1
        frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
974
1
}
975
976
static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
977
{
978
    if (frontendChannel)
979
        frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
980
}
981
982
1
void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
983
{
984
1
    reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
985
1
}
986
987
8972
void DispatcherBase::clearFrontend()
988
{
989
8972
    m_frontendChannel = nullptr;
990
8972
    for (auto& weak : m_weakPtrs)
991
        weak->dispose();
992
8972
    m_weakPtrs.clear();
993
8972
}
994
995
17
std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
996
{
997
17
    std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
998
17
    m_weakPtrs.insert(weak.get());
999
17
    return weak;
1000
}
1001
1002
4867
UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
1003
4867
    : m_frontendChannel(frontendChannel) { }
1004
1005
9734
void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
1006
{
1007
9734
    m_dispatchers[name] = std::move(dispatcher);
1008
9734
}
1009
1010
9734
void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
1011
{
1012
9734
    for (const auto& pair : redirects)
1013
        m_redirects[pair.first] = pair.second;
1014
9734
}
1015
1016
14320
bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
1017
14320
    if (!parsedMessage) {
1018
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
1019
        return false;
1020
    }
1021
14320
    protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
1022
14320
    if (!messageObject) {
1023
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
1024
        return false;
1025
    }
1026
1027
14320
    int callId = 0;
1028
14320
    protocol::Value* callIdValue = messageObject->get("id");
1029

14320
    bool success = callIdValue && callIdValue->asInteger(&callId);
1030
14320
    if (!success) {
1031
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
1032
        return false;
1033
    }
1034
14320
    if (outCallId)
1035
14320
      *outCallId = callId;
1036
1037
14320
    protocol::Value* methodValue = messageObject->get("method");
1038
14320
    String method;
1039

14320
    success = methodValue && methodValue->asString(&method);
1040
14319
    if (!success) {
1041
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
1042
        return false;
1043
    }
1044
14319
    if (outMethod)
1045
14319
      *outMethod = method;
1046
14320
    return true;
1047
}
1048
1049
17
protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
1050
17
    size_t dotIndex = StringUtil::find(method, ".");
1051
17
    if (dotIndex == StringUtil::kNotFound)
1052
        return nullptr;
1053
17
    String domain = StringUtil::substring(method, 0, dotIndex);
1054
17
    auto it = m_dispatchers.find(domain);
1055
17
    if (it == m_dispatchers.end())
1056
        return nullptr;
1057
17
    if (!it->second->canDispatch(method))
1058
        return nullptr;
1059
17
    return it->second.get();
1060
}
1061
1062
bool UberDispatcher::canDispatch(const String& in_method)
1063
{
1064
    String method = in_method;
1065
    auto redirectIt = m_redirects.find(method);
1066
    if (redirectIt != m_redirects.end())
1067
        method = redirectIt->second;
1068
    return !!findDispatcher(method);
1069
}
1070
1071
17
void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
1072
{
1073
17
    String method = in_method;
1074
17
    auto redirectIt = m_redirects.find(method);
1075
17
    if (redirectIt != m_redirects.end())
1076
        method = redirectIt->second;
1077
17
    protocol::DispatcherBase* dispatcher = findDispatcher(method);
1078
17
    if (!dispatcher) {
1079
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
1080
17
        return;
1081
    }
1082
34
    std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
1083
34
    dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
1084
}
1085
1086
UberDispatcher::~UberDispatcher() = default;
1087
1088
// static
1089
16
std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
1090
{
1091
16
    return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
1092
}
1093
1094
// static
1095
100
std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
1096
{
1097
100
    return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
1098
}
1099
1100
116
String InternalResponse::serializeToJSON()
1101
{
1102
116
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
1103

232
    std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
1104
116
    if (m_notification.length()) {
1105
100
        result->setString("method", m_notification);
1106
100
        result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
1107
    } else {
1108
16
        result->setInteger("id", m_callId);
1109
16
        result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
1110
    }
1111
232
    return result->serializeToJSON();
1112
}
1113
1114
std::vector<uint8_t> InternalResponse::serializeToBinary()
1115
{
1116
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
1117
    std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
1118
    if (m_notification.length()) {
1119
        result->setString("method", m_notification);
1120
        result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
1121
    } else {
1122
        result->setInteger("id", m_callId);
1123
        result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
1124
    }
1125
    return result->serializeToBinary();
1126
}
1127
1128
116
InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
1129
    : m_callId(callId)
1130
    , m_notification(notification)
1131
116
    , m_params(params ? std::move(params) : nullptr)
1132
{
1133
116
}
1134
1135
} // namespace node
1136
} // namespace inspector
1137
} // namespace protocol
1138
1139
1140
// This file is generated by Parser_cpp.template.
1141
1142
// Copyright 2016 The Chromium Authors. All rights reserved.
1143
// Use of this source code is governed by a BSD-style license that can be
1144
// found in the LICENSE file.
1145
1146
namespace node {
1147
namespace inspector {
1148
namespace protocol {
1149
1150
namespace {
1151
1152
const int stackLimit = 1000;
1153
1154
enum Token {
1155
    ObjectBegin,
1156
    ObjectEnd,
1157
    ArrayBegin,
1158
    ArrayEnd,
1159
    StringLiteral,
1160
    Number,
1161
    BoolTrue,
1162
    BoolFalse,
1163
    NullToken,
1164
    ListSeparator,
1165
    ObjectPairSeparator,
1166
    InvalidToken,
1167
};
1168
1169
const char* const nullString = "null";
1170
const char* const trueString = "true";
1171
const char* const falseString = "false";
1172
1173
344858
bool isASCII(uint16_t c)
1174
{
1175
344858
    return !(c & ~0x7F);
1176
}
1177
1178
330421
bool isSpaceOrNewLine(uint16_t c)
1179
{
1180


330421
    return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
1181
}
1182
1183
14372
double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
1184
{
1185
14372
    std::vector<char> buffer;
1186
14371
    buffer.reserve(length + 1);
1187
28810
    for (size_t i = 0; i < length; ++i) {
1188
14438
        if (!isASCII(characters[i])) {
1189
            *ok = false;
1190
            return 0;
1191
        }
1192
14438
        buffer.push_back(static_cast<char>(characters[i]));
1193
    }
1194
14372
    buffer.push_back('\0');
1195
14372
    return StringUtil::toDouble(buffer.data(), length, ok);
1196
}
1197
1198
double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
1199
{
1200
    std::string buffer(reinterpret_cast<const char*>(characters), length);
1201
    return StringUtil::toDouble(buffer.data(), length, ok);
1202
}
1203
1204
template<typename Char>
1205
9361
bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
1206
{
1207




9361
    while (start < end && *token != '\0' && *start++ == *token++) { }
1208

9361
    if (*token != '\0')
1209
        return false;
1210
9361
    *tokenEnd = start;
1211
9361
    return true;
1212
}
1213
1214
template<typename Char>
1215
14372
bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
1216
{
1217

14372
    if (start == end)
1218
        return false;
1219
14372
    bool haveLeadingZero = '0' == *start;
1220
14372
    int length = 0;
1221



43183
    while (start < end && '0' <= *start && *start <= '9') {
1222
14439
        ++start;
1223
14439
        ++length;
1224
    }
1225

14372
    if (!length)
1226
        return false;
1227



14372
    if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
1228
        return false;
1229
14372
    *tokenEnd = start;
1230
14372
    return true;
1231
}
1232
1233
template<typename Char>
1234
14372
bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
1235
{
1236
    // We just grab the number here. We validate the size in DecodeNumber.
1237
    // According to RFC4627, a valid number is: [minus] int [frac] [exp]
1238

14372
    if (start == end)
1239
        return false;
1240
14372
    Char c = *start;
1241

14372
    if ('-' == c)
1242
        ++start;
1243
1244

14372
    if (!readInt(start, end, &start, false))
1245
        return false;
1246

14372
    if (start == end) {
1247
        *tokenEnd = start;
1248
        return true;
1249
    }
1250
1251
    // Optional fraction part
1252
14372
    c = *start;
1253

14372
    if ('.' == c) {
1254
        ++start;
1255
        if (!readInt(start, end, &start, true))
1256
            return false;
1257
        if (start == end) {
1258
            *tokenEnd = start;
1259
            return true;
1260
        }
1261
        c = *start;
1262
    }
1263
1264
    // Optional exponent part
1265


14372
    if ('e' == c || 'E' == c) {
1266
        ++start;
1267
        if (start == end)
1268
            return false;
1269
        c = *start;
1270
        if ('-' == c || '+' == c) {
1271
            ++start;
1272
            if (start == end)
1273
                return false;
1274
        }
1275
        if (!readInt(start, end, &start, true))
1276
            return false;
1277
    }
1278
1279
14372
    *tokenEnd = start;
1280
14372
    return true;
1281
}
1282
1283
template<typename Char>
1284
bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
1285
{
1286
    if (end - start < digits)
1287
        return false;
1288
    for (int i = 0; i < digits; ++i) {
1289
        Char c = *start++;
1290
        if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
1291
            return false;
1292
    }
1293
    *tokenEnd = start;
1294
    return true;
1295
}
1296
1297
template<typename Char>
1298
57294
bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1299
{
1300

681847
    while (start < end) {
1301
624553
        Char c = *start++;
1302

624553
        if ('\\' == c) {
1303

148
	    if (start == end)
1304
	        return false;
1305
148
            c = *start++;
1306
            // Make sure the escaped char is valid.
1307


148
            switch (c) {
1308
            case 'x':
1309
                if (!readHexDigits(start, end, &start, 2))
1310
                    return false;
1311
                break;
1312
            case 'u':
1313
                if (!readHexDigits(start, end, &start, 4))
1314
                    return false;
1315
                break;
1316
            case '\\':
1317
            case '/':
1318
            case 'b':
1319
            case 'f':
1320
            case 'n':
1321
            case 'r':
1322
            case 't':
1323
            case 'v':
1324
            case '"':
1325
148
                break;
1326
            default:
1327
                return false;
1328
            }
1329

624405
        } else if ('"' == c) {
1330
57294
            *tokenEnd = start;
1331
57294
            return true;
1332
        }
1333
    }
1334
    return false;
1335
}
1336
1337
template<typename Char>
1338
bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
1339
{
1340
    if (start == end)
1341
        return false;
1342
1343
    if (*start != '/' || start + 1 >= end)
1344
        return false;
1345
    ++start;
1346
1347
    if (*start == '/') {
1348
        // Single line comment, read to newline.
1349
        for (++start; start < end; ++start) {
1350
            if (*start == '\n' || *start == '\r') {
1351
                *commentEnd = start + 1;
1352
                return true;
1353
            }
1354
        }
1355
        *commentEnd = end;
1356
        // Comment reaches end-of-input, which is fine.
1357
        return true;
1358
    }
1359
1360
    if (*start == '*') {
1361
        Char previous = '\0';
1362
        // Block comment, read until end marker.
1363
        for (++start; start < end; previous = *start++) {
1364
            if (previous == '*' && *start == '/') {
1365
                *commentEnd = start + 1;
1366
                return true;
1367
            }
1368
        }
1369
        // Block comment must close before end-of-input.
1370
        return false;
1371
    }
1372
1373
    return false;
1374
}
1375
1376
template<typename Char>
1377
243137
void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1378
{
1379

587881
    while (start < end) {
1380

330420
        if (isSpaceOrNewLine(*start)) {
1381
101607
            ++start;
1382

228816
        } else if (*start == '/') {
1383
            const Char* commentEnd;
1384
            if (!skipComment(start, end, &commentEnd))
1385
                break;
1386
            start = commentEnd;
1387
        } else {
1388
228816
            break;
1389
        }
1390
    }
1391
243140
    *whitespaceEnd = start;
1392
243140
}
1393
1394
template<typename Char>
1395
185918
Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1396
{
1397
185918
    skipWhitespaceAndComments(start, end, tokenStart);
1398
185918
    start = *tokenStart;
1399
1400

185918
    if (start == end)
1401
        return InvalidToken;
1402
1403






185918
    switch (*start) {
1404
    case 'n':
1405

1
        if (parseConstToken(start, end, tokenEnd, nullString))
1406
1
            return NullToken;
1407
        break;
1408
    case 't':
1409

9326
        if (parseConstToken(start, end, tokenEnd, trueString))
1410
9326
            return BoolTrue;
1411
        break;
1412
    case 'f':
1413

34
        if (parseConstToken(start, end, tokenEnd, falseString))
1414
34
            return BoolFalse;
1415
        break;
1416
    case '[':
1417
12
        *tokenEnd = start + 1;
1418
12
        return ArrayBegin;
1419
    case ']':
1420
12
        *tokenEnd = start + 1;
1421
12
        return ArrayEnd;
1422
    case ',':
1423
23816
        *tokenEnd = start + 1;
1424
23816
        return ListSeparator;
1425
    case '{':
1426
19078
        *tokenEnd = start + 1;
1427
19078
        return ObjectBegin;
1428
    case '}':
1429
19078
        *tokenEnd = start + 1;
1430
19078
        return ObjectEnd;
1431
    case ':':
1432
42894
        *tokenEnd = start + 1;
1433
42894
        return ObjectPairSeparator;
1434
    case '0':
1435
    case '1':
1436
    case '2':
1437
    case '3':
1438
    case '4':
1439
    case '5':
1440
    case '6':
1441
    case '7':
1442
    case '8':
1443
    case '9':
1444
    case '-':
1445

14372
        if (parseNumberToken(start, end, tokenEnd))
1446
14372
            return Number;
1447
        break;
1448
    case '"':
1449

57295
        if (parseStringToken(start + 1, end, tokenEnd))
1450
57294
            return StringLiteral;
1451
        break;
1452
    }
1453
    return InvalidToken;
1454
}
1455
1456
template<typename Char>
1457
int hexToInt(Char c)
1458
{
1459
    if ('0' <= c && c <= '9')
1460
        return c - '0';
1461
    if ('A' <= c && c <= 'F')
1462
        return c - 'A' + 10;
1463
    if ('a' <= c && c <= 'f')
1464
        return c - 'a' + 10;
1465
    DCHECK(false);
1466
    return 0;
1467
}
1468
1469
template<typename Char>
1470
57283
bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1471
{
1472

681786
    while (start < end) {
1473
567219
        uint16_t c = *start++;
1474

567219
        if ('\\' != c) {
1475
567071
            StringUtil::builderAppend(*output, c);
1476
567072
            continue;
1477
        }
1478

148
	if (start == end)
1479
	    return false;
1480
148
        c = *start++;
1481
1482

148
        if (c == 'x') {
1483
            // \x is not supported.
1484
            return false;
1485
        }
1486
1487




148
        switch (c) {
1488
        case '"':
1489
        case '/':
1490
        case '\\':
1491
134
            break;
1492
        case 'b':
1493
            c = '\b';
1494
            break;
1495
        case 'f':
1496
            c = '\f';
1497
            break;
1498
        case 'n':
1499
14
            c = '\n';
1500
14
            break;
1501
        case 'r':
1502
            c = '\r';
1503
            break;
1504
        case 't':
1505
            c = '\t';
1506
            break;
1507
        case 'v':
1508
            c = '\v';
1509
            break;
1510
        case 'u':
1511
            c = (hexToInt(*start) << 12) +
1512
                (hexToInt(*(start + 1)) << 8) +
1513
                (hexToInt(*(start + 2)) << 4) +
1514
                hexToInt(*(start + 3));
1515
            start += 4;
1516
            break;
1517
        default:
1518
            return false;
1519
        }
1520
148
        StringUtil::builderAppend(*output, c);
1521
    }
1522
57284
    return true;
1523
}
1524
1525
template<typename Char>
1526
57290
bool decodeString(const Char* start, const Char* end, String* output)
1527
{
1528

57290
    if (start == end) {
1529
6
        *output = "";
1530
6
        return true;
1531
    }
1532

57284
    if (start > end)
1533
        return false;
1534
57284
    StringBuilder buffer;
1535
57284
    StringUtil::builderReserve(buffer, end - start);
1536

57283
    if (!decodeString(start, end, &buffer))
1537
        return false;
1538
57284
    *output = StringUtil::builderToString(buffer);
1539
57284
    return true;
1540
}
1541
1542
template<typename Char>
1543
57219
std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1544
{
1545

57219
    if (depth > stackLimit)
1546
        return nullptr;
1547
1548
57219
    std::unique_ptr<Value> result;
1549
    const Char* tokenStart;
1550
    const Char* tokenEnd;
1551
57219
    Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1552




57218
    switch (token) {
1553
    case InvalidToken:
1554
        return nullptr;
1555
    case NullToken:
1556
1
        result = Value::null();
1557
1
        break;
1558
    case BoolTrue:
1559
9326
        result = FundamentalValue::create(true);
1560
9326
        break;
1561
    case BoolFalse:
1562
34
        result = FundamentalValue::create(false);
1563
34
        break;
1564
    case Number: {
1565
        bool ok;
1566
14371
        double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1567

14372
        if (!ok)
1568
            return nullptr;
1569



14372
        if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value)
1570
14372
            result = FundamentalValue::create(static_cast<int>(value));
1571
        else
1572
            result = FundamentalValue::create(value);
1573
14372
        break;
1574
    }
1575
    case StringLiteral: {
1576
14396
        String value;
1577
14396
        bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1578

14396
        if (!ok)
1579
            return nullptr;
1580
14396
        result = StringValue::create(value);
1581

14396
        break;
1582
    }
1583
    case ArrayBegin: {
1584
12
        std::unique_ptr<ListValue> array = ListValue::create();
1585
12
        start = tokenEnd;
1586
12
        token = parseToken(start, end, &tokenStart, &tokenEnd);
1587

5
        while (token != ArrayEnd) {
1588
5
            std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
1589

5
            if (!arrayNode)
1590
                return nullptr;
1591
5
            array->pushValue(std::move(arrayNode));
1592
1593
            // After a list value, we expect a comma or the end of the list.
1594
5
            start = tokenEnd;
1595
5
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1596

5
            if (token == ListSeparator) {
1597
                start = tokenEnd;
1598
                token = parseToken(start, end, &tokenStart, &tokenEnd);
1599
                if (token == ArrayEnd)
1600
                    return nullptr;
1601

5
            } else if (token != ArrayEnd) {
1602
                // Unexpected value after list value. Bail out.
1603
                return nullptr;
1604
            }
1605
        }
1606

12
        if (token != ArrayEnd)
1607
            return nullptr;
1608
12
        result = std::move(array);
1609

12
        break;
1610
    }
1611
    case ObjectBegin: {
1612
19078
        std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1613
19078
        start = tokenEnd;
1614
19078
        token = parseToken(start, end, &tokenStart, &tokenEnd);
1615

61971
        while (token != ObjectEnd) {
1616

42893
            if (token != StringLiteral)
1617
                return nullptr;
1618
42893
            String key;
1619

42893
            if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1620
                return nullptr;
1621
42894
            start = tokenEnd;
1622
1623
42894
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1624

42894
            if (token != ObjectPairSeparator)
1625
                return nullptr;
1626
42894
            start = tokenEnd;
1627
1628

85788
            std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1);
1629

42894
            if (!value)
1630
                return nullptr;
1631
42894
            object->setValue(key, std::move(value));
1632
42894
            start = tokenEnd;
1633
1634
            // After a key/value pair, we expect a comma or the end of the
1635
            // object.
1636
42894
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1637

42895
            if (token == ListSeparator) {
1638
23816
                start = tokenEnd;
1639
23816
                token = parseToken(start, end, &tokenStart, &tokenEnd);
1640

23815
                if (token == ObjectEnd)
1641
                    return nullptr;
1642

19079
            } else if (token != ObjectEnd) {
1643
                // Unexpected value after last object value. Bail out.
1644
                return nullptr;
1645
            }
1646
        }
1647

19078
        if (token != ObjectEnd)
1648
            return nullptr;
1649
19078
        result = std::move(object);
1650

19078
        break;
1651
    }
1652
1653
    default:
1654
        // We got a token that's not a value.
1655
        return nullptr;
1656
    }
1657
1658
57219
    skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1659
57219
    return result;
1660
}
1661
1662
template<typename Char>
1663
14320
std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1664
{
1665
14320
    const Char* end = start + length;
1666
    const Char *tokenEnd;
1667
14320
    std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1668



14320
    if (!value || tokenEnd != end)
1669
        return nullptr;
1670
14320
    return value;
1671
}
1672
1673
} // anonymous namespace
1674
1675
14320
std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1676
{
1677
14320
    return parseJSONInternal<uint16_t>(characters, length);
1678
}
1679
1680
std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
1681
{
1682
    return parseJSONInternal<uint8_t>(characters, length);
1683
}
1684
1685
} // namespace node
1686
} // namespace inspector
1687
} // namespace protocol
1688
1689
1690
// Generated by lib/CBOR_cpp.template.
1691
1692
// Copyright 2019 The Chromium Authors. All rights reserved.
1693
// Use of this source code is governed by a BSD-style license that can be
1694
// found in the LICENSE file.
1695
1696
1697
#include <cassert>
1698
#include <limits>
1699
1700
namespace node {
1701
namespace inspector {
1702
namespace protocol {
1703
1704
// ===== encoding/cbor.cc =====
1705
1706
using namespace cbor;
1707
1708
namespace {
1709
1710
// See RFC 7049 Section 2.3, Table 2.
1711
static constexpr uint8_t kEncodedTrue =
1712
    EncodeInitialByte(MajorType::SIMPLE_VALUE, 21);
1713
static constexpr uint8_t kEncodedFalse =
1714
    EncodeInitialByte(MajorType::SIMPLE_VALUE, 20);
1715
static constexpr uint8_t kEncodedNull =
1716
    EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
1717
static constexpr uint8_t kInitialByteForDouble =
1718
    EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
1719
1720
}  // namespace
1721
1722
uint8_t EncodeTrue() { return kEncodedTrue; }
1723
uint8_t EncodeFalse() { return kEncodedFalse; }
1724
uint8_t EncodeNull() { return kEncodedNull; }
1725
1726
uint8_t EncodeIndefiniteLengthArrayStart() {
1727
  return kInitialByteIndefiniteLengthArray;
1728
}
1729
1730
uint8_t EncodeIndefiniteLengthMapStart() {
1731
  return kInitialByteIndefiniteLengthMap;
1732
}
1733
1734
uint8_t EncodeStop() { return kStopByte; }
1735
1736
namespace {
1737
// See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
1738
// arbitrary binary data encoded as BYTE_STRING.
1739
static constexpr uint8_t kExpectedConversionToBase64Tag =
1740
    EncodeInitialByte(MajorType::TAG, 22);
1741
1742
// When parsing CBOR, we limit recursion depth for objects and arrays
1743
// to this constant.
1744
static constexpr int kStackLimit = 1000;
1745
1746
// Writes the bytes for |v| to |out|, starting with the most significant byte.
1747
// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1748
template <typename T>
1749
void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) {
1750
  for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes)
1751
    out->push_back(0xff & (v >> (shift_bytes * 8)));
1752
}
1753
}  // namespace
1754
1755
namespace cbor_internals {
1756
// Writes the start of a token with |type|. The |value| may indicate the size,
1757
// or it may be the payload if the value is an unsigned integer.
1758
void WriteTokenStart(MajorType type, uint64_t value,
1759
                     std::vector<uint8_t>* encoded) {
1760
  if (value < 24) {
1761
    // Values 0-23 are encoded directly into the additional info of the
1762
    // initial byte.
1763
    encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value));
1764
    return;
1765
  }
1766
  if (value <= std::numeric_limits<uint8_t>::max()) {
1767
    // Values 24-255 are encoded with one initial byte, followed by the value.
1768
    encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte));
1769
    encoded->push_back(value);
1770
    return;
1771
  }
1772
  if (value <= std::numeric_limits<uint16_t>::max()) {
1773
    // Values 256-65535: 1 initial byte + 2 bytes payload.
1774
    encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes));
1775
    WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded);
1776
    return;
1777
  }
1778
  if (value <= std::numeric_limits<uint32_t>::max()) {
1779
    // 32 bit uint: 1 initial byte + 4 bytes payload.
1780
    encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes));
1781
    WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value),
1782
                                                 encoded);
1783
    return;
1784
  }
1785
  // 64 bit uint: 1 initial byte + 8 bytes payload.
1786
  encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes));
1787
  WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded);
1788
}
1789
}  // namespace cbor_internals
1790
1791
namespace {
1792
// Extracts sizeof(T) bytes from |in| to extract a value of type T
1793
// (e.g. uint64_t, uint32_t, ...), most significant byte first.
1794
// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1795
template <typename T>
1796
T ReadBytesMostSignificantByteFirst(span<uint8_t> in) {
1797
  assert(static_cast<std::size_t>(in.size()) >= sizeof(T));
1798
  T result = 0;
1799
  for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes)
1800
    result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8);
1801
  return result;
1802
}
1803
}  // namespace
1804
1805
namespace cbor_internals {
1806
int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
1807
  if (bytes.empty()) return -1;
1808
  uint8_t initial_byte = bytes[0];
1809
  *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
1810
1811
  uint8_t additional_information = initial_byte & kAdditionalInformationMask;
1812
  if (additional_information < 24) {
1813
    // Values 0-23 are encoded directly into the additional info of the
1814
    // initial byte.
1815
    *value = additional_information;
1816
    return 1;
1817
  }
1818
  if (additional_information == kAdditionalInformation1Byte) {
1819
    // Values 24-255 are encoded with one initial byte, followed by the value.
1820
    if (bytes.size() < 2) return -1;
1821
    *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
1822
    return 2;
1823
  }
1824
  if (additional_information == kAdditionalInformation2Bytes) {
1825
    // Values 256-65535: 1 initial byte + 2 bytes payload.
1826
    if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t))
1827
      return -1;
1828
    *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
1829
    return 3;
1830
  }
1831
  if (additional_information == kAdditionalInformation4Bytes) {
1832
    // 32 bit uint: 1 initial byte + 4 bytes payload.
1833
    if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t))
1834
      return -1;
1835
    *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
1836
    return 5;
1837
  }
1838
  if (additional_information == kAdditionalInformation8Bytes) {
1839
    // 64 bit uint: 1 initial byte + 8 bytes payload.
1840
    if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t))
1841
      return -1;
1842
    *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
1843
    return 9;
1844
  }
1845
  return -1;
1846
}
1847
}  // namespace cbor_internals
1848
1849
using cbor_internals::WriteTokenStart;
1850
using cbor_internals::ReadTokenStart;
1851
1852
void EncodeInt32(int32_t value, std::vector<uint8_t>* out) {
1853
  if (value >= 0) {
1854
    WriteTokenStart(MajorType::UNSIGNED, value, out);
1855
  } else {
1856
    uint64_t representation = static_cast<uint64_t>(-(value + 1));
1857
    WriteTokenStart(MajorType::NEGATIVE, representation, out);
1858
  }
1859
}
1860
1861
void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) {
1862
  uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
1863
  WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
1864
  // When emitting UTF16 characters, we always write the least significant byte
1865
  // first; this is because it's the native representation for X86.
1866
  // TODO(johannes): Implement a more efficient thing here later, e.g.
1867
  // casting *iff* the machine has this byte order.
1868
  // The wire format for UTF16 chars will probably remain the same
1869
  // (least significant byte first) since this way we can have
1870
  // golden files, unittests, etc. that port easily and universally.
1871
  // See also:
1872
  // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
1873
  for (const uint16_t two_bytes : in) {
1874
    out->push_back(two_bytes);
1875
    out->push_back(two_bytes >> 8);
1876
  }
1877
}
1878
1879
void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) {
1880
  WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(in.size_bytes()),
1881
                  out);
1882
  out->insert(out->end(), in.begin(), in.end());
1883
}
1884
1885
void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) {
1886
  out->push_back(kExpectedConversionToBase64Tag);
1887
  uint64_t byte_length = static_cast<uint64_t>(in.size_bytes());
1888
  WriteTokenStart(MajorType::BYTE_STRING, byte_length, out);
1889
  out->insert(out->end(), in.begin(), in.end());
1890
}
1891
1892
// A double is encoded with a specific initial byte
1893
// (kInitialByteForDouble) plus the 64 bits of payload for its value.
1894
constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t);
1895
1896
// An envelope is encoded with a specific initial byte
1897
// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32
1898
// bit wide length, plus a 32 bit length for that string.
1899
constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t);
1900
1901
void EncodeDouble(double value, std::vector<uint8_t>* out) {
1902
  // The additional_info=27 indicates 64 bits for the double follow.
1903
  // See RFC 7049 Section 2.3, Table 1.
1904
  out->push_back(kInitialByteForDouble);
1905
  union {
1906
    double from_double;
1907
    uint64_t to_uint64;
1908
  } reinterpret;
1909
  reinterpret.from_double = value;
1910
  WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out);
1911
}
1912
1913
void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) {
1914
  assert(byte_size_pos_ == 0);
1915
  out->push_back(kInitialByteForEnvelope);
1916
  out->push_back(kInitialByteFor32BitLengthByteString);
1917
  byte_size_pos_ = out->size();
1918
  out->resize(out->size() + sizeof(uint32_t));
1919
}
1920
1921
bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) {
1922
  assert(byte_size_pos_ != 0);
1923
  // The byte size is the size of the payload, that is, all the
1924
  // bytes that were written past the byte size position itself.
1925
  uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t));
1926
  // We store exactly 4 bytes, so at most INT32MAX, with most significant
1927
  // byte first.
1928
  if (byte_size > std::numeric_limits<uint32_t>::max()) return false;
1929
  for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0;
1930
       --shift_bytes) {
1931
    (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8));
1932
  }
1933
  return true;
1934
}
1935
1936
namespace {
1937
class JSONToCBOREncoder : public JSONParserHandler {
1938
 public:
1939
  JSONToCBOREncoder(std::vector<uint8_t>* out, Status* status)
1940
      : out_(out), status_(status) {
1941
    *status_ = Status();
1942
  }
1943
1944
  void HandleObjectBegin() override {
1945
    envelopes_.emplace_back();
1946
    envelopes_.back().EncodeStart(out_);
1947
    out_->push_back(kInitialByteIndefiniteLengthMap);
1948
  }
1949
1950
  void HandleObjectEnd() override {
1951
    out_->push_back(kStopByte);
1952
    assert(!envelopes_.empty());
1953
    envelopes_.back().EncodeStop(out_);
1954
    envelopes_.pop_back();
1955
  }
1956
1957
  void HandleArrayBegin() override {
1958
    envelopes_.emplace_back();
1959
    envelopes_.back().EncodeStart(out_);
1960
    out_->push_back(kInitialByteIndefiniteLengthArray);
1961
  }
1962
1963
  void HandleArrayEnd() override {
1964
    out_->push_back(kStopByte);
1965
    assert(!envelopes_.empty());
1966
    envelopes_.back().EncodeStop(out_);
1967
    envelopes_.pop_back();
1968
  }
1969
1970
  void HandleString16(std::vector<uint16_t> chars) override {
1971
    for (uint16_t ch : chars) {
1972
      if (ch >= 0x7f) {
1973
        // If there's at least one non-7bit character, we encode as UTF16.
1974
        EncodeString16(span<uint16_t>(chars.data(), chars.size()), out_);
1975
        return;
1976
      }
1977
    }
1978
    std::vector<uint8_t> sevenbit_chars(chars.begin(), chars.end());
1979
    EncodeString8(span<uint8_t>(sevenbit_chars.data(), sevenbit_chars.size()),
1980
                  out_);
1981
  }
1982
1983
  void HandleBinary(std::vector<uint8_t> bytes) override {
1984
    EncodeBinary(span<uint8_t>(bytes.data(), bytes.size()), out_);
1985
  }
1986
1987
  void HandleDouble(double value) override { EncodeDouble(value, out_); }
1988
1989
  void HandleInt32(int32_t value) override { EncodeInt32(value, out_); }
1990
1991
  void HandleBool(bool value) override {
1992
    // See RFC 7049 Section 2.3, Table 2.
1993
    out_->push_back(value ? kEncodedTrue : kEncodedFalse);
1994
  }
1995
1996
  void HandleNull() override {
1997
    // See RFC 7049 Section 2.3, Table 2.
1998
    out_->push_back(kEncodedNull);
1999
  }
2000
2001
  void HandleError(Status error) override {
2002
    assert(!error.ok());
2003
    *status_ = error;
2004
    out_->clear();
2005
  }
2006
2007
 private:
2008
  std::vector<uint8_t>* out_;
2009
  std::vector<EnvelopeEncoder> envelopes_;
2010
  Status* status_;
2011
};
2012
}  // namespace
2013
2014
std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder(
2015
    std::vector<uint8_t>* out, Status* status) {
2016
  return std::unique_ptr<JSONParserHandler>(new JSONToCBOREncoder(out, status));
2017
}
2018
2019
namespace {
2020
// Below are three parsing routines for CBOR, which cover enough
2021
// to roundtrip JSON messages.
2022
bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer,
2023
              JSONParserHandler* out);
2024
bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer,
2025
                JSONParserHandler* out);
2026
bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer,
2027
                JSONParserHandler* out);
2028
2029
void ParseUTF16String(CBORTokenizer* tokenizer, JSONParserHandler* out) {
2030
  std::vector<uint16_t> value;
2031
  span<uint8_t> rep = tokenizer->GetString16WireRep();
2032
  for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2)
2033
    value.push_back((rep[ii + 1] << 8) | rep[ii]);
2034
  out->HandleString16(std::move(value));
2035
  tokenizer->Next();
2036
}
2037
2038
// For now this method only covers US-ASCII. Later, we may allow UTF8.
2039
bool ParseASCIIString(CBORTokenizer* tokenizer, JSONParserHandler* out) {
2040
  assert(tokenizer->TokenTag() == CBORTokenTag::STRING8);
2041
  std::vector<uint16_t> value16;
2042
  for (uint8_t ch : tokenizer->GetString8()) {
2043
    // We only accept us-ascii (7 bit) strings here. Other strings must
2044
    // be encoded with 16 bit (the BYTE_STRING case).
2045
    if (ch >= 0x7f) {
2046
      out->HandleError(
2047
          Status{Error::CBOR_STRING8_MUST_BE_7BIT, tokenizer->Status().pos});
2048
      return false;
2049
    }
2050
    value16.push_back(ch);
2051
  }
2052
  out->HandleString16(std::move(value16));
2053
  tokenizer->Next();
2054
  return true;
2055
}
2056
2057
bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer,
2058
                JSONParserHandler* out) {
2059
  if (stack_depth > kStackLimit) {
2060
    out->HandleError(
2061
        Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
2062
    return false;
2063
  }
2064
  // Skip past the envelope to get to what's inside.
2065
  if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
2066
    tokenizer->EnterEnvelope();
2067
  switch (tokenizer->TokenTag()) {
2068
    case CBORTokenTag::ERROR_VALUE:
2069
      out->HandleError(tokenizer->Status());
2070
      return false;
2071
    case CBORTokenTag::DONE:
2072
      out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
2073
                              tokenizer->Status().pos});
2074
      return false;
2075
    case CBORTokenTag::TRUE_VALUE:
2076
      out->HandleBool(true);
2077
      tokenizer->Next();
2078
      return true;
2079
    case CBORTokenTag::FALSE_VALUE:
2080
      out->HandleBool(false);
2081
      tokenizer->Next();
2082
      return true;
2083
    case CBORTokenTag::NULL_VALUE:
2084
      out->HandleNull();
2085
      tokenizer->Next();
2086
      return true;
2087
    case CBORTokenTag::INT32:
2088
      out->HandleInt32(tokenizer->GetInt32());
2089
      tokenizer->Next();
2090
      return true;
2091
    case CBORTokenTag::DOUBLE:
2092
      out->HandleDouble(tokenizer->GetDouble());
2093
      tokenizer->Next();
2094
      return true;
2095
    case CBORTokenTag::STRING8:
2096
      return ParseASCIIString(tokenizer, out);
2097
    case CBORTokenTag::STRING16:
2098
      ParseUTF16String(tokenizer, out);
2099
      return true;
2100
    case CBORTokenTag::BINARY: {
2101
      span<uint8_t> binary = tokenizer->GetBinary();
2102
      out->HandleBinary(std::vector<uint8_t>(binary.begin(), binary.end()));
2103
      tokenizer->Next();
2104
      return true;
2105
    }
2106
    case CBORTokenTag::MAP_START:
2107
      return ParseMap(stack_depth + 1, tokenizer, out);
2108
    case CBORTokenTag::ARRAY_START:
2109
      return ParseArray(stack_depth + 1, tokenizer, out);
2110
    default:
2111
      out->HandleError(
2112
          Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos});
2113
      return false;
2114
  }
2115
}
2116
2117
// |bytes| must start with the indefinite length array byte, so basically,
2118
// ParseArray may only be called after an indefinite length array has been
2119
// detected.
2120
bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer,
2121
                JSONParserHandler* out) {
2122
  assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START);
2123
  tokenizer->Next();
2124
  out->HandleArrayBegin();
2125
  while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2126
    if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2127
      out->HandleError(
2128
          Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
2129
      return false;
2130
    }
2131
    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2132
      out->HandleError(tokenizer->Status());
2133
      return false;
2134
    }
2135
    // Parse value.
2136
    if (!ParseValue(stack_depth, tokenizer, out)) return false;
2137
  }
2138
  out->HandleArrayEnd();
2139
  tokenizer->Next();
2140
  return true;
2141
}
2142
2143
// |bytes| must start with the indefinite length array byte, so basically,
2144
// ParseArray may only be called after an indefinite length array has been
2145
// detected.
2146
bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer,
2147
              JSONParserHandler* out) {
2148
  assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START);
2149
  out->HandleObjectBegin();
2150
  tokenizer->Next();
2151
  while (tokenizer->TokenTag() != CBORTokenTag::STOP) {
2152
    if (tokenizer->TokenTag() == CBORTokenTag::DONE) {
2153
      out->HandleError(
2154
          Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
2155
      return false;
2156
    }
2157
    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
2158
      out->HandleError(tokenizer->Status());
2159
      return false;
2160
    }
2161
    // Parse key.
2162
    if (tokenizer->TokenTag() == CBORTokenTag::STRING8) {
2163
      if (!ParseASCIIString(tokenizer, out)) return false;
2164
    } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) {
2165
      ParseUTF16String(tokenizer, out);
2166
    } else {
2167
      out->HandleError(
2168
          Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos});
2169
      return false;
2170
    }
2171
    // Parse value.
2172
    if (!ParseValue(stack_depth, tokenizer, out)) return false;
2173
  }
2174
  out->HandleObjectEnd();
2175
  tokenizer->Next();
2176
  return true;
2177
}
2178
}  // namespace
2179
2180
void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out) {
2181
  if (bytes.empty()) {
2182
    json_out->HandleError(Status{Error::CBOR_NO_INPUT, 0});
2183
    return;
2184
  }
2185
  if (bytes[0] != kInitialByteForEnvelope) {
2186
    json_out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0});
2187
    return;
2188
  }
2189
  CBORTokenizer tokenizer(bytes);
2190
  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2191
    json_out->HandleError(tokenizer.Status());
2192
    return;
2193
  }
2194
  // We checked for the envelope start byte above, so the tokenizer
2195
  // must agree here, since it's not an error.
2196
  assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
2197
  tokenizer.EnterEnvelope();
2198
  if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
2199
    json_out->HandleError(
2200
        Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
2201
    return;
2202
  }
2203
  if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return;
2204
  if (tokenizer.TokenTag() == CBORTokenTag::DONE) return;
2205
  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
2206
    json_out->HandleError(tokenizer.Status());
2207
    return;
2208
  }
2209
  json_out->HandleError(
2210
      Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos});
2211
}
2212
2213
CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) {
2214
  ReadNextToken(/*enter_envelope=*/false);
2215
}
2216
CBORTokenizer::~CBORTokenizer() {}
2217
2218
CBORTokenTag CBORTokenizer::TokenTag() const { return token_tag_; }
2219
2220
void CBORTokenizer::Next() {
2221
  if (token_tag_ == CBORTokenTag::ERROR_VALUE || token_tag_ == CBORTokenTag::DONE)
2222
    return;
2223
  ReadNextToken(/*enter_envelope=*/false);
2224
}
2225
2226
void CBORTokenizer::EnterEnvelope() {
2227
  assert(token_tag_ == CBORTokenTag::ENVELOPE);
2228
  ReadNextToken(/*enter_envelope=*/true);
2229
}
2230
2231
Status CBORTokenizer::Status() const { return status_; }
2232
2233
int32_t CBORTokenizer::GetInt32() const {
2234
  assert(token_tag_ == CBORTokenTag::INT32);
2235
  // The range checks happen in ::ReadNextToken().
2236
  return static_cast<uint32_t>(
2237
      token_start_type_ == MajorType::UNSIGNED
2238
          ? token_start_internal_value_
2239
          : -static_cast<int64_t>(token_start_internal_value_) - 1);
2240
}
2241
2242
double CBORTokenizer::GetDouble() const {
2243
  assert(token_tag_ == CBORTokenTag::DOUBLE);
2244
  union {
2245
    uint64_t from_uint64;
2246
    double to_double;
2247
  } reinterpret;
2248
  reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>(
2249
      bytes_.subspan(status_.pos + 1));
2250
  return reinterpret.to_double;
2251
}
2252
2253
span<uint8_t> CBORTokenizer::GetString8() const {
2254
  assert(token_tag_ == CBORTokenTag::STRING8);
2255
  auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2256
  return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2257
}
2258
2259
span<uint8_t> CBORTokenizer::GetString16WireRep() const {
2260
  assert(token_tag_ == CBORTokenTag::STRING16);
2261
  auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2262
  return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2263
}
2264
2265
span<uint8_t> CBORTokenizer::GetBinary() const {
2266
  assert(token_tag_ == CBORTokenTag::BINARY);
2267
  auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2268
  return bytes_.subspan(status_.pos + (token_byte_length_ - length), length);
2269
}
2270
2271
void CBORTokenizer::ReadNextToken(bool enter_envelope) {
2272
  if (enter_envelope) {
2273
    status_.pos += kEncodedEnvelopeHeaderSize;
2274
  } else {
2275
    status_.pos =
2276
        status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_;
2277
  }
2278
  status_.error = Error::OK;
2279
  if (status_.pos >= bytes_.size()) {
2280
    token_tag_ = CBORTokenTag::DONE;
2281
    return;
2282
  }
2283
  switch (bytes_[status_.pos]) {
2284
    case kStopByte:
2285
      SetToken(CBORTokenTag::STOP, 1);
2286
      return;
2287
    case kInitialByteIndefiniteLengthMap:
2288
      SetToken(CBORTokenTag::MAP_START, 1);
2289
      return;
2290
    case kInitialByteIndefiniteLengthArray:
2291
      SetToken(CBORTokenTag::ARRAY_START, 1);
2292
      return;
2293
    case kEncodedTrue:
2294
      SetToken(CBORTokenTag::TRUE_VALUE, 1);
2295
      return;
2296
    case kEncodedFalse:
2297
      SetToken(CBORTokenTag::FALSE_VALUE, 1);
2298
      return;
2299
    case kEncodedNull:
2300
      SetToken(CBORTokenTag::NULL_VALUE, 1);
2301
      return;
2302
    case kExpectedConversionToBase64Tag: {  // BINARY
2303
      int8_t bytes_read =
2304
          ReadTokenStart(bytes_.subspan(status_.pos + 1), &token_start_type_,
2305
                         &token_start_internal_value_);
2306
      int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_;
2307
      if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
2308
          status_.pos + token_byte_length > bytes_.size()) {
2309
        SetError(Error::CBOR_INVALID_BINARY);
2310
        return;
2311
      }
2312
      SetToken(CBORTokenTag::BINARY,
2313
               static_cast<std::ptrdiff_t>(token_byte_length));
2314
      return;
2315
    }
2316
    case kInitialByteForDouble: {  // DOUBLE
2317
      if (status_.pos + kEncodedDoubleSize > bytes_.size()) {
2318
        SetError(Error::CBOR_INVALID_DOUBLE);
2319
        return;
2320
      }
2321
      SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize);
2322
      return;
2323
    }
2324
    case kInitialByteForEnvelope: {  // ENVELOPE
2325
      if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) {
2326
        SetError(Error::CBOR_INVALID_ENVELOPE);
2327
        return;
2328
      }
2329
      // The envelope must be a byte string with 32 bit length.
2330
      if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) {
2331
        SetError(Error::CBOR_INVALID_ENVELOPE);
2332
        return;
2333
      }
2334
      // Read the length of the byte string.
2335
      token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>(
2336
          bytes_.subspan(status_.pos + 2));
2337
      // Make sure the payload is contained within the message.
2338
      if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize +
2339
              status_.pos >
2340
          static_cast<std::size_t>(bytes_.size())) {
2341
        SetError(Error::CBOR_INVALID_ENVELOPE);
2342
        return;
2343
      }
2344
      auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2345
      SetToken(CBORTokenTag::ENVELOPE,
2346
               kEncodedEnvelopeHeaderSize + length);
2347
      return;
2348
    }
2349
    default: {
2350
      span<uint8_t> remainder =
2351
          bytes_.subspan(status_.pos, bytes_.size() - status_.pos);
2352
      assert(!remainder.empty());
2353
      int8_t token_start_length = ReadTokenStart(remainder, &token_start_type_,
2354
                                                 &token_start_internal_value_);
2355
      bool success = token_start_length != -1;
2356
      switch (token_start_type_) {
2357
        case MajorType::UNSIGNED:  // INT32.
2358
          if (!success || std::numeric_limits<int32_t>::max() <
2359
                              token_start_internal_value_) {
2360
            SetError(Error::CBOR_INVALID_INT32);
2361
            return;
2362
          }
2363
          SetToken(CBORTokenTag::INT32, token_start_length);
2364
          return;
2365
        case MajorType::NEGATIVE:  // INT32.
2366
          if (!success ||
2367
              std::numeric_limits<int32_t>::min() >
2368
                  -static_cast<int64_t>(token_start_internal_value_) - 1) {
2369
            SetError(Error::CBOR_INVALID_INT32);
2370
            return;
2371
          }
2372
          SetToken(CBORTokenTag::INT32, token_start_length);
2373
          return;
2374
        case MajorType::STRING: {  // STRING8.
2375
          if (!success || remainder.size() < static_cast<int64_t>(
2376
                                                 token_start_internal_value_)) {
2377
            SetError(Error::CBOR_INVALID_STRING8);
2378
            return;
2379
          }
2380
          auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2381
          SetToken(CBORTokenTag::STRING8, token_start_length + length);
2382
          return;
2383
        }
2384
        case MajorType::BYTE_STRING: {  // STRING16.
2385
          if (!success ||
2386
              remainder.size() <
2387
                  static_cast<int64_t>(token_start_internal_value_) ||
2388
              // Must be divisible by 2 since UTF16 is 2 bytes per character.
2389
              token_start_internal_value_ & 1) {
2390
            SetError(Error::CBOR_INVALID_STRING16);
2391
            return;
2392
          }
2393
          auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_);
2394
          SetToken(CBORTokenTag::STRING16, token_start_length + length);
2395
          return;
2396
        }
2397
        case MajorType::ARRAY:
2398
        case MajorType::MAP:
2399
        case MajorType::TAG:
2400
        case MajorType::SIMPLE_VALUE:
2401
          SetError(Error::CBOR_UNSUPPORTED_VALUE);
2402
          return;
2403
      }
2404
    }
2405
  }
2406
}
2407
2408
void CBORTokenizer::SetToken(CBORTokenTag token_tag,
2409
                             std::ptrdiff_t token_byte_length) {
2410
  token_tag_ = token_tag;
2411
  token_byte_length_ = token_byte_length;
2412
}
2413
2414
void CBORTokenizer::SetError(Error error) {
2415
  token_tag_ = CBORTokenTag::ERROR_VALUE;
2416
  status_.error = error;
2417
}
2418
2419
#if 0
2420
void DumpCBOR(span<uint8_t> cbor) {
2421
  std::string indent;
2422
  CBORTokenizer tokenizer(cbor);
2423
  while (true) {
2424
    fprintf(stderr, "%s", indent.c_str());
2425
    switch (tokenizer.TokenTag()) {
2426
      case CBORTokenTag::ERROR_VALUE:
2427
        fprintf(stderr, "ERROR {status.error=%d, status.pos=%ld}\n",
2428
               tokenizer.Status().error, tokenizer.Status().pos);
2429
        return;
2430
      case CBORTokenTag::DONE:
2431
        fprintf(stderr, "DONE\n");
2432
        return;
2433
      case CBORTokenTag::TRUE_VALUE:
2434
        fprintf(stderr, "TRUE_VALUE\n");
2435
        break;
2436
      case CBORTokenTag::FALSE_VALUE:
2437
        fprintf(stderr, "FALSE_VALUE\n");
2438
        break;
2439
      case CBORTokenTag::NULL_VALUE:
2440
        fprintf(stderr, "NULL_VALUE\n");
2441
        break;
2442
      case CBORTokenTag::INT32:
2443
        fprintf(stderr, "INT32 [%d]\n", tokenizer.GetInt32());
2444
        break;
2445
      case CBORTokenTag::DOUBLE:
2446
        fprintf(stderr, "DOUBLE [%lf]\n", tokenizer.GetDouble());
2447
        break;
2448
      case CBORTokenTag::STRING8: {
2449
        span<uint8_t> v = tokenizer.GetString8();
2450
        std::string t(v.begin(), v.end());
2451
        fprintf(stderr, "STRING8 [%s]\n", t.c_str());
2452
        break;
2453
      }
2454
      case CBORTokenTag::STRING16: {
2455
        span<uint8_t> v = tokenizer.GetString16WireRep();
2456
        std::string t(v.begin(), v.end());
2457
        fprintf(stderr, "STRING16 [%s]\n", t.c_str());
2458
        break;
2459
      }
2460
      case CBORTokenTag::BINARY: {
2461
        span<uint8_t> v = tokenizer.GetBinary();
2462
        std::string t(v.begin(), v.end());
2463
        fprintf(stderr, "BINARY [%s]\n", t.c_str());
2464
        break;
2465
      }
2466
      case CBORTokenTag::MAP_START:
2467
        fprintf(stderr, "MAP_START\n");
2468
        indent += "  ";
2469
        break;
2470
      case CBORTokenTag::ARRAY_START:
2471
        fprintf(stderr, "ARRAY_START\n");
2472
        indent += "  ";
2473
        break;
2474
      case CBORTokenTag::STOP:
2475
        fprintf(stderr, "STOP\n");
2476
        indent.erase(0, 2);
2477
        break;
2478
      case CBORTokenTag::ENVELOPE:
2479
        fprintf(stderr, "ENVELOPE\n");
2480
        tokenizer.EnterEnvelope();
2481
        continue;
2482
    }
2483
    tokenizer.Next();
2484
  }
2485
}
2486
#endif
2487
2488
2489
} // namespace node
2490
} // namespace inspector
2491
} // namespace protocol