mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8027302: Identifiers containing unicode escapes are not recognized as reserved words
Reviewed-by: jlaskey, sundar
This commit is contained in:
parent
7d50345d2d
commit
61995f03d4
6 changed files with 358 additions and 34 deletions
|
@ -477,4 +477,14 @@ public final class IdentNode extends Expression implements PropertyKey, Function
|
|||
public IdentNode setIsDestructuredParameter() {
|
||||
return new IdentNode(this, name, type, flags | DESTRUCTURED_PARAMETER, programPoint, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the source code for this ident contains a unicode escape sequence by comparing
|
||||
* the length of its name with its length in source code.
|
||||
*
|
||||
* @return true if ident source contains a unicode escape sequence
|
||||
*/
|
||||
public boolean containsEscapes() {
|
||||
return Token.descLength(getToken()) != name.length();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -786,15 +786,9 @@ public class Lexer extends Scanner {
|
|||
if (ch0 == '\\' && ch1 == 'u') {
|
||||
skip(2);
|
||||
final int ch = hexSequence(4, TokenType.IDENT);
|
||||
if (isWhitespace((char)ch)) {
|
||||
return null;
|
||||
}
|
||||
if (ch < 0) {
|
||||
sb.append('\\');
|
||||
sb.append('u');
|
||||
} else {
|
||||
sb.append((char)ch);
|
||||
}
|
||||
assert ! isWhitespace((char)ch);
|
||||
assert ch >= 0;
|
||||
sb.append((char)ch);
|
||||
} else {
|
||||
// Add regular character.
|
||||
sb.append(ch0);
|
||||
|
@ -994,9 +988,6 @@ 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);
|
||||
|
@ -1093,9 +1084,6 @@ public class Lexer extends Scanner {
|
|||
} else if (ch0 == '\\') {
|
||||
skip(1);
|
||||
// EscapeSequence
|
||||
if (!isEscapeCharacter(ch0)) {
|
||||
error(Lexer.message("invalid.escape.char"), TEMPLATE, position, limit);
|
||||
}
|
||||
if (isEOL(ch0)) {
|
||||
// LineContinuation
|
||||
skipEOL(false);
|
||||
|
@ -1114,16 +1102,6 @@ public class Lexer extends Scanner {
|
|||
error(Lexer.message("missing.close.quote"), TEMPLATE, position, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
|
|
@ -1472,12 +1472,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
*/
|
||||
private void verifyIdent(final IdentNode ident, final String contextString) {
|
||||
verifyStrictIdent(ident, contextString);
|
||||
if (isES6()) {
|
||||
final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
|
||||
if (tokenType != IDENT && tokenType.getKind() != TokenKind.FUTURESTRICT) {
|
||||
throw error(expectMessage(IDENT));
|
||||
}
|
||||
}
|
||||
checkEscapedKeyword(ident);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1502,6 +1497,18 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ES6 11.6.2: A code point in a ReservedWord cannot be expressed by a | UnicodeEscapeSequence.
|
||||
*/
|
||||
private void checkEscapedKeyword(final IdentNode ident) {
|
||||
if (isES6() && ident.containsEscapes()) {
|
||||
final TokenType tokenType = TokenLookup.lookupKeyword(ident.getName().toCharArray(), 0, ident.getName().length());
|
||||
if (tokenType != IDENT && !(tokenType.getKind() == TokenKind.FUTURESTRICT && !isStrictMode)) {
|
||||
throw error(AbstractParser.message("keyword.escaped.character"), ident.getToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* VariableStatement :
|
||||
* var VariableDeclarationList ;
|
||||
|
@ -2646,7 +2653,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
});
|
||||
} else {
|
||||
// ECMA 12.4.1 strict mode restrictions
|
||||
verifyStrictIdent((IdentNode) exception, "catch argument");
|
||||
verifyIdent((IdentNode) exception, "catch argument");
|
||||
}
|
||||
|
||||
|
||||
|
@ -2761,6 +2768,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
break;
|
||||
}
|
||||
detectSpecialProperty(ident);
|
||||
checkEscapedKeyword(ident);
|
||||
return ident;
|
||||
case OCTAL_LEGACY:
|
||||
if (isStrictMode) {
|
||||
|
@ -3404,6 +3412,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
// Catch special functions.
|
||||
if (lhs instanceof IdentNode) {
|
||||
detectSpecialFunction((IdentNode)lhs);
|
||||
checkEscapedKeyword((IdentNode)lhs);
|
||||
}
|
||||
|
||||
lhs = new CallNode(callLine, callToken, finish, lhs, arguments, false);
|
||||
|
@ -3779,7 +3788,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
expect(IDENT);
|
||||
}
|
||||
name = getIdent();
|
||||
verifyStrictIdent(name, "function name");
|
||||
verifyIdent(name, "function name");
|
||||
} else if (isStatement) {
|
||||
// Nashorn extension: anonymous function statements.
|
||||
// Do not allow anonymous function statement if extensions
|
||||
|
@ -4871,7 +4880,7 @@ public class Parser extends AbstractParser implements Loggable {
|
|||
final String contextString = "function parameter";
|
||||
if (param instanceof IdentNode) {
|
||||
final IdentNode ident = (IdentNode)param;
|
||||
verifyStrictIdent(ident, contextString);
|
||||
verifyIdent(ident, contextString);
|
||||
final ParserContextFunctionNode currentFunction = lc.getCurrentFunction();
|
||||
if (currentFunction != null) {
|
||||
currentFunction.addParameterBinding(ident);
|
||||
|
|
|
@ -62,6 +62,7 @@ parser.error.regex.syntax={0}
|
|||
parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
|
||||
parser.error.missing.const.assignment=Missing assignment to constant "{0}"
|
||||
parser.error.unterminated.template.expression=Expected } after expression in template literal
|
||||
parser.error.keyword.escaped.character=Keyword must not contain escaped characters
|
||||
|
||||
# ES6 mode error messages
|
||||
parser.error.multiple.constructors=Class contains more than one constructor
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue