8143304: Random failures when script size exceeds token limits

Reviewed-by: sundar, attila, lagergren
This commit is contained in:
Hannes Wallnöfer 2015-11-19 14:37:14 +01:00
parent 4897df19a3
commit bc8fbeee55
5 changed files with 61 additions and 10 deletions

View File

@ -3323,9 +3323,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
if (needsScope) {
method.loadCompilerConstant(SCOPE);
}
if (needsScope) {
loadExpressionUnbounded(init);
// block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);

View File

@ -103,6 +103,9 @@ public abstract class AbstractParser {
* @param lineOffset Offset from which lines should be counted
*/
protected AbstractParser(final Source source, final ErrorManager errors, final boolean strict, final int lineOffset) {
if (source.getLength() > Token.LENGTH_MASK) {
throw new RuntimeException("Source exceeds size limit of " + Token.LENGTH_MASK + " bytes");
}
this.source = source;
this.errors = errors;
this.k = -1;

View File

@ -213,7 +213,6 @@ public class Lexer extends Scanner {
* function body. This is used with the feature where the parser is skipping nested function bodies to
* avoid reading ahead unnecessarily when we skip the function bodies.
*/
public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting, final boolean es6, final boolean pauseOnFunctionBody) {
super(source.getContent(), 1, start, len);
this.source = source;

View File

@ -30,11 +30,21 @@ import static jdk.nashorn.internal.parser.TokenKind.LITERAL;
import jdk.nashorn.internal.runtime.Source;
/**
* Basic parse/lex unit.
*
* A token is a 64 bit long value that represents a basic parse/lex unit.
* This class provides static methods to manipulate lexer tokens.
*/
public class Token {
/**
* We use 28 bits for the position and 28 bits for the length of the token.
* This limits the maximal length of code we can handle to 2 ^ 28 - 1 bytes.
*/
public final static int LENGTH_MASK = 0xfffffff;
// The first 8 bits are used for the token type, followed by length and position
private final static int LENGTH_SHIFT = 8;
private final static int POSITION_SHIFT = 36;
private Token() {
}
@ -46,8 +56,9 @@ public class Token {
* @return Token descriptor.
*/
public static long toDesc(final TokenType type, final int position, final int length) {
return (long)position << 32 |
(long)length << 8 |
assert position <= LENGTH_MASK && length <= LENGTH_MASK;
return (long)position << POSITION_SHIFT |
(long)length << LENGTH_SHIFT |
type.ordinal();
}
@ -57,7 +68,7 @@ public class Token {
* @return Start position of the token in the source.
*/
public static int descPosition(final long token) {
return (int)(token >>> 32);
return (int)(token >>> POSITION_SHIFT);
}
/**
@ -98,7 +109,7 @@ public class Token {
* @return Length of the token.
*/
public static int descLength(final long token) {
return (int)token >>> 8;
return (int)((token >>> LENGTH_SHIFT) & LENGTH_MASK);
}
/**

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2015, 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-8059934: Random failures when script size exceeds token limits
*
* @test
* @run
*/
// Make sure that we can successfully evaluate a 100 MB string.
// We don't go beyond that as we'd likely hit heap size limits.
var src = "var x = 'ok';";
for (var i = 0; i < 1000000; i++) {
src += " ";
}
src += "x;";
Assert.assertEquals(100000015, src.length);
Assert.assertEquals("ok", eval(src));