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: 188 746 25.2 %
Date: 2019-02-01 22:03:38 Branches: 87 664 13.1 %

Line Branch Exec Source
1
// This file is generated.
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 <cmath>
11
12
#include <cstring>
13
14
15
// Copyright 2016 The Chromium Authors. All rights reserved.
16
// Use of this source code is governed by a BSD-style license that can be
17
// found in the LICENSE file.
18
19
//#include "ErrorSupport.h"
20
21
namespace node {
22
namespace inspector {
23
namespace protocol {
24
25
ErrorSupport::ErrorSupport() { }
26
ErrorSupport::~ErrorSupport() { }
27
28
void ErrorSupport::setName(const char* name)
29
{
30
    setName(String(name));
31
}
32
33
void ErrorSupport::setName(const String& name)
34
{
35
    DCHECK(m_path.size());
36
    m_path[m_path.size() - 1] = name;
37
}
38
39
void ErrorSupport::push()
40
{
41
    m_path.push_back(String());
42
}
43
44
void ErrorSupport::pop()
45
{
46
    m_path.pop_back();
47
}
48
49
void ErrorSupport::addError(const char* error)
50
{
51
    addError(String(error));
52
}
53
54
void ErrorSupport::addError(const String& error)
55
{
56
    StringBuilder builder;
57
    for (size_t i = 0; i < m_path.size(); ++i) {
58
        if (i)
59
            StringUtil::builderAppend(builder, '.');
60
        StringUtil::builderAppend(builder, m_path[i]);
61
    }
62
    StringUtil::builderAppend(builder, ": ");
63
    StringUtil::builderAppend(builder, error);
64
    m_errors.push_back(StringUtil::builderToString(builder));
65
}
66
67
bool ErrorSupport::hasErrors()
68
{
69
    return !!m_errors.size();
70
}
71
72
String ErrorSupport::errors()
73
{
74
    StringBuilder builder;
75
    for (size_t i = 0; i < m_errors.size(); ++i) {
76
        if (i)
77
            StringUtil::builderAppend(builder, "; ");
78
        StringUtil::builderAppend(builder, m_errors[i]);
79
    }
80
    return StringUtil::builderToString(builder);
81
}
82
83
} // namespace node
84
} // namespace inspector
85
} // namespace protocol
86
87
88
// Copyright 2016 The Chromium Authors. All rights reserved.
89
// Use of this source code is governed by a BSD-style license that can be
90
// found in the LICENSE file.
91
92
//#include "Values.h"
93
94
namespace node {
95
namespace inspector {
96
namespace protocol {
97
98
namespace {
99
100
const char* const nullValueString = "null";
101
const char* const trueValueString = "true";
102
const char* const falseValueString = "false";
103
104
inline bool escapeChar(uint16_t c, StringBuilder* dst)
105
{
106
    switch (c) {
107
    case '\b': StringUtil::builderAppend(*dst, "\\b"); break;
108
    case '\f': StringUtil::builderAppend(*dst, "\\f"); break;
109
    case '\n': StringUtil::builderAppend(*dst, "\\n"); break;
110
    case '\r': StringUtil::builderAppend(*dst, "\\r"); break;
111
    case '\t': StringUtil::builderAppend(*dst, "\\t"); break;
112
    case '\\': StringUtil::builderAppend(*dst, "\\\\"); break;
113
    case '"': StringUtil::builderAppend(*dst, "\\\""); break;
114
    default:
115
        return false;
116
    }
117
    return true;
118
}
119
120
const char hexDigits[17] = "0123456789ABCDEF";
121
122
void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
123
{
124
    StringUtil::builderAppend(*dst, "\\u");
125
    for (size_t i = 0; i < 4; ++i) {
126
        uint16_t c = hexDigits[(number & 0xF000) >> 12];
127
        StringUtil::builderAppend(*dst, c);
128
        number <<= 4;
129
    }
130
}
131
132
template <typename Char>
133
void escapeStringForJSONInternal(const Char* str, unsigned len,
134
                                 StringBuilder* dst)
135
{
136
    for (unsigned i = 0; i < len; ++i) {
137
        Char c = str[i];
138
        if (escapeChar(c, dst))
139
            continue;
140
        if (c < 32 || c > 126) {
141
            appendUnsignedAsHex(c, dst);
142
        } else {
143
            StringUtil::builderAppend(*dst, c);
144
        }
145
    }
146
}
147
148
} // anonymous namespace
149
150
bool Value::asBoolean(bool*) const
151
{
152
    return false;
153
}
154
155
bool Value::asDouble(double*) const
156
{
157
    return false;
158
}
159
160
bool Value::asInteger(int*) const
161
{
162
    return false;
163
}
164
165
bool Value::asString(String*) const
166
{
167
    return false;
168
}
169
170
bool Value::asSerialized(String*) const
171
{
172
    return false;
173
}
174
175
void Value::writeJSON(StringBuilder* output) const
176
{
177
    DCHECK(m_type == TypeNull);
178
    StringUtil::builderAppend(*output, nullValueString, 4);
179
}
180
181
std::unique_ptr<Value> Value::clone() const
182
{
183
    return Value::null();
184
}
185
186
String Value::serialize()
187
{
188
    StringBuilder result;
189
    StringUtil::builderReserve(result, 512);
190
    writeJSON(&result);
191
    return StringUtil::builderToString(result);
192
}
193
194
bool FundamentalValue::asBoolean(bool* output) const
195
{
196
    if (type() != TypeBoolean)
197
        return false;
198
    *output = m_boolValue;
199
    return true;
200
}
201
202
bool FundamentalValue::asDouble(double* output) const
203
{
204
    if (type() == TypeDouble) {
205
        *output = m_doubleValue;
206
        return true;
207
    }
208
    if (type() == TypeInteger) {
209
        *output = m_integerValue;
210
        return true;
211
    }
212
    return false;
213
}
214
215
bool FundamentalValue::asInteger(int* output) const
216
{
217
    if (type() != TypeInteger)
218
        return false;
219
    *output = m_integerValue;
220
    return true;
221
}
222
223
void FundamentalValue::writeJSON(StringBuilder* output) const
224
{
225
    DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble);
226
    if (type() == TypeBoolean) {
227
        if (m_boolValue)
228
            StringUtil::builderAppend(*output, trueValueString, 4);
229
        else
230
            StringUtil::builderAppend(*output, falseValueString, 5);
231
    } else if (type() == TypeDouble) {
232
        if (!std::isfinite(m_doubleValue)) {
233
            StringUtil::builderAppend(*output, nullValueString, 4);
234
            return;
235
        }
236
        StringUtil::builderAppend(*output, StringUtil::fromDouble(m_doubleValue));
237
    } else if (type() == TypeInteger) {
238
        StringUtil::builderAppend(*output, StringUtil::fromInteger(m_integerValue));
239
    }
240
}
241
242
std::unique_ptr<Value> FundamentalValue::clone() const
243
{
244
    switch (type()) {
245
    case TypeDouble: return FundamentalValue::create(m_doubleValue);
246
    case TypeInteger: return FundamentalValue::create(m_integerValue);
247
    case TypeBoolean: return FundamentalValue::create(m_boolValue);
248
    default:
249
        DCHECK(false);
250
    }
251
    return nullptr;
252
}
253
254
489
bool StringValue::asString(String* output) const
255
{
256
489
    *output = m_stringValue;
257
489
    return true;
258
}
259
260
void StringValue::writeJSON(StringBuilder* output) const
261
{
262
    DCHECK(type() == TypeString);
263
    StringUtil::builderAppendQuotedString(*output, m_stringValue);
264
}
265
266
std::unique_ptr<Value> StringValue::clone() const
267
{
268
    return StringValue::create(m_stringValue);
269
}
270
271
bool SerializedValue::asSerialized(String* output) const
272
{
273
    *output = m_serializedValue;
274
    return true;
275
}
276
277
void SerializedValue::writeJSON(StringBuilder* output) const
278
{
279
    DCHECK(type() == TypeSerialized);
280
    StringUtil::builderAppend(*output, m_serializedValue);
281
}
282
283
std::unique_ptr<Value> SerializedValue::clone() const
284
{
285
    return SerializedValue::create(m_serializedValue);
286
}
287
288
1304
DictionaryValue::~DictionaryValue()
289
{
290
1304
}
291
292
void DictionaryValue::setBoolean(const String& name, bool value)
293
{
294
    setValue(name, FundamentalValue::create(value));
295
}
296
297
void DictionaryValue::setInteger(const String& name, int value)
298
{
299
    setValue(name, FundamentalValue::create(value));
300
}
301
302
void DictionaryValue::setDouble(const String& name, double value)
303
{
304
    setValue(name, FundamentalValue::create(value));
305
}
306
307
void DictionaryValue::setString(const String& name, const String& value)
308
{
309
    setValue(name, StringValue::create(value));
310
}
311
312
1467
void DictionaryValue::setValue(const String& name, std::unique_ptr<Value> value)
313
{
314
1467
    set(name, value);
315
1467
}
316
317
void DictionaryValue::setObject(const String& name, std::unique_ptr<DictionaryValue> value)
318
{
319
    set(name, value);
320
}
321
322
void DictionaryValue::setArray(const String& name, std::unique_ptr<ListValue> value)
323
{
324
    set(name, value);
325
}
326
327
bool DictionaryValue::getBoolean(const String& name, bool* output) const
328
{
329
    protocol::Value* value = get(name);
330
    if (!value)
331
        return false;
332
    return value->asBoolean(output);
333
}
334
335
bool DictionaryValue::getInteger(const String& name, int* output) const
336
{
337
    Value* value = get(name);
338
    if (!value)
339
        return false;
340
    return value->asInteger(output);
341
}
342
343
bool DictionaryValue::getDouble(const String& name, double* output) const
344
{
345
    Value* value = get(name);
346
    if (!value)
347
        return false;
348
    return value->asDouble(output);
349
}
350
351
489
bool DictionaryValue::getString(const String& name, String* output) const
352
{
353
489
    protocol::Value* value = get(name);
354
489
    if (!value)
355
        return false;
356
489
    return value->asString(output);
357
}
358
359
DictionaryValue* DictionaryValue::getObject(const String& name) const
360
{
361
    return DictionaryValue::cast(get(name));
362
}
363
364
protocol::ListValue* DictionaryValue::getArray(const String& name) const
365
{
366
    return ListValue::cast(get(name));
367
}
368
369
489
protocol::Value* DictionaryValue::get(const String& name) const
370
{
371
489
    Dictionary::const_iterator it = m_data.find(name);
372
489
    if (it == m_data.end())
373
        return nullptr;
374
489
    return it->second.get();
375
}
376
377
DictionaryValue::Entry DictionaryValue::at(size_t index) const
378
{
379
    const String key = m_order[index];
380
    return std::make_pair(key, m_data.find(key)->second.get());
381
}
382
383
bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const
384
{
385
    bool result = defaultValue;
386
    getBoolean(name, &result);
387
    return result;
388
}
389
390
int DictionaryValue::integerProperty(const String& name, int defaultValue) const
391
{
392
    int result = defaultValue;
393
    getInteger(name, &result);
394
    return result;
395
}
396
397
double DictionaryValue::doubleProperty(const String& name, double defaultValue) const
398
{
399
    double result = defaultValue;
400
    getDouble(name, &result);
401
    return result;
402
}
403
404
void DictionaryValue::remove(const String& name)
405
{
406
    m_data.erase(name);
407
    m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end());
408
}
409
410
void DictionaryValue::writeJSON(StringBuilder* output) const
411
{
412
    StringUtil::builderAppend(*output, '{');
413
    for (size_t i = 0; i < m_order.size(); ++i) {
414
        Dictionary::const_iterator it = m_data.find(m_order[i]);
415
        CHECK(it != m_data.end());
416
        if (i)
417
            StringUtil::builderAppend(*output, ',');
418
        StringUtil::builderAppendQuotedString(*output, it->first);
419
        StringUtil::builderAppend(*output, ':');
420
        it->second->writeJSON(output);
421
    }
422
    StringUtil::builderAppend(*output, '}');
423
}
424
425
std::unique_ptr<Value> DictionaryValue::clone() const
426
{
427
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
428
    for (size_t i = 0; i < m_order.size(); ++i) {
429
        String key = m_order[i];
430
        Dictionary::const_iterator value = m_data.find(key);
431
        DCHECK(value != m_data.cend() && value->second);
432
        result->setValue(key, value->second->clone());
433
    }
434
    return std::move(result);
435
}
436
437
652
DictionaryValue::DictionaryValue()
438
652
    : Value(TypeObject)
439
{
440
652
}
441
442
ListValue::~ListValue()
443
{
444
}
445
446
void ListValue::writeJSON(StringBuilder* output) const
447
{
448
    StringUtil::builderAppend(*output, '[');
449
    bool first = true;
450
    for (const std::unique_ptr<protocol::Value>& value : m_data) {
451
        if (!first)
452
            StringUtil::builderAppend(*output, ',');
453
        value->writeJSON(output);
454
        first = false;
455
    }
456
    StringUtil::builderAppend(*output, ']');
457
}
458
459
std::unique_ptr<Value> ListValue::clone() const
460
{
461
    std::unique_ptr<ListValue> result = ListValue::create();
462
    for (const std::unique_ptr<protocol::Value>& value : m_data)
463
        result->pushValue(value->clone());
464
    return std::move(result);
465
}
466
467
ListValue::ListValue()
468
    : Value(TypeArray)
469
{
470
}
471
472
void ListValue::pushValue(std::unique_ptr<protocol::Value> value)
473
{
474
    DCHECK(value);
475
    m_data.push_back(std::move(value));
476
}
477
478
protocol::Value* ListValue::at(size_t index)
479
{
480
    DCHECK_LT(index, m_data.size());
481
    return m_data[index].get();
482
}
483
484
void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
485
{
486
    escapeStringForJSONInternal<uint8_t>(str, len, dst);
487
}
488
489
void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
490
{
491
    escapeStringForJSONInternal<uint16_t>(str, len, dst);
492
}
493
494
} // namespace node
495
} // namespace inspector
496
} // namespace protocol
497
498
499
// Copyright 2016 The Chromium Authors. All rights reserved.
500
// Use of this source code is governed by a BSD-style license that can be
501
// found in the LICENSE file.
502
503
//#include "Object.h"
504
505
namespace node {
506
namespace inspector {
507
namespace protocol {
508
509
std::unique_ptr<Object> Object::fromValue(protocol::Value* value, ErrorSupport* errors)
510
{
511
    protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
512
    if (!dictionary) {
513
        errors->addError("object expected");
514
        return nullptr;
515
    }
516
    dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
517
    return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
518
}
519
520
std::unique_ptr<protocol::DictionaryValue> Object::toValue() const
521
{
522
    return DictionaryValue::cast(m_object->clone());
523
}
524
525
std::unique_ptr<Object> Object::clone() const
526
{
527
    return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
528
}
529
530
Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }
531
532
Object::~Object() { }
533
534
} // namespace node
535
} // namespace inspector
536
} // namespace protocol
537
538
539
// Copyright 2016 The Chromium Authors. All rights reserved.
540
// Use of this source code is governed by a BSD-style license that can be
541
// found in the LICENSE file.
542
543
//#include "DispatcherBase.h"
544
//#include "Parser.h"
545
546
namespace node {
547
namespace inspector {
548
namespace protocol {
549
550
// static
551
326
DispatchResponse DispatchResponse::OK()
552
{
553
326
    DispatchResponse result;
554
326
    result.m_status = kSuccess;
555
326
    result.m_errorCode = kParseError;
556
326
    return result;
557
}
558
559
// static
560
DispatchResponse DispatchResponse::Error(const String& error)
561
{
562
    DispatchResponse result;
563
    result.m_status = kError;
564
    result.m_errorCode = kServerError;
565
    result.m_errorMessage = error;
566
    return result;
567
}
568
569
// static
570
DispatchResponse DispatchResponse::InternalError()
571
{
572
    DispatchResponse result;
573
    result.m_status = kError;
574
    result.m_errorCode = kInternalError;
575
    result.m_errorMessage = "Internal error";
576
    return result;
577
}
578
579
// static
580
DispatchResponse DispatchResponse::InvalidParams(const String& error)
581
{
582
    DispatchResponse result;
583
    result.m_status = kError;
584
    result.m_errorCode = kInvalidParams;
585
    result.m_errorMessage = error;
586
    return result;
587
}
588
589
// static
590
DispatchResponse DispatchResponse::FallThrough()
591
{
592
    DispatchResponse result;
593
    result.m_status = kFallThrough;
594
    result.m_errorCode = kParseError;
595
    return result;
596
}
597
598
// static
599
const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";
600
601
DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }
602
603
DispatcherBase::WeakPtr::~WeakPtr()
604
{
605
    if (m_dispatcher)
606
        m_dispatcher->m_weakPtrs.erase(this);
607
}
608
609
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
610
    : m_backendImpl(std::move(backendImpl))
611
    , m_callId(callId)
612
    , m_callbackId(callbackId) { }
613
614
DispatcherBase::Callback::~Callback() = default;
615
616
void DispatcherBase::Callback::dispose()
617
{
618
    m_backendImpl = nullptr;
619
}
620
621
void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
622
{
623
    if (!m_backendImpl || !m_backendImpl->get())
624
        return;
625
    m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
626
    m_backendImpl = nullptr;
627
}
628
629
void DispatcherBase::Callback::fallThroughIfActive()
630
{
631
    if (!m_backendImpl || !m_backendImpl->get())
632
        return;
633
    m_backendImpl->get()->markFallThrough(m_callbackId);
634
    m_backendImpl = nullptr;
635
}
636
637
326
DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
638
    : m_frontendChannel(frontendChannel)
639
    , m_lastCallbackId(0)
640
326
    , m_lastCallbackFallThrough(false) { }
641
642
652
DispatcherBase::~DispatcherBase()
643
{
644
326
    clearFrontend();
645
326
}
646
647
int DispatcherBase::nextCallbackId()
648
{
649
    m_lastCallbackFallThrough = false;
650
    return ++m_lastCallbackId;
651
}
652
653
void DispatcherBase::markFallThrough(int callbackId)
654
{
655
    DCHECK(callbackId == m_lastCallbackId);
656
    m_lastCallbackFallThrough = true;
657
}
658
659
void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
660
{
661
    if (!m_frontendChannel)
662
        return;
663
    if (response.status() == DispatchResponse::kError) {
664
        reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
665
        return;
666
    }
667
    m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
668
}
669
670
void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
671
{
672
    sendResponse(callId, response, DictionaryValue::create());
673
}
674
675
namespace {
676
677
class ProtocolError : public Serializable {
678
public:
679
    static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
680
    {
681
        std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
682
        protocolError->m_callId = callId;
683
        protocolError->m_hasCallId = true;
684
        if (errors && errors->hasErrors())
685
            protocolError->m_data = errors->errors();
686
        return protocolError;
687
    }
688
689
    static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
690
    {
691
        return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
692
    }
693
694
    String serialize() override
695
    {
696
        std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
697
        error->setInteger("code", m_code);
698
        error->setString("message", m_errorMessage);
699
        if (m_data.length())
700
            error->setString("data", m_data);
701
        std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
702
        message->setObject("error", std::move(error));
703
        if (m_hasCallId)
704
            message->setInteger("id", m_callId);
705
        return message->serialize();
706
    }
707
708
    ~ProtocolError() override {}
709
710
private:
711
    ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
712
        : m_code(code)
713
        , m_errorMessage(errorMessage)
714
    {
715
    }
716
717
    DispatchResponse::ErrorCode m_code;
718
    String m_errorMessage;
719
    String m_data;
720
    int m_callId = 0;
721
    bool m_hasCallId = false;
722
};
723
724
} // namespace
725
726
static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
727
{
728
    if (frontendChannel)
729
        frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
730
}
731
732
static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
733
{
734
    if (frontendChannel)
735
        frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
736
}
737
738
void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
739
{
740
    reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
741
}
742
743
326
void DispatcherBase::clearFrontend()
744
{
745
326
    m_frontendChannel = nullptr;
746
326
    for (auto& weak : m_weakPtrs)
747
        weak->dispose();
748
326
    m_weakPtrs.clear();
749
326
}
750
751
std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
752
{
753
    std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
754
    m_weakPtrs.insert(weak.get());
755
    return weak;
756
}
757
758
163
UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
759
    : m_frontendChannel(frontendChannel)
760
163
    , m_fallThroughForNotFound(false) { }
761
762
void UberDispatcher::setFallThroughForNotFound(bool fallThroughForNotFound)
763
{
764
    m_fallThroughForNotFound = fallThroughForNotFound;
765
}
766
767
326
void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
768
{
769
326
    m_dispatchers[name] = std::move(dispatcher);
770
326
}
771
772
326
void UberDispatcher::setupRedirects(const HashMap<String, String>& redirects)
773
{
774
326
    for (const auto& pair : redirects)
775
        m_redirects[pair.first] = pair.second;
776
326
}
777
778
DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage, int* outCallId, String* outMethod)
779
{
780
    if (!parsedMessage) {
781
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
782
        return DispatchResponse::kError;
783
    }
784
    std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
785
    if (!messageObject) {
786
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
787
        return DispatchResponse::kError;
788
    }
789
790
    int callId = 0;
791
    protocol::Value* callIdValue = messageObject->get("id");
792
    bool success = callIdValue && callIdValue->asInteger(&callId);
793
    if (outCallId)
794
        *outCallId = callId;
795
    if (!success) {
796
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
797
        return DispatchResponse::kError;
798
    }
799
800
    protocol::Value* methodValue = messageObject->get("method");
801
    String method;
802
    success = methodValue && methodValue->asString(&method);
803
    if (outMethod)
804
        *outMethod = method;
805
    if (!success) {
806
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
807
        return DispatchResponse::kError;
808
    }
809
810
    HashMap<String, String>::iterator redirectIt = m_redirects.find(method);
811
    if (redirectIt != m_redirects.end())
812
        method = redirectIt->second;
813
814
    size_t dotIndex = StringUtil::find(method, ".");
815
    if (dotIndex == StringUtil::kNotFound) {
816
        if (m_fallThroughForNotFound)
817
            return DispatchResponse::kFallThrough;
818
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
819
        return DispatchResponse::kError;
820
    }
821
    String domain = StringUtil::substring(method, 0, dotIndex);
822
    auto it = m_dispatchers.find(domain);
823
    if (it == m_dispatchers.end()) {
824
        if (m_fallThroughForNotFound)
825
            return DispatchResponse::kFallThrough;
826
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
827
        return DispatchResponse::kError;
828
    }
829
    return it->second->dispatch(callId, method, std::move(messageObject));
830
}
831
832
489
bool UberDispatcher::getCommandName(const String& message, String* method, std::unique_ptr<protocol::DictionaryValue>* parsedMessage)
833
{
834
489
    std::unique_ptr<protocol::Value> value = StringUtil::parseJSON(message);
835
489
    if (!value) {
836
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
837
        return false;
838
   }
839
840
489
    protocol::DictionaryValue* object = DictionaryValue::cast(value.get());
841
489
    if (!object) {
842
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
843
        return false;
844
    }
845
846
489
    if (!object->getString("method", method)) {
847
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have string 'method' property");
848
        return false;
849
    }
850
851
489
    parsedMessage->reset(DictionaryValue::cast(value.release()));
852
489
    return true;
853
}
854
855
UberDispatcher::~UberDispatcher() = default;
856
857
// static
858
std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
859
{
860
    return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
861
}
862
863
// static
864
std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
865
{
866
    return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
867
}
868
869
String InternalResponse::serialize()
870
{
871
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
872
    std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
873
    if (m_notification.length()) {
874
        result->setString("method", m_notification);
875
        result->setValue("params", SerializedValue::create(params->serialize()));
876
    } else {
877
        result->setInteger("id", m_callId);
878
        result->setValue("result", SerializedValue::create(params->serialize()));
879
    }
880
    return result->serialize();
881
}
882
883
InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
884
    : m_callId(callId)
885
    , m_notification(notification)
886
    , m_params(params ? std::move(params) : nullptr)
887
{
888
}
889
890
} // namespace node
891
} // namespace inspector
892
} // namespace protocol
893
894
895
// Copyright 2016 The Chromium Authors. All rights reserved.
896
// Use of this source code is governed by a BSD-style license that can be
897
// found in the LICENSE file.
898
899
namespace node {
900
namespace inspector {
901
namespace protocol {
902
903
namespace {
904
905
const int stackLimit = 1000;
906
907
enum Token {
908
    ObjectBegin,
909
    ObjectEnd,
910
    ArrayBegin,
911
    ArrayEnd,
912
    StringLiteral,
913
    Number,
914
    BoolTrue,
915
    BoolFalse,
916
    NullToken,
917
    ListSeparator,
918
    ObjectPairSeparator,
919
    InvalidToken,
920
};
921
922
const char* const nullString = "null";
923
const char* const trueString = "true";
924
const char* const falseString = "false";
925
926
8313
bool isASCII(uint16_t c)
927
{
928
8313
    return !(c & ~0x7F);
929
}
930
931
7824
bool isSpaceOrNewLine(uint16_t c)
932
{
933


7824
    return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
934
}
935
936
489
double charactersToDouble(const uint16_t* characters, size_t length, bool* ok)
937
{
938
489
    std::vector<char> buffer;
939
489
    buffer.reserve(length + 1);
940
978
    for (size_t i = 0; i < length; ++i) {
941
489
        if (!isASCII(characters[i])) {
942
            *ok = false;
943
            return 0;
944
        }
945
489
        buffer.push_back(static_cast<char>(characters[i]));
946
    }
947
489
    buffer.push_back('\0');
948
489
    return StringUtil::toDouble(buffer.data(), length, ok);
949
}
950
951
double charactersToDouble(const uint8_t* characters, size_t length, bool* ok)
952
{
953
    std::string buffer(reinterpret_cast<const char*>(characters), length);
954
    return StringUtil::toDouble(buffer.data(), length, ok);
955
}
956
957
template<typename Char>
958
326
bool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token)
959
{
960




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

326
    if (*token != '\0')
962
        return false;
963
326
    *tokenEnd = start;
964
326
    return true;
965
}
966
967
template<typename Char>
968
489
bool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros)
969
{
970

489
    if (start == end)
971
        return false;
972
489
    bool haveLeadingZero = '0' == *start;
973
489
    int length = 0;
974



1467
    while (start < end && '0' <= *start && *start <= '9') {
975
489
        ++start;
976
489
        ++length;
977
    }
978

489
    if (!length)
979
        return false;
980



489
    if (!canHaveLeadingZeros && length > 1 && haveLeadingZero)
981
        return false;
982
489
    *tokenEnd = start;
983
489
    return true;
984
}
985
986
template<typename Char>
987
489
bool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd)
988
{
989
    // We just grab the number here. We validate the size in DecodeNumber.
990
    // According to RFC4627, a valid number is: [minus] int [frac] [exp]
991

489
    if (start == end)
992
        return false;
993
489
    Char c = *start;
994

489
    if ('-' == c)
995
        ++start;
996
997

489
    if (!readInt(start, end, &start, false))
998
        return false;
999

489
    if (start == end) {
1000
        *tokenEnd = start;
1001
        return true;
1002
    }
1003
1004
    // Optional fraction part
1005
489
    c = *start;
1006

489
    if ('.' == c) {
1007
        ++start;
1008
        if (!readInt(start, end, &start, true))
1009
            return false;
1010
        if (start == end) {
1011
            *tokenEnd = start;
1012
            return true;
1013
        }
1014
        c = *start;
1015
    }
1016
1017
    // Optional exponent part
1018


489
    if ('e' == c || 'E' == c) {
1019
        ++start;
1020
        if (start == end)
1021
            return false;
1022
        c = *start;
1023
        if ('-' == c || '+' == c) {
1024
            ++start;
1025
            if (start == end)
1026
                return false;
1027
        }
1028
        if (!readInt(start, end, &start, true))
1029
            return false;
1030
    }
1031
1032
489
    *tokenEnd = start;
1033
489
    return true;
1034
}
1035
1036
template<typename Char>
1037
bool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits)
1038
{
1039
    if (end - start < digits)
1040
        return false;
1041
    for (int i = 0; i < digits; ++i) {
1042
        Char c = *start++;
1043
        if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
1044
            return false;
1045
    }
1046
    *tokenEnd = start;
1047
    return true;
1048
}
1049
1050
template<typename Char>
1051
1956
bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
1052
{
1053

23309
    while (start < end) {
1054
21353
        Char c = *start++;
1055

21353
        if ('\\' == c) {
1056
	    if (start == end)
1057
	        return false;
1058
            c = *start++;
1059
            // Make sure the escaped char is valid.
1060
            switch (c) {
1061
            case 'x':
1062
                if (!readHexDigits(start, end, &start, 2))
1063
                    return false;
1064
                break;
1065
            case 'u':
1066
                if (!readHexDigits(start, end, &start, 4))
1067
                    return false;
1068
                break;
1069
            case '\\':
1070
            case '/':
1071
            case 'b':
1072
            case 'f':
1073
            case 'n':
1074
            case 'r':
1075
            case 't':
1076
            case 'v':
1077
            case '"':
1078
                break;
1079
            default:
1080
                return false;
1081
            }
1082

21353
        } else if ('"' == c) {
1083
1956
            *tokenEnd = start;
1084
1956
            return true;
1085
        }
1086
    }
1087
    return false;
1088
}
1089
1090
template<typename Char>
1091
bool skipComment(const Char* start, const Char* end, const Char** commentEnd)
1092
{
1093
    if (start == end)
1094
        return false;
1095
1096
    if (*start != '/' || start + 1 >= end)
1097
        return false;
1098
    ++start;
1099
1100
    if (*start == '/') {
1101
        // Single line comment, read to newline.
1102
        for (++start; start < end; ++start) {
1103
            if (*start == '\n' || *start == '\r') {
1104
                *commentEnd = start + 1;
1105
                return true;
1106
            }
1107
        }
1108
        *commentEnd = end;
1109
        // Comment reaches end-of-input, which is fine.
1110
        return true;
1111
    }
1112
1113
    if (*start == '*') {
1114
        Char previous = '\0';
1115
        // Block comment, read until end marker.
1116
        for (++start; start < end; previous = *start++) {
1117
            if (previous == '*' && *start == '/') {
1118
                *commentEnd = start + 1;
1119
                return true;
1120
            }
1121
        }
1122
        // Block comment must close before end-of-input.
1123
        return false;
1124
    }
1125
1126
    return false;
1127
}
1128
1129
template<typename Char>
1130
8313
void skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd)
1131
{
1132

16626
    while (start < end) {
1133

7824
        if (isSpaceOrNewLine(*start)) {
1134
            ++start;
1135

7824
        } else if (*start == '/') {
1136
            const Char* commentEnd;
1137
            if (!skipComment(start, end, &commentEnd))
1138
                break;
1139
            start = commentEnd;
1140
        } else {
1141
7824
            break;
1142
        }
1143
    }
1144
8313
    *whitespaceEnd = start;
1145
8313
}
1146
1147
template<typename Char>
1148
6357
Token parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd)
1149
{
1150
6357
    skipWhitespaceAndComments(start, end, tokenStart);
1151
6357
    start = *tokenStart;
1152
1153

6357
    if (start == end)
1154
        return InvalidToken;
1155
1156






6357
    switch (*start) {
1157
    case 'n':
1158
        if (parseConstToken(start, end, tokenEnd, nullString))
1159
            return NullToken;
1160
        break;
1161
    case 't':
1162

326
        if (parseConstToken(start, end, tokenEnd, trueString))
1163
326
            return BoolTrue;
1164
        break;
1165
    case 'f':
1166
        if (parseConstToken(start, end, tokenEnd, falseString))
1167
            return BoolFalse;
1168
        break;
1169
    case '[':
1170
        *tokenEnd = start + 1;
1171
        return ArrayBegin;
1172
    case ']':
1173
        *tokenEnd = start + 1;
1174
        return ArrayEnd;
1175
    case ',':
1176
815
        *tokenEnd = start + 1;
1177
815
        return ListSeparator;
1178
    case '{':
1179
652
        *tokenEnd = start + 1;
1180
652
        return ObjectBegin;
1181
    case '}':
1182
652
        *tokenEnd = start + 1;
1183
652
        return ObjectEnd;
1184
    case ':':
1185
1467
        *tokenEnd = start + 1;
1186
1467
        return ObjectPairSeparator;
1187
    case '0':
1188
    case '1':
1189
    case '2':
1190
    case '3':
1191
    case '4':
1192
    case '5':
1193
    case '6':
1194
    case '7':
1195
    case '8':
1196
    case '9':
1197
    case '-':
1198

489
        if (parseNumberToken(start, end, tokenEnd))
1199
489
            return Number;
1200
        break;
1201
    case '"':
1202

1956
        if (parseStringToken(start + 1, end, tokenEnd))
1203
1956
            return StringLiteral;
1204
        break;
1205
    }
1206
    return InvalidToken;
1207
}
1208
1209
template<typename Char>
1210
int hexToInt(Char c)
1211
{
1212
    if ('0' <= c && c <= '9')
1213
        return c - '0';
1214
    if ('A' <= c && c <= 'F')
1215
        return c - 'A' + 10;
1216
    if ('a' <= c && c <= 'f')
1217
        return c - 'a' + 10;
1218
    DCHECK(false);
1219
    return 0;
1220
}
1221
1222
template<typename Char>
1223
1956
bool decodeString(const Char* start, const Char* end, StringBuilder* output)
1224
{
1225

23309
    while (start < end) {
1226
19397
        uint16_t c = *start++;
1227

19397
        if ('\\' != c) {
1228
19397
            StringUtil::builderAppend(*output, c);
1229
19397
            continue;
1230
        }
1231
	if (start == end)
1232
	    return false;
1233
        c = *start++;
1234
1235
        if (c == 'x') {
1236
            // \x is not supported.
1237
            return false;
1238
        }
1239
1240
        switch (c) {
1241
        case '"':
1242
        case '/':
1243
        case '\\':
1244
            break;
1245
        case 'b':
1246
            c = '\b';
1247
            break;
1248
        case 'f':
1249
            c = '\f';
1250
            break;
1251
        case 'n':
1252
            c = '\n';
1253
            break;
1254
        case 'r':
1255
            c = '\r';
1256
            break;
1257
        case 't':
1258
            c = '\t';
1259
            break;
1260
        case 'v':
1261
            c = '\v';
1262
            break;
1263
        case 'u':
1264
            c = (hexToInt(*start) << 12) +
1265
                (hexToInt(*(start + 1)) << 8) +
1266
                (hexToInt(*(start + 2)) << 4) +
1267
                hexToInt(*(start + 3));
1268
            start += 4;
1269
            break;
1270
        default:
1271
            return false;
1272
        }
1273
        StringUtil::builderAppend(*output, c);
1274
    }
1275
1956
    return true;
1276
}
1277
1278
template<typename Char>
1279
1956
bool decodeString(const Char* start, const Char* end, String* output)
1280
{
1281

1956
    if (start == end) {
1282
        *output = "";
1283
        return true;
1284
    }
1285

1956
    if (start > end)
1286
        return false;
1287
1956
    StringBuilder buffer;
1288
1956
    StringUtil::builderReserve(buffer, end - start);
1289

1956
    if (!decodeString(start, end, &buffer))
1290
        return false;
1291
1956
    *output = StringUtil::builderToString(buffer);
1292
1956
    return true;
1293
}
1294
1295
template<typename Char>
1296
1956
std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth)
1297
{
1298

1956
    if (depth > stackLimit)
1299
        return nullptr;
1300
1301
1956
    std::unique_ptr<Value> result;
1302
    const Char* tokenStart;
1303
    const Char* tokenEnd;
1304
1956
    Token token = parseToken(start, end, &tokenStart, &tokenEnd);
1305




1956
    switch (token) {
1306
    case InvalidToken:
1307
        return nullptr;
1308
    case NullToken:
1309
        result = Value::null();
1310
        break;
1311
    case BoolTrue:
1312
326
        result = FundamentalValue::create(true);
1313
326
        break;
1314
    case BoolFalse:
1315
        result = FundamentalValue::create(false);
1316
        break;
1317
    case Number: {
1318
        bool ok;
1319
489
        double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
1320

489
        if (!ok)
1321
            return nullptr;
1322
489
        int number = static_cast<int>(value);
1323

489
        if (number == value)
1324
489
            result = FundamentalValue::create(number);
1325
        else
1326
            result = FundamentalValue::create(value);
1327
489
        break;
1328
    }
1329
    case StringLiteral: {
1330
489
        String value;
1331
489
        bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
1332

489
        if (!ok)
1333
            return nullptr;
1334
489
        result = StringValue::create(value);
1335

489
        break;
1336
    }
1337
    case ArrayBegin: {
1338
        std::unique_ptr<ListValue> array = ListValue::create();
1339
        start = tokenEnd;
1340
        token = parseToken(start, end, &tokenStart, &tokenEnd);
1341
        while (token != ArrayEnd) {
1342
            std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
1343
            if (!arrayNode)
1344
                return nullptr;
1345
            array->pushValue(std::move(arrayNode));
1346
1347
            // After a list value, we expect a comma or the end of the list.
1348
            start = tokenEnd;
1349
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1350
            if (token == ListSeparator) {
1351
                start = tokenEnd;
1352
                token = parseToken(start, end, &tokenStart, &tokenEnd);
1353
                if (token == ArrayEnd)
1354
                    return nullptr;
1355
            } else if (token != ArrayEnd) {
1356
                // Unexpected value after list value. Bail out.
1357
                return nullptr;
1358
            }
1359
        }
1360
        if (token != ArrayEnd)
1361
            return nullptr;
1362
        result = std::move(array);
1363
        break;
1364
    }
1365
    case ObjectBegin: {
1366
652
        std::unique_ptr<DictionaryValue> object = DictionaryValue::create();
1367
652
        start = tokenEnd;
1368
652
        token = parseToken(start, end, &tokenStart, &tokenEnd);
1369

2119
        while (token != ObjectEnd) {
1370

1467
            if (token != StringLiteral)
1371
                return nullptr;
1372
1467
            String key;
1373

1467
            if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
1374
                return nullptr;
1375
1467
            start = tokenEnd;
1376
1377
1467
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1378

1467
            if (token != ObjectPairSeparator)
1379
                return nullptr;
1380
1467
            start = tokenEnd;
1381
1382

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

1467
            if (!value)
1384
                return nullptr;
1385
1467
            object->setValue(key, std::move(value));
1386
1467
            start = tokenEnd;
1387
1388
            // After a key/value pair, we expect a comma or the end of the
1389
            // object.
1390
1467
            token = parseToken(start, end, &tokenStart, &tokenEnd);
1391

1467
            if (token == ListSeparator) {
1392
815
                start = tokenEnd;
1393
815
                token = parseToken(start, end, &tokenStart, &tokenEnd);
1394

815
                if (token == ObjectEnd)
1395
                    return nullptr;
1396

652
            } else if (token != ObjectEnd) {
1397
                // Unexpected value after last object value. Bail out.
1398
                return nullptr;
1399
            }
1400
        }
1401

652
        if (token != ObjectEnd)
1402
            return nullptr;
1403
652
        result = std::move(object);
1404

652
        break;
1405
    }
1406
1407
    default:
1408
        // We got a token that's not a value.
1409
        return nullptr;
1410
    }
1411
1412
1956
    skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd);
1413
1956
    return result;
1414
}
1415
1416
template<typename Char>
1417
489
std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
1418
{
1419
489
    const Char* end = start + length;
1420
    const Char *tokenEnd;
1421
489
    std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0);
1422



489
    if (!value || tokenEnd != end)
1423
        return nullptr;
1424
489
    return value;
1425
}
1426
1427
} // anonymous namespace
1428
1429
489
std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
1430
{
1431
489
    return parseJSONInternal<uint16_t>(characters, length);
1432
}
1433
1434
std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
1435
{
1436
    return parseJSONInternal<uint8_t>(characters, length);
1437
}
1438
1439
} // namespace node
1440
} // namespace inspector
1441
} // namespace protocol