Commit d0e718a7 authored by Johannes Henkel's avatar Johannes Henkel Committed by Commit Bot

[DevTools] Roll inspector_protocol

New revision: d114a62e144cdfdae697fe0af6581ce39a31af37

Change-Id: I865edf40848d5593ae80a5ee0ed65c0c472a5a89
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1713234Reviewed-by: 's avatarAlexei Filippov <alph@chromium.org>
Commit-Queue: Johannes Henkel <johannes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63328}
parent bb2e7071
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment