Commit d6b7b063 authored by Ian Clelland's avatar Ian Clelland

Fix bounds check in platform JSON parser.

WTF::Strings are not null-terminated, so this error would cause a single
character to be read past the end of the string, if the string ends in an
unfinished escape sequence.

(This parser is not currently used by any code in blink)

This also adds a test that would have caught this error, if run on an MSAN
bot, and fixes the same code in the DevTools parser. The DevTools parser
would not trigger an out-of-bounds read in the same situation, since it
operates on null-terminated string data.

Also added is the fuzzer which caught the issue in the first place.

BUG=651166
R=dgozman@chromium.org, mmoroz@chromium.org, pfeldman@chromium.org, pfeldman

Review URL: https://codereview.chromium.org/2380823002 .

Cr-Commit-Position: refs/heads/master@{#422702}
parent 2dfac17b
......@@ -1918,6 +1918,18 @@ fuzzer_test("web_icon_sizes_fuzzer") {
dict = "//testing/libfuzzer/fuzzers/dicts/web_icon_sizes.dict"
}
# Fuzzer for blink::JSONParser.
fuzzer_test("blink_json_parser_fuzzer") {
sources = [
"json/JSONParserFuzzer.cpp",
]
deps = [
":blink_fuzzer_test_support",
":platform",
]
dict = "//testing/libfuzzer/fuzzers/dicts/json.dict"
}
# NOTE: These are legacy unit tests and tests that require a Platform
# object. Do not add more unless the test requires a Platform object.
# These tests are a part of the webkit_unit_tests binary.
......
......@@ -165,6 +165,8 @@ bool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd)
while (start < end) {
Char c = *start++;
if ('\\' == c) {
if (start == end)
return false;
c = *start++;
// Make sure the escaped char is valid.
switch (c) {
......@@ -338,6 +340,8 @@ bool decodeString(const Char* start, const Char* end, StringBuilder* output)
output->append(c);
continue;
}
if (start == end)
return false;
c = *start++;
if (c == 'x') {
......
......@@ -143,6 +143,8 @@ bool parseStringToken(const CharType* start,
while (start < end) {
CharType c = *start++;
if ('\\' == c) {
if (start == end)
return false;
c = *start++;
// Make sure the escaped char is valid.
switch (c) {
......@@ -320,6 +322,8 @@ bool decodeString(const CharType* start,
output->append(c);
continue;
}
if (start == end)
return false;
c = *start++;
if (c == 'x') {
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/json/JSONParser.h"
#include "platform/json/JSONValues.h"
#include "platform/testing/BlinkFuzzerTestSupport.h"
#include "wtf/text/WTFString.h"
#include <stddef.h>
#include <stdint.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
blink::parseJSON(WTF::String(data, size));
return 0;
}
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
blink::InitializeBlinkFuzzTest(argc, argv);
return 0;
}
......@@ -479,7 +479,7 @@ TEST(JSONParserTest, Reading) {
TEST(JSONParserTest, InvalidSanity) {
const char* const invalidJson[] = {
"/* test *", "{\"foo\"", "{\"foo\":", " [", "\"\\u123g\"", "{\n\"eh:\n}",
"////", "*/**/", "/**/", "/*/", "//**/"};
"////", "*/**/", "/**/", "/*/", "//**/", "\"\\"};
for (size_t i = 0; i < WTF_ARRAY_LENGTH(invalidJson); ++i) {
std::unique_ptr<JSONValue> result = parseJSON(invalidJson[i]);
......
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