Skip to content

Commit d0e718a

Browse files
powdercloudCommit Bot
authored andcommitted
[DevTools] Roll inspector_protocol
New revision: d114a62e144cdfdae697fe0af6581ce39a31af37 Change-Id: I865edf40848d5593ae80a5ee0ed65c0c472a5a89 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1713234 Reviewed-by: Alexei Filippov <alph@chromium.org> Commit-Queue: Johannes Henkel <johannes@chromium.org> Cr-Commit-Position: refs/heads/master@{#63328}
1 parent bb2e707 commit d0e718a

4 files changed

Lines changed: 167 additions & 30 deletions

File tree

third_party/inspector_protocol/README.v8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Name: inspector protocol
22
Short Name: inspector_protocol
33
URL: https://chromium.googlesource.com/deps/inspector_protocol/
44
Version: 0
5-
Revision: 373efb7fe33a7ae84038868ed08b9f1bd328b55d
5+
Revision: d114a62e144cdfdae697fe0af6581ce39a31af37
66
License: BSD
77
License File: LICENSE
88
Security Critical: no

third_party/inspector_protocol/encoding/encoding.cc

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ std::string Status::ToASCIIString() const {
5353
return ToASCIIString("CBOR: invalid double");
5454
case Error::CBOR_INVALID_ENVELOPE:
5555
return ToASCIIString("CBOR: invalid envelope");
56+
case Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH:
57+
return ToASCIIString("CBOR: envelope contents length mismatch");
58+
case Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE:
59+
return ToASCIIString("CBOR: map or array expected in envelope");
5660
case Error::CBOR_INVALID_STRING8:
5761
return ToASCIIString("CBOR: invalid string8");
5862
case Error::CBOR_INVALID_STRING16:
@@ -929,6 +933,9 @@ bool ParseArray(int32_t stack_depth,
929933
bool ParseValue(int32_t stack_depth,
930934
CBORTokenizer* tokenizer,
931935
StreamingParserHandler* out);
936+
bool ParseEnvelope(int32_t stack_depth,
937+
CBORTokenizer* tokenizer,
938+
StreamingParserHandler* out);
932939

933940
void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
934941
std::vector<uint16_t> value;
@@ -946,6 +953,52 @@ bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) {
946953
return true;
947954
}
948955

956+
bool ParseEnvelope(int32_t stack_depth,
957+
CBORTokenizer* tokenizer,
958+
StreamingParserHandler* out) {
959+
assert(tokenizer->TokenTag() == CBORTokenTag::ENVELOPE);
960+
// Before we enter the envelope, we save the position that we
961+
// expect to see after we're done parsing the envelope contents.
962+
// This way we can compare and produce an error if the contents
963+
// didn't fit exactly into the envelope length.
964+
size_t pos_past_envelope = tokenizer->Status().pos +
965+
kEncodedEnvelopeHeaderSize +
966+
tokenizer->GetEnvelopeContents().size();
967+
tokenizer->EnterEnvelope();
968+
switch (tokenizer->TokenTag()) {
969+
case CBORTokenTag::ERROR_VALUE:
970+
out->HandleError(tokenizer->Status());
971+
return false;
972+
case CBORTokenTag::MAP_START:
973+
if (!ParseMap(stack_depth + 1, tokenizer, out))
974+
return false;
975+
break; // Continue to check pos_past_envelope below.
976+
case CBORTokenTag::ARRAY_START:
977+
if (stack_depth == 0) { // Not allowed at the top level.
978+
out->HandleError(
979+
Status{Error::CBOR_MAP_START_EXPECTED, tokenizer->Status().pos});
980+
return false;
981+
}
982+
if (!ParseArray(stack_depth + 1, tokenizer, out))
983+
return false;
984+
break; // Continue to check pos_past_envelope below.
985+
default:
986+
out->HandleError(Status{
987+
stack_depth == 0 ? Error::CBOR_MAP_START_EXPECTED
988+
: Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE,
989+
tokenizer->Status().pos});
990+
return false;
991+
}
992+
// The contents of the envelope parsed OK, now check that we're at
993+
// the expected position.
994+
if (pos_past_envelope != tokenizer->Status().pos) {
995+
out->HandleError(Status{Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH,
996+
tokenizer->Status().pos});
997+
return false;
998+
}
999+
return true;
1000+
}
1001+
9491002
bool ParseValue(int32_t stack_depth,
9501003
CBORTokenizer* tokenizer,
9511004
StreamingParserHandler* out) {
@@ -954,9 +1007,6 @@ bool ParseValue(int32_t stack_depth,
9541007
Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos});
9551008
return false;
9561009
}
957-
// Skip past the envelope to get to what's inside.
958-
if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
959-
tokenizer->EnterEnvelope();
9601010
switch (tokenizer->TokenTag()) {
9611011
case CBORTokenTag::ERROR_VALUE:
9621012
out->HandleError(tokenizer->Status());
@@ -965,6 +1015,8 @@ bool ParseValue(int32_t stack_depth,
9651015
out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE,
9661016
tokenizer->Status().pos});
9671017
return false;
1018+
case CBORTokenTag::ENVELOPE:
1019+
return ParseEnvelope(stack_depth, tokenizer, out);
9681020
case CBORTokenTag::TRUE_VALUE:
9691021
out->HandleBool(true);
9701022
tokenizer->Next();
@@ -1091,13 +1143,7 @@ void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) {
10911143
// We checked for the envelope start byte above, so the tokenizer
10921144
// must agree here, since it's not an error.
10931145
assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE);
1094-
tokenizer.EnterEnvelope();
1095-
if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) {
1096-
out->HandleError(
1097-
Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos});
1098-
return;
1099-
}
1100-
if (!ParseMap(/*stack_depth=*/1, &tokenizer, out))
1146+
if (!ParseEnvelope(/*stack_depth=*/0, &tokenizer, out))
11011147
return;
11021148
if (tokenizer.TokenTag() == CBORTokenTag::DONE)
11031149
return;

third_party/inspector_protocol/encoding/encoding.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,23 @@ enum class Error {
125125
CBOR_INVALID_INT32 = 0x0e,
126126
CBOR_INVALID_DOUBLE = 0x0f,
127127
CBOR_INVALID_ENVELOPE = 0x10,
128-
CBOR_INVALID_STRING8 = 0x11,
129-
CBOR_INVALID_STRING16 = 0x12,
130-
CBOR_INVALID_BINARY = 0x13,
131-
CBOR_UNSUPPORTED_VALUE = 0x14,
132-
CBOR_NO_INPUT = 0x15,
133-
CBOR_INVALID_START_BYTE = 0x16,
134-
CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17,
135-
CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18,
136-
CBOR_UNEXPECTED_EOF_IN_MAP = 0x19,
137-
CBOR_INVALID_MAP_KEY = 0x1a,
138-
CBOR_STACK_LIMIT_EXCEEDED = 0x1b,
139-
CBOR_TRAILING_JUNK = 0x1c,
140-
CBOR_MAP_START_EXPECTED = 0x1d,
141-
CBOR_MAP_STOP_EXPECTED = 0x1e,
142-
CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x1f,
128+
CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH = 0x11,
129+
CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE = 0x12,
130+
CBOR_INVALID_STRING8 = 0x13,
131+
CBOR_INVALID_STRING16 = 0x14,
132+
CBOR_INVALID_BINARY = 0x15,
133+
CBOR_UNSUPPORTED_VALUE = 0x16,
134+
CBOR_NO_INPUT = 0x17,
135+
CBOR_INVALID_START_BYTE = 0x18,
136+
CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x19,
137+
CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x1a,
138+
CBOR_UNEXPECTED_EOF_IN_MAP = 0x1b,
139+
CBOR_INVALID_MAP_KEY = 0x1c,
140+
CBOR_STACK_LIMIT_EXCEEDED = 0x1d,
141+
CBOR_TRAILING_JUNK = 0x1e,
142+
CBOR_MAP_START_EXPECTED = 0x1f,
143+
CBOR_MAP_STOP_EXPECTED = 0x20,
144+
CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x21,
143145
};
144146

145147
// A status value with position that can be copied. The default status

third_party/inspector_protocol/encoding/encoding_test.cc

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,72 @@ TEST(ParseCBORTest, UnexpectedEofInMapError) {
979979
EXPECT_EQ("", out);
980980
}
981981

982+
TEST(ParseCBORTest, TopLevelCantBeEmptyEnvelope) {
983+
// Normally, an array would be allowed inside an envelope, but
984+
// the top-level envelope is required to contain a map.
985+
std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, 0}; // envelope
986+
std::string out;
987+
Status status;
988+
std::unique_ptr<StreamingParserHandler> json_writer =
989+
NewJSONEncoder(&GetTestPlatform(), &out, &status);
990+
ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
991+
EXPECT_EQ(Error::CBOR_MAP_START_EXPECTED, status.error);
992+
EXPECT_EQ(bytes.size(), status.pos);
993+
EXPECT_EQ("", out);
994+
}
995+
996+
TEST(ParseCBORTest, MapStartExpectedAtTopLevel) {
997+
// Normally, an array would be allowed inside an envelope, but
998+
// the top-level envelope is required to contain a map.
999+
constexpr uint8_t kPayloadLen = 1;
1000+
std::vector<uint8_t> bytes = {0xd8,
1001+
0x5a,
1002+
0,
1003+
0,
1004+
0,
1005+
kPayloadLen, // envelope
1006+
EncodeIndefiniteLengthArrayStart()};
1007+
EXPECT_EQ(kPayloadLen, bytes.size() - 6);
1008+
std::string out;
1009+
Status status;
1010+
std::unique_ptr<StreamingParserHandler> json_writer =
1011+
NewJSONEncoder(&GetTestPlatform(), &out, &status);
1012+
ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1013+
EXPECT_EQ(Error::CBOR_MAP_START_EXPECTED, status.error);
1014+
EXPECT_EQ(6u, status.pos);
1015+
EXPECT_EQ("", out);
1016+
}
1017+
1018+
TEST(ParseCBORTest, OnlyMapsAndArraysSupportedInsideEnvelopes) {
1019+
// The top level is a map with key "foo", and the value
1020+
// is an envelope that contains just a number (1). We don't
1021+
// allow numbers to be contained in an envelope though, only
1022+
// maps and arrays.
1023+
constexpr uint8_t kPayloadLen = 1;
1024+
std::vector<uint8_t> bytes = {0xd8,
1025+
0x5a,
1026+
0,
1027+
0,
1028+
0,
1029+
kPayloadLen, // envelope
1030+
EncodeIndefiniteLengthMapStart()};
1031+
EncodeString8(SpanFrom("foo"), &bytes);
1032+
for (uint8_t byte : {0xd8, 0x5a, 0, 0, 0, /*payload_len*/ 1})
1033+
bytes.emplace_back(byte);
1034+
size_t error_pos = bytes.size();
1035+
bytes.push_back(1); // Envelope contents / payload = number 1.
1036+
bytes.emplace_back(EncodeStop());
1037+
1038+
std::string out;
1039+
Status status;
1040+
std::unique_ptr<StreamingParserHandler> json_writer =
1041+
NewJSONEncoder(&GetTestPlatform(), &out, &status);
1042+
ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1043+
EXPECT_EQ(Error::CBOR_MAP_OR_ARRAY_EXPECTED_IN_ENVELOPE, status.error);
1044+
EXPECT_EQ(error_pos, status.pos);
1045+
EXPECT_EQ("", out);
1046+
}
1047+
9821048
TEST(ParseCBORTest, InvalidMapKeyError) {
9831049
constexpr uint8_t kPayloadLen = 2;
9841050
std::vector<uint8_t> bytes = {0xd8, 0x5a, 0,
@@ -1195,18 +1261,18 @@ TEST(ParseCBORTest, InvalidSignedError) {
11951261
}
11961262

11971263
TEST(ParseCBORTest, TrailingJunk) {
1198-
constexpr uint8_t kPayloadLen = 35;
1264+
constexpr uint8_t kPayloadLen = 12;
11991265
std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope
12001266
0xbf}; // map start
12011267
EncodeString8(SpanFrom("key"), &bytes);
12021268
EncodeString8(SpanFrom("value"), &bytes);
12031269
bytes.push_back(0xff); // Up to here, it's a perfectly fine msg.
1270+
ASSERT_EQ(kPayloadLen, bytes.size() - 6);
12041271
size_t error_pos = bytes.size();
1272+
// Now write some trailing junk after the message.
12051273
EncodeString8(SpanFrom("trailing junk"), &bytes);
1206-
12071274
internals::WriteTokenStart(MajorType::UNSIGNED,
12081275
std::numeric_limits<uint64_t>::max(), &bytes);
1209-
EXPECT_EQ(kPayloadLen, bytes.size() - 6);
12101276
std::string out;
12111277
Status status;
12121278
std::unique_ptr<StreamingParserHandler> json_writer =
@@ -1217,6 +1283,29 @@ TEST(ParseCBORTest, TrailingJunk) {
12171283
EXPECT_EQ("", out);
12181284
}
12191285

1286+
TEST(ParseCBORTest, EnvelopeContentsLengthMismatch) {
1287+
constexpr uint8_t kPartialPayloadLen = 5;
1288+
std::vector<uint8_t> bytes = {0xd8, 0x5a, 0,
1289+
0, 0, kPartialPayloadLen, // envelope
1290+
0xbf}; // map start
1291+
EncodeString8(SpanFrom("key"), &bytes);
1292+
// kPartialPayloadLen would need to indicate the length of the entire map,
1293+
// all the way past the 0xff map stop character. Instead, it only covers
1294+
// a portion of the map.
1295+
EXPECT_EQ(bytes.size() - 6, kPartialPayloadLen);
1296+
EncodeString8(SpanFrom("value"), &bytes);
1297+
bytes.push_back(0xff); // map stop
1298+
1299+
std::string out;
1300+
Status status;
1301+
std::unique_ptr<StreamingParserHandler> json_writer =
1302+
NewJSONEncoder(&GetTestPlatform(), &out, &status);
1303+
ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get());
1304+
EXPECT_EQ(Error::CBOR_ENVELOPE_CONTENTS_LENGTH_MISMATCH, status.error);
1305+
EXPECT_EQ(bytes.size(), status.pos);
1306+
EXPECT_EQ("", out);
1307+
}
1308+
12201309
// =============================================================================
12211310
// cbor::AppendString8EntryToMap - for limited in-place editing of messages
12221311
// =============================================================================
@@ -1376,7 +1465,7 @@ TEST(JsonEncoder, IncompleteUtf8Sequence) {
13761465

13771466
{ // 🌎 takes four bytes to encode in UTF-8. We test with the first three;
13781467
// This means we're trying to emit a string that consists solely of an
1379-
// incomplete UTF-8 sequence. So the string in the JSON output is emtpy.
1468+
// incomplete UTF-8 sequence. So the string in the JSON output is empty.
13801469
std::string world_utf8 = "🌎";
13811470
ASSERT_EQ(4u, world_utf8.size());
13821471
std::vector<uint8_t> chars(world_utf8.begin(), world_utf8.begin() + 3);

0 commit comments

Comments
 (0)