Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inspector: update inspector_protocol to 89c4adf #39650

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions tools/inspector_protocol/encoding/encoding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -843,14 +843,15 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) {
return;
case MajorType::NEGATIVE: { // INT32.
// INT32 is a signed int32 (int32 makes sense for the
// inspector_protocol, it's not a CBOR limitation); in CBOR,
// the negative values for INT32 are represented as NEGATIVE,
// that is, -1 INT32 is represented as 1 << 5 | 0 (major type 1,
// additional info value 0). So here, we compute the INT32 value
// and then check it against the INT32 min.
int64_t actual_value =
-static_cast<int64_t>(token_start_internal_value_) - 1;
if (!success || actual_value < std::numeric_limits<int32_t>::min()) {
// inspector_protocol, it's not a CBOR limitation); in CBOR, the
// negative values for INT32 are represented as NEGATIVE, that is, -1
// INT32 is represented as 1 << 5 | 0 (major type 1, additional info
// value 0). The minimal allowed INT32 value in our protocol is
// std::numeric_limits<int32_t>::min(). We check for it by directly
// checking the payload against the maximal allowed signed (!) int32
// value.
if (!success || token_start_internal_value_ >
std::numeric_limits<int32_t>::max()) {
SetError(Error::CBOR_INVALID_INT32);
return;
}
Expand Down Expand Up @@ -1857,7 +1858,7 @@ class JsonParser {
// If the |Char| we're dealing with is really a byte, then
// we have utf8 here, and we need to check for multibyte characters
// and transcode them to utf16 (either one or two utf16 chars).
if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) {
if (sizeof(Char) == sizeof(uint8_t) && c > 0x7f) {
// Inspect the leading byte to figure out how long the utf8
// byte sequence is; while doing this initialize |codepoint|
// with the first few bits.
Expand Down Expand Up @@ -1896,7 +1897,7 @@ class JsonParser {
// Disallow overlong encodings for ascii characters, as these
// would include " and other characters significant to JSON
// string termination / control.
if (codepoint < 0x7f)
if (codepoint <= 0x7f)
return false;
// Invalid in UTF8, and can't be represented in UTF16 anyway.
if (codepoint > 0x10ffff)
Expand Down
58 changes: 49 additions & 9 deletions tools/inspector_protocol/encoding/encoding_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,24 @@ TEST(EncodeDecodeInt32Test, RoundtripsInt32Max) {
EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
}

TEST(EncodeDecodeInt32Test, RoundtripsInt32Min) {
// std::numeric_limits<int32_t> is encoded as a uint32 after the initial byte.
std::vector<uint8_t> encoded;
EncodeInt32(std::numeric_limits<int32_t>::min(), &encoded);
// 1 for initial byte, 4 for the uint32.
// first three bits: major type = 1;
// remaining five bits: additional info = 26, indicating payload is uint32.
EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 5>{
{1 << 5 | 26, 0x7f, 0xff, 0xff, 0xff}}));

// Reverse direction: decode with CBORTokenizer.
CBORTokenizer tokenizer(SpanFrom(encoded));
EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag());
EXPECT_EQ(std::numeric_limits<int32_t>::min(), tokenizer.GetInt32());
tokenizer.Next();
EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag());
}

TEST(EncodeDecodeInt32Test, CantRoundtripUint32) {
// 0xdeadbeef is a value which does not fit below
// std::numerical_limits<int32_t>::max(), so we can't encode
Expand Down Expand Up @@ -261,15 +279,21 @@ TEST(EncodeDecodeInt32Test, DecodeErrorCases) {
std::vector<uint8_t> data;
std::string msg;
};
std::vector<TestCase> tests{
{TestCase{
{24},
"additional info = 24 would require 1 byte of payload (but it's 0)"},
TestCase{{27, 0xaa, 0xbb, 0xcc},
"additional info = 27 would require 8 bytes of payload (but "
"it's 3)"},
TestCase{{29}, "additional info = 29 isn't recognized"}}};

std::vector<TestCase> tests{{
TestCase{
{24},
"additional info = 24 would require 1 byte of payload (but it's 0)"},
TestCase{{27, 0xaa, 0xbb, 0xcc},
"additional info = 27 would require 8 bytes of payload (but "
"it's 3)"},
TestCase{{29}, "additional info = 29 isn't recognized"},
TestCase{{1 << 5 | 27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
"Max UINT64 payload is outside the allowed range"},
TestCase{{1 << 5 | 26, 0xff, 0xff, 0xff, 0xff},
"Max UINT32 payload is outside the allowed range"},
TestCase{{1 << 5 | 26, 0x80, 0x00, 0x00, 0x00},
"UINT32 payload w/ high bit set is outside the allowed range"},
}};
for (const TestCase& test : tests) {
SCOPED_TRACE(test.msg);
CBORTokenizer tokenizer(SpanFrom(test.data));
Expand Down Expand Up @@ -1517,6 +1541,22 @@ TEST_F(JsonParserTest, SimpleDictionary) {
log_.str());
}

TEST_F(JsonParserTest, UsAsciiDelCornerCase) {
// DEL (0x7f) is a 7 bit US-ASCII character, and while it is a control
// character according to Unicode, it's not considered a control
// character in https://tools.ietf.org/html/rfc7159#section-7, so
// it can be placed directly into the JSON string, without JSON escaping.
std::string json = "{\"foo\": \"a\x7f\"}";
ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
EXPECT_TRUE(log_.status().ok());
EXPECT_EQ(
"map begin\n"
"string16: foo\n"
"string16: a\x7f\n"
"map end\n",
log_.str());
}

TEST_F(JsonParserTest, Whitespace) {
std::string json = "\n {\n\"msg\"\n: \v\"Hello, world.\"\t\r}\t";
ParseJSON(GetTestPlatform(), SpanFrom(json), &log_);
Expand Down