diff options
Diffstat (limited to 'deps/v8/third_party/inspector_protocol')
5 files changed, 168 insertions, 34 deletions
diff --git a/deps/v8/third_party/inspector_protocol/README.v8 b/deps/v8/third_party/inspector_protocol/README.v8 index 622ff72f74..a092e3e7a1 100644 --- a/deps/v8/third_party/inspector_protocol/README.v8 +++ b/deps/v8/third_party/inspector_protocol/README.v8 @@ -2,7 +2,7 @@ Name: inspector protocol Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: 373efb7fe33a7ae84038868ed08b9f1bd328b55d +Revision: d114a62e144cdfdae697fe0af6581ce39a31af37 License: BSD License File: LICENSE Security Critical: no diff --git a/deps/v8/third_party/inspector_protocol/code_generator.py b/deps/v8/third_party/inspector_protocol/code_generator.py index 5cf5a308c5..7c72cc70e4 100755 --- a/deps/v8/third_party/inspector_protocol/code_generator.py +++ b/deps/v8/third_party/inspector_protocol/code_generator.py @@ -43,9 +43,6 @@ def read_config(): items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items] keys, values = list(zip(*items)) - # 'async' is a keyword since Python 3.7. - # Avoid namedtuple(rename=True) for compatibility with Python 2.X. - keys = tuple('async_' if k == 'async' else k for k in keys) return collections.namedtuple('X', keys)(*values) return json.loads(data, object_hook=json_object_hook) @@ -558,7 +555,7 @@ class Protocol(object): if not self.config.protocol.options: return False return self.check_options(self.config.protocol.options, domain, command, - "async_", None, False) + "async", None, False) def is_exported(self, domain, name): if not self.config.protocol.options: diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding.cc b/deps/v8/third_party/inspector_protocol/encoding/encoding.cc index 1da7c45aa3..6e5619d00e 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding.cc +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding.cc @@ -53,6 +53,10 @@ std::string Status::ToASCIIString() const { return ToASCIIString("CBOR: invalid double"); case Error::CBOR_INVALID_ENVELOPE: return ToASCIIString("CBOR: invalid envelope"); + case Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH: + return ToASCIIString("CBOR: envelope contents length mismatch"); + case Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE: + return ToASCIIString("CBOR: map or array expected in envelope"); case Error::CBOR_INVALID_STRING8: return ToASCIIString("CBOR: invalid string8"); case Error::CBOR_INVALID_STRING16: @@ -929,6 +933,9 @@ bool ParseArray(int32_t stack_depth, bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, StreamingParserHandler* out); +bool ParseEnvelope(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { std::vector<uint16_t> value; @@ -946,6 +953,52 @@ bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { return true; } +bool ParseEnvelope(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::ENVELOPE); + // Before we enter the envelope, we save the position that we + // expect to see after we're done parsing the envelope contents. + // This way we can compare and produce an error if the contents + // didn't fit exactly into the envelope length. + size_t pos_past_envelope = tokenizer->Status().pos + + kEncodedEnvelopeHeaderSize + + tokenizer->GetEnvelopeContents().size(); + tokenizer->EnterEnvelope(); + switch (tokenizer->TokenTag()) { + case CBORTokenTag::ERROR_VALUE: + out->HandleError(tokenizer->Status()); + return false; + case CBORTokenTag::MAP_START: + if (!ParseMap(stack_depth + 1, tokenizer, out)) + return false; + break; // Continue to check pos_past_envelope below. + case CBORTokenTag::ARRAY_START: + if (stack_depth == 0) { // Not allowed at the top level. + out->HandleError( + Status{Error::CBOR_MAP_START_EXPECTED, tokenizer->Status().pos}); + return false; + } + if (!ParseArray(stack_depth + 1, tokenizer, out)) + return false; + break; // Continue to check pos_past_envelope below. + default: + out->HandleError(Status{ + stack_depth == 0 ? Error::CBOR_MAP_START_EXPECTED + : Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE, + tokenizer->Status().pos}); + return false; + } + // The contents of the envelope parsed OK, now check that we're at + // the expected position. + if (pos_past_envelope != tokenizer->Status().pos) { + out->HandleError(Status{Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH, + tokenizer->Status().pos}); + return false; + } + return true; +} + bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, StreamingParserHandler* out) { @@ -954,9 +1007,6 @@ bool ParseValue(int32_t stack_depth, Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); return false; } - // Skip past the envelope to get to what's inside. - if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) - tokenizer->EnterEnvelope(); switch (tokenizer->TokenTag()) { case CBORTokenTag::ERROR_VALUE: out->HandleError(tokenizer->Status()); @@ -965,6 +1015,8 @@ bool ParseValue(int32_t stack_depth, out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, tokenizer->Status().pos}); return false; + case CBORTokenTag::ENVELOPE: + return ParseEnvelope(stack_depth, tokenizer, out); case CBORTokenTag::TRUE_VALUE: out->HandleBool(true); tokenizer->Next(); @@ -1091,13 +1143,7 @@ void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) { // We checked for the envelope start byte above, so the tokenizer // must agree here, since it's not an error. assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); - tokenizer.EnterEnvelope(); - if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { - out->HandleError( - Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); - return; - } - if (!ParseMap(/*stack_depth=*/1, &tokenizer, out)) + if (!ParseEnvelope(/*stack_depth=*/0, &tokenizer, out)) return; if (tokenizer.TokenTag() == CBORTokenTag::DONE) return; diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding.h b/deps/v8/third_party/inspector_protocol/encoding/encoding.h index 340667f604..c9ddd3a9be 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding.h +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding.h @@ -125,21 +125,23 @@ enum class Error { CBOR_INVALID_INT32 = 0x0e, CBOR_INVALID_DOUBLE = 0x0f, CBOR_INVALID_ENVELOPE = 0x10, - CBOR_INVALID_STRING8 = 0x11, - CBOR_INVALID_STRING16 = 0x12, - CBOR_INVALID_BINARY = 0x13, - CBOR_UNSUPPORTED_VALUE = 0x14, - CBOR_NO_INPUT = 0x15, - CBOR_INVALID_START_BYTE = 0x16, - CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, - CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, - CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, - CBOR_INVALID_MAP_KEY = 0x1a, - CBOR_STACK_LIMIT_EXCEEDED = 0x1b, - CBOR_TRAILING_JUNK = 0x1c, - CBOR_MAP_START_EXPECTED = 0x1d, - CBOR_MAP_STOP_EXPECTED = 0x1e, - CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x1f, + CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH = 0x11, + CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE = 0x12, + CBOR_INVALID_STRING8 = 0x13, + CBOR_INVALID_STRING16 = 0x14, + CBOR_INVALID_BINARY = 0x15, + CBOR_UNSUPPORTED_VALUE = 0x16, + CBOR_NO_INPUT = 0x17, + CBOR_INVALID_START_BYTE = 0x18, + CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x19, + CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x1a, + CBOR_UNEXPECTED_EOF_IN_MAP = 0x1b, + CBOR_INVALID_MAP_KEY = 0x1c, + CBOR_STACK_LIMIT_EXCEEDED = 0x1d, + CBOR_TRAILING_JUNK = 0x1e, + CBOR_MAP_START_EXPECTED = 0x1f, + CBOR_MAP_STOP_EXPECTED = 0x20, + CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x21, }; // A status value with position that can be copied. The default status diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc b/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc index 768e19bb9e..a36b200bad 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc @@ -979,6 +979,72 @@ TEST(ParseCBORTest, UnexpectedEofInMapError) { EXPECT_EQ("", out); } +TEST(ParseCBORTest, TopLevelCantBeEmptyEnvelope) { + // Normally, an array would be allowed inside an envelope, but + // the top-level envelope is required to contain a map. + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, 0}; // envelope + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(&GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_MAP_START_EXPECTED, status.error); + EXPECT_EQ(bytes.size(), status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, MapStartExpectedAtTopLevel) { + // Normally, an array would be allowed inside an envelope, but + // the top-level envelope is required to contain a map. + constexpr uint8_t kPayloadLen = 1; + std::vector<uint8_t> bytes = {0xd8, + 0x5a, + 0, + 0, + 0, + kPayloadLen, // envelope + EncodeIndefiniteLengthArrayStart()}; + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(&GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_MAP_START_EXPECTED, status.error); + EXPECT_EQ(6u, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, OnlyMapsAndArraysSupportedInsideEnvelopes) { + // The top level is a map with key "foo", and the value + // is an envelope that contains just a number (1). We don't + // allow numbers to be contained in an envelope though, only + // maps and arrays. + constexpr uint8_t kPayloadLen = 1; + std::vector<uint8_t> bytes = {0xd8, + 0x5a, + 0, + 0, + 0, + kPayloadLen, // envelope + EncodeIndefiniteLengthMapStart()}; + EncodeString8(SpanFrom("foo"), &bytes); + for (uint8_t byte : {0xd8, 0x5a, 0, 0, 0, /*payload_len*/ 1}) + bytes.emplace_back(byte); + size_t error_pos = bytes.size(); + bytes.push_back(1); // Envelope contents / payload = number 1. + bytes.emplace_back(EncodeStop()); + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(&GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + TEST(ParseCBORTest, InvalidMapKeyError) { constexpr uint8_t kPayloadLen = 2; std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, @@ -1195,18 +1261,18 @@ TEST(ParseCBORTest, InvalidSignedError) { } TEST(ParseCBORTest, TrailingJunk) { - constexpr uint8_t kPayloadLen = 35; + constexpr uint8_t kPayloadLen = 12; std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope 0xbf}; // map start EncodeString8(SpanFrom("key"), &bytes); EncodeString8(SpanFrom("value"), &bytes); bytes.push_back(0xff); // Up to here, it's a perfectly fine msg. + ASSERT_EQ(kPayloadLen, bytes.size() - 6); size_t error_pos = bytes.size(); + // Now write some trailing junk after the message. EncodeString8(SpanFrom("trailing junk"), &bytes); - internals::WriteTokenStart(MajorType::UNSIGNED, std::numeric_limits<uint64_t>::max(), &bytes); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); std::string out; Status status; std::unique_ptr<StreamingParserHandler> json_writer = @@ -1217,6 +1283,29 @@ TEST(ParseCBORTest, TrailingJunk) { EXPECT_EQ("", out); } +TEST(ParseCBORTest, EnvelopeContentsLengthMismatch) { + constexpr uint8_t kPartialPayloadLen = 5; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, + 0, 0, kPartialPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFrom("key"), &bytes); + // kPartialPayloadLen would need to indicate the length of the entire map, + // all the way past the 0xff map stop character. Instead, it only covers + // a portion of the map. + EXPECT_EQ(bytes.size() - 6, kPartialPayloadLen); + EncodeString8(SpanFrom("value"), &bytes); + bytes.push_back(0xff); // map stop + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(&GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH, status.error); + EXPECT_EQ(bytes.size(), status.pos); + EXPECT_EQ("", out); +} + // ============================================================================= // cbor::AppendString8EntryToMap - for limited in-place editing of messages // ============================================================================= @@ -1376,7 +1465,7 @@ TEST(JsonEncoder, IncompleteUtf8Sequence) { { // 🌎 takes four bytes to encode in UTF-8. We test with the first three; // This means we're trying to emit a string that consists solely of an - // incomplete UTF-8 sequence. So the string in the JSON output is emtpy. + // incomplete UTF-8 sequence. So the string in the JSON output is empty. std::string world_utf8 = "🌎"; ASSERT_EQ(4u, world_utf8.size()); std::vector<uint8_t> chars(world_utf8.begin(), world_utf8.begin() + 3); |