提交 33271273 编写于 作者: S sundar

8015346: JSON parsing issues with escaped strings, octal, decimal numbers

Reviewed-by: hannesw, jlaskey
上级 4eed7c8e
......@@ -63,6 +63,7 @@ public class BlockLexicalContext extends LexicalContext {
return sstack.pop();
}
@SuppressWarnings("unchecked")
@Override
public <T extends LexicalContextNode> T pop(final T node) {
T expected = node;
......
......@@ -54,10 +54,9 @@ public class JSONParser extends AbstractParser {
* Constructor
* @param source the source
* @param errors the error manager
* @param strict are we in strict mode
*/
public JSONParser(final Source source, final ErrorManager errors, final boolean strict) {
super(source, errors, strict);
public JSONParser(final Source source, final ErrorManager errors) {
super(source, errors, false);
}
/**
......@@ -135,6 +134,7 @@ public class JSONParser extends AbstractParser {
return ch == '\"';
}
// ECMA 15.12.1.1 The JSON Lexical Grammar - JSONWhiteSpace
@Override
protected boolean isWhitespace(final char ch) {
return Lexer.isJsonWhitespace(ch);
......@@ -144,6 +144,99 @@ public class JSONParser extends AbstractParser {
protected boolean isEOL(final char ch) {
return Lexer.isJsonEOL(ch);
}
// ECMA 15.12.1.1 The JSON Lexical Grammar - JSONNumber
@Override
protected void scanNumber() {
// Record beginning of number.
final int start = position;
// Assume value is a decimal.
TokenType type = TokenType.DECIMAL;
// floating point can't start with a "." with no leading digit before
if (ch0 == '.') {
error(Lexer.message("json.invalid.number"), STRING, position, limit);
}
// First digit of number.
int digit = convertDigit(ch0, 10);
// skip first digit
skip(1);
if (digit != 0) {
// Skip over remaining digits.
while (convertDigit(ch0, 10) != -1) {
skip(1);
}
}
if (ch0 == '.' || ch0 == 'E' || ch0 == 'e') {
// Must be a double.
if (ch0 == '.') {
// Skip period.
skip(1);
boolean mantissa = false;
// Skip mantissa.
while (convertDigit(ch0, 10) != -1) {
mantissa = true;
skip(1);
}
if (! mantissa) {
// no digit after "."
error(Lexer.message("json.invalid.number"), STRING, position, limit);
}
}
// Detect exponent.
if (ch0 == 'E' || ch0 == 'e') {
// Skip E.
skip(1);
// Detect and skip exponent sign.
if (ch0 == '+' || ch0 == '-') {
skip(1);
}
boolean exponent = false;
// Skip exponent.
while (convertDigit(ch0, 10) != -1) {
exponent = true;
skip(1);
}
if (! exponent) {
// no digit after "E"
error(Lexer.message("json.invalid.number"), STRING, position, limit);
}
}
type = TokenType.FLOATING;
}
// Add number token.
add(type, start);
}
// ECMA 15.12.1.1 The JSON Lexical Grammar - JSONEscapeCharacter
@Override
protected boolean isEscapeCharacter(final char ch) {
switch (ch) {
case '"':
case '/':
case '\\':
case 'b':
case 'f':
case 'n':
case 'r':
case 't':
// could be unicode escape
case 'u':
return true;
default:
return false;
}
}
};
k = -1;
......
......@@ -648,7 +648,7 @@ public class Lexer extends Scanner {
*
* @return The converted digit or -1 if invalid.
*/
private static int convertDigit(final char ch, final int base) {
protected static int convertDigit(final char ch, final int base) {
int digit;
if ('0' <= ch && ch <= '9') {
......@@ -908,7 +908,7 @@ public class Lexer extends Scanner {
/**
* Scan over a string literal.
*/
private void scanString(final boolean add) {
protected void scanString(final boolean add) {
// Type of string.
TokenType type = STRING;
// Record starting quote.
......@@ -925,6 +925,9 @@ public class Lexer extends Scanner {
if (ch0 == '\\') {
type = ESCSTRING;
skip(1);
if (! isEscapeCharacter(ch0)) {
error(Lexer.message("invalid.escape.char"), STRING, position, limit);
}
if (isEOL(ch0)) {
// Multiline string literal
skipEOL(false);
......@@ -978,6 +981,16 @@ public class Lexer extends Scanner {
}
}
/**
* Is the given character a valid escape char after "\" ?
*
* @param ch character to be checked
* @return if the given character is valid after "\"
*/
protected boolean isEscapeCharacter(final char ch) {
return true;
}
/**
* Convert string to number.
*
......@@ -1024,7 +1037,7 @@ public class Lexer extends Scanner {
/**
* Scan a number.
*/
private void scanNumber() {
protected void scanNumber() {
// Record beginning of number.
final int start = position;
// Assume value is a decimal.
......@@ -1583,7 +1596,7 @@ public class Lexer extends Scanner {
return null;
}
private static String message(final String msgId, final String... args) {
protected static String message(final String msgId, final String... args) {
return ECMAErrors.getMessage("lexer.error." + msgId, args);
}
......
......@@ -66,13 +66,9 @@ public final class JSONFunctions {
*/
public static Object parse(final Object text, final Object reviver) {
final String str = JSType.toString(text);
final Context context = Context.getContextTrusted();
final JSONParser parser = new JSONParser(
new Source("<json>", str),
new Context.ThrowErrorManager(),
(context != null) ?
context.getEnv()._strict :
false);
new Context.ThrowErrorManager());
Node node;
......
......@@ -28,6 +28,8 @@ lexer.error.missing.close.quote=Missing close quote
lexer.error.invalid.hex=Invalid hex digit
lexer.error.invalid.octal=Invalid octal digit
lexer.error.strict.no.octal=cannot use octal escapes in strict mode
lexer.error.json.invalid.number=Invalid JSON number format
lexer.error.invalid.escape.char=Invalid escape character
lexer.error.illegal.identifier.character=Illegal character in identifier
parser.error.illegal.continue.stmt=Illegal continue statement
......
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8015346: JSON parsing issues with escaped strings, octal, decimal numbers *
* @test
* @run
*/
function checkJSON(str) {
try {
JSON.parse(str);
fail("should have thrown SyntaxError for JSON.parse on " + str);
} catch (e) {
if (! (e instanceof SyntaxError)) {
fail("Expected SyntaxError, but got " + e);
}
}
}
// invalid escape in a string
checkJSON('"\\a"')
// invalid floating point number patterns
checkJSON("1.")
checkJSON(".8")
checkJSON("2.3e+")
checkJSON("0.3E+")
// octal, hexadecimal not allowed
checkJSON("08")
checkJSON("06")
checkJSON('0x3')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册