提交 dbf57739 编写于 作者: L lana

Merge

...@@ -210,42 +210,10 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { ...@@ -210,42 +210,10 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
} }
private static ClassLoader getAppClassLoader() { private static ClassLoader getAppClassLoader() {
if (System.getSecurityManager() == null) { // Revisit: script engine implementation needs the capability to
return Thread.currentThread().getContextClassLoader(); // find the class loader of the context in which the script engine
} // is running so that classes will be found and loaded properly
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
// Try to determine the caller class loader. Use that if it can be
// found. If not, use the class loader of nashorn itself as the
// "application" class loader for scripts.
// User could have called ScriptEngineFactory.getScriptEngine()
//
// <caller>
// <factory.getScriptEngine()>
// <factory.getAppClassLoader()>
// <Reflection.getCallerClass()>
//
// or used one of the getEngineByABC methods of ScriptEngineManager.
//
// <caller>
// <ScriptEngineManager.getEngineByName()>
// <factory.getScriptEngine()>
// <factory.getAppClassLoader()>
// <Reflection.getCallerClass()>
// So, stack depth is 3 or 4 (recall it is zero based). We try
// stack depths 3, 4 and look for non-bootstrap caller.
Class<?> caller = null;
for (int depth = 3; depth < 5; depth++) {
caller = Reflection.getCallerClass(depth);
if (caller != null && caller.getClassLoader() != null) {
// found a non-bootstrap caller
break;
}
}
final ClassLoader ccl = (caller == null)? null : caller.getClassLoader();
// if caller loader is null, then use nashorn's own loader
return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl; return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl;
} }
} }
...@@ -76,7 +76,7 @@ public final class NativeArray extends ScriptObject { ...@@ -76,7 +76,7 @@ public final class NativeArray extends ScriptObject {
private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class, private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class); Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class);
private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", int.class, private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class,
ScriptFunction.class, Object.class, Object.class, Object.class); ScriptFunction.class, Object.class, Object.class, Object.class);
private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class); private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
...@@ -793,11 +793,15 @@ public final class NativeArray extends ScriptObject { ...@@ -793,11 +793,15 @@ public final class NativeArray extends ScriptObject {
} }
private static ScriptFunction compareFunction(final Object comparefn) { private static ScriptFunction compareFunction(final Object comparefn) {
try { if (comparefn == ScriptRuntime.UNDEFINED) {
return (ScriptFunction)comparefn; return null;
} catch (final ClassCastException e) { }
return null; //undefined or null
if (! (comparefn instanceof ScriptFunction)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(comparefn));
} }
return (ScriptFunction)comparefn;
} }
private static Object[] sort(final Object[] array, final Object comparefn) { private static Object[] sort(final Object[] array, final Object comparefn) {
...@@ -819,7 +823,7 @@ public final class NativeArray extends ScriptObject { ...@@ -819,7 +823,7 @@ public final class NativeArray extends ScriptObject {
if (cmp != null) { if (cmp != null) {
try { try {
return (int)CALL_CMP.invokeExact(cmp, cmpThis, x, y); return (int)Math.signum((double)CALL_CMP.invokeExact(cmp, cmpThis, x, y));
} catch (final RuntimeException | Error e) { } catch (final RuntimeException | Error e) {
throw e; throw e;
} catch (final Throwable t) { } catch (final Throwable t) {
......
...@@ -56,6 +56,7 @@ import jdk.nashorn.internal.ir.debug.PrintVisitor; ...@@ -56,6 +56,7 @@ import jdk.nashorn.internal.ir.debug.PrintVisitor;
import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
import jdk.nashorn.internal.runtime.options.Options; import jdk.nashorn.internal.runtime.options.Options;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection; import sun.reflect.Reflection;
/** /**
...@@ -113,11 +114,12 @@ public final class Context { ...@@ -113,11 +114,12 @@ public final class Context {
* Get the current global scope * Get the current global scope
* @return the current global scope * @return the current global scope
*/ */
@CallerSensitive
public static ScriptObject getGlobal() { public static ScriptObject getGlobal() {
final SecurityManager sm = System.getSecurityManager(); final SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
// skip getCallerClass and getGlobal and get to the real caller // skip getCallerClass and getGlobal and get to the real caller
Class<?> caller = Reflection.getCallerClass(2); Class<?> caller = Reflection.getCallerClass();
ClassLoader callerLoader = caller.getClassLoader(); ClassLoader callerLoader = caller.getClassLoader();
// Allow this method only for nashorn's own classes, objects // Allow this method only for nashorn's own classes, objects
......
...@@ -40,7 +40,7 @@ public class RegExpFactory { ...@@ -40,7 +40,7 @@ public class RegExpFactory {
private final static String JONI = "joni"; private final static String JONI = "joni";
static { static {
final String impl = Options.getStringProperty("nashorn.regexp.impl", JDK); final String impl = Options.getStringProperty("nashorn.regexp.impl", JONI);
switch (impl) { switch (impl) {
case JONI: case JONI:
instance = new JoniRegExp.Factory(); instance = new JoniRegExp.Factory();
......
...@@ -47,9 +47,6 @@ final class RegExpScanner extends Scanner { ...@@ -47,9 +47,6 @@ final class RegExpScanner extends Scanner {
*/ */
private final StringBuilder sb; private final StringBuilder sb;
/** Is this the special case of a regexp that never matches anything */
private boolean neverMatches;
/** Expected token table */ /** Expected token table */
private final Map<Character, Integer> expected = new HashMap<>(); private final Map<Character, Integer> expected = new HashMap<>();
...@@ -99,24 +96,17 @@ final class RegExpScanner extends Scanner { ...@@ -99,24 +96,17 @@ final class RegExpScanner extends Scanner {
} }
private void processForwardReferences() { private void processForwardReferences() {
if (neverMatches()) {
return;
}
Iterator<Integer> iterator = forwardReferences.descendingIterator(); Iterator<Integer> iterator = forwardReferences.descendingIterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
final int pos = iterator.next(); final int pos = iterator.next();
final int num = iterator.next(); final int num = iterator.next();
if (num > caps.size()) { if (num > caps.size()) {
// Non-existing reference should never match, if smaller than 8 convert to octal escape // Non-existing backreference. If the number begins with a valid octal convert it to
// to be compatible with other engines. // Unicode escape and append the rest to a literal character sequence.
if (num < 8) { final StringBuilder buffer = new StringBuilder();
String escape = "\\x0" + num; octalOrLiteral(Integer.toString(num), buffer);
sb.insert(pos, escape); sb.insert(pos, buffer);
} else {
neverMatches = true;
break;
}
} }
} }
...@@ -140,9 +130,6 @@ final class RegExpScanner extends Scanner { ...@@ -140,9 +130,6 @@ final class RegExpScanner extends Scanner {
} }
scanner.processForwardReferences(); scanner.processForwardReferences();
if (scanner.neverMatches()) {
return null; // never matches
}
// Throw syntax error unless we parsed the entire JavaScript regexp without syntax errors // Throw syntax error unless we parsed the entire JavaScript regexp without syntax errors
if (scanner.position != string.length()) { if (scanner.position != string.length()) {
...@@ -151,16 +138,6 @@ final class RegExpScanner extends Scanner { ...@@ -151,16 +138,6 @@ final class RegExpScanner extends Scanner {
} }
return scanner; return scanner;
}
/**
* Does this regexp ever match anything? Use of e.g. [], which is legal in JavaScript,
* is an example where we never match
*
* @return boolean
*/
private boolean neverMatches() {
return neverMatches;
} }
final StringBuilder getStringBuilder() { final StringBuilder getStringBuilder() {
...@@ -282,23 +259,16 @@ final class RegExpScanner extends Scanner { ...@@ -282,23 +259,16 @@ final class RegExpScanner extends Scanner {
} }
if (atom()) { if (atom()) {
boolean emptyCharacterClass = false; // Check for character classes that never or always match
if (sb.toString().endsWith("[]")) { if (sb.toString().endsWith("[]")) {
emptyCharacterClass = true; sb.setLength(sb.length() - 1);
sb.append("^\\s\\S]");
} else if (sb.toString().endsWith("[^]")) { } else if (sb.toString().endsWith("[^]")) {
sb.setLength(sb.length() - 2); sb.setLength(sb.length() - 2);
sb.append("\\s\\S]"); sb.append("\\s\\S]");
} }
boolean quantifier = quantifier(); quantifier();
if (emptyCharacterClass) {
if (!quantifier) {
neverMatches = true; //never matches ever.
}
// Note: we could check if quantifier has min zero to mark empty character class as dead.
}
return true; return true;
} }
...@@ -626,13 +596,14 @@ final class RegExpScanner extends Scanner { ...@@ -626,13 +596,14 @@ final class RegExpScanner extends Scanner {
* ABCDEFGHIJKLMNOPQRSTUVWXYZ * ABCDEFGHIJKLMNOPQRSTUVWXYZ
*/ */
private boolean controlLetter() { private boolean controlLetter() {
final char c = Character.toUpperCase(ch0); // To match other engines we also accept '0'..'9' and '_' as control letters inside a character class.
if (c >= 'A' && c <= 'Z') { if ((ch0 >= 'A' && ch0 <= 'Z') || (ch0 >= 'a' && ch0 <= 'z')
|| (inCharClass && (isDecimalDigit(ch0) || ch0 == '_'))) {
// for some reason java regexps don't like control characters on the // for some reason java regexps don't like control characters on the
// form "\\ca".match([string with ascii 1 at char0]). Translating // form "\\ca".match([string with ascii 1 at char0]). Translating
// them to unicode does it though. // them to unicode does it though.
sb.setLength(sb.length() - 1); sb.setLength(sb.length() - 1);
unicode(c - 'A' + 1); unicode(ch0 % 32, sb);
skip(1); skip(1);
return true; return true;
} }
...@@ -651,14 +622,7 @@ final class RegExpScanner extends Scanner { ...@@ -651,14 +622,7 @@ final class RegExpScanner extends Scanner {
} }
// ES 5.1 A.7 requires "not IdentifierPart" here but all major engines accept any character here. // ES 5.1 A.7 requires "not IdentifierPart" here but all major engines accept any character here.
if (ch0 == 'c') { if (ch0 == 'c') {
// Ignore invalid control letter escape if within a character class sb.append('\\'); // Treat invalid \c control sequence as \\c
if (inCharClass && ch1 != ']') {
sb.setLength(sb.length() - 1);
skip(2);
return true;
} else {
sb.append('\\'); // Treat invalid \c control sequence as \\c
}
} else if (NON_IDENT_ESCAPES.indexOf(ch0) == -1) { } else if (NON_IDENT_ESCAPES.indexOf(ch0) == -1) {
sb.setLength(sb.length() - 1); sb.setLength(sb.length() - 1);
} }
...@@ -673,7 +637,7 @@ final class RegExpScanner extends Scanner { ...@@ -673,7 +637,7 @@ final class RegExpScanner extends Scanner {
final int startIn = position; final int startIn = position;
final int startOut = sb.length(); final int startOut = sb.length();
if (ch0 == '0' && !isDecimalDigit(ch1)) { if (ch0 == '0' && !isOctalDigit(ch1)) {
skip(1); skip(1);
// DecimalEscape :: 0. If i is zero, return the EscapeValue consisting of a <NUL> character (Unicodevalue0000); // DecimalEscape :: 0. If i is zero, return the EscapeValue consisting of a <NUL> character (Unicodevalue0000);
sb.append("\u0000"); sb.append("\u0000");
...@@ -681,50 +645,56 @@ final class RegExpScanner extends Scanner { ...@@ -681,50 +645,56 @@ final class RegExpScanner extends Scanner {
} }
if (isDecimalDigit(ch0)) { if (isDecimalDigit(ch0)) {
final int num = ch0 - '0';
// Single digit escape, treat as backreference. if (ch0 == '0') {
if (!isDecimalDigit(ch1)) { // We know this is an octal escape.
if (num <= caps.size() && caps.get(num - 1).getNegativeLookaheadLevel() > 0) { if (inCharClass) {
// Convert octal escape to unicode escape if inside character class.
int octalValue = 0;
while (isOctalDigit(ch0)) {
octalValue = octalValue * 8 + ch0 - '0';
skip(1);
}
unicode(octalValue, sb);
} else {
// Copy decimal escape as-is
decimalDigits();
}
} else {
// This should be a backreference, but could also be an octal escape or even a literal string.
int decimalValue = 0;
while (isDecimalDigit(ch0)) {
decimalValue = decimalValue * 10 + ch0 - '0';
skip(1);
}
if (inCharClass) {
// No backreferences in character classes. Encode as unicode escape or literal char sequence
sb.setLength(sb.length() - 1);
octalOrLiteral(Integer.toString(decimalValue), sb);
} else if (decimalValue <= caps.size() && caps.get(decimalValue - 1).getNegativeLookaheadLevel() > 0) {
// Captures that live inside a negative lookahead are dead after the // Captures that live inside a negative lookahead are dead after the
// lookahead and will be undefined if referenced from outside. // lookahead and will be undefined if referenced from outside.
if (caps.get(num - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) { if (caps.get(decimalValue - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) {
sb.setLength(sb.length() - 1); sb.setLength(sb.length() - 1);
} else { } else {
sb.append(ch0); sb.append(decimalValue);
} }
skip(1); } else if (decimalValue > caps.size()) {
return true; // Forward reference to a capture group. Forward references are always undefined so we can omit
} else if (num > caps.size()) { // it from the output buffer. However, if the target capture does not exist, we need to rewrite
// Forward reference to a capture group. Forward references are always undefined so we // the reference as hex escape or literal string, so register the reference for later processing.
// can omit it from the output buffer. Additionally, if the capture group does not exist
// the whole regexp becomes invalid, so register the reference for later processing.
sb.setLength(sb.length() - 1); sb.setLength(sb.length() - 1);
forwardReferences.add(num); forwardReferences.add(decimalValue);
forwardReferences.add(sb.length()); forwardReferences.add(sb.length());
skip(1); } else {
return true; // Append as backreference
} sb.append(decimalValue);
}
if (inCharClass) {
// Convert octal escape to unicode escape if inside character class.
StringBuilder digit = new StringBuilder(4);
while (isDecimalDigit(ch0)) {
digit.append(ch0);
skip(1);
}
int value = Integer.parseInt(digit.toString(), 8); //throws exception that leads to SyntaxError if not octal
if (value > 0xff) {
throw new NumberFormatException(digit.toString());
} }
unicode(value);
} else {
// Copy decimal escape as-is
decimalDigits();
} }
return true; return true;
} }
...@@ -904,7 +874,6 @@ final class RegExpScanner extends Scanner { ...@@ -904,7 +874,6 @@ final class RegExpScanner extends Scanner {
switch (ch0) { switch (ch0) {
case ']': case ']':
case '-': case '-':
case '\0':
return false; return false;
case '[': case '[':
...@@ -965,13 +934,41 @@ final class RegExpScanner extends Scanner { ...@@ -965,13 +934,41 @@ final class RegExpScanner extends Scanner {
return true; return true;
} }
private void unicode(final int value) { private void unicode(final int value, final StringBuilder buffer) {
final String hex = Integer.toHexString(value); final String hex = Integer.toHexString(value);
sb.append('u'); buffer.append('u');
for (int i = 0; i < 4 - hex.length(); i++) { for (int i = 0; i < 4 - hex.length(); i++) {
sb.append('0'); buffer.append('0');
}
buffer.append(hex);
}
// Convert what would have been a backreference into a unicode escape, or a number literal, or both.
private void octalOrLiteral(final String numberLiteral, final StringBuilder buffer) {
final int length = numberLiteral.length();
int octalValue = 0;
int pos = 0;
// Maximum value for octal escape is 0377 (255) so we stop the loop at 32
while (pos < length && octalValue < 0x20) {
final char ch = numberLiteral.charAt(pos);
if (isOctalDigit(ch)) {
octalValue = octalValue * 8 + ch - '0';
} else {
break;
}
pos++;
} }
sb.append(hex); if (octalValue > 0) {
buffer.append('\\');
unicode(octalValue, buffer);
buffer.append(numberLiteral.substring(pos));
} else {
buffer.append(numberLiteral);
}
}
private static boolean isOctalDigit(final char ch) {
return ch >= '0' && ch <= '7';
} }
private static boolean isDecimalDigit(final char ch) { private static boolean isDecimalDigit(final char ch) {
......
...@@ -156,9 +156,6 @@ final class Analyser extends Parser { ...@@ -156,9 +156,6 @@ final class Analyser extends Parser {
env.memNodes = null; env.memNodes = null;
new ArrayCompiler(this).compile();
//new AsmCompiler(this).compile();
if (regex.numRepeat != 0 || regex.btMemEnd != 0) { if (regex.numRepeat != 0 || regex.btMemEnd != 0) {
regex.stackPopLevel = StackPopLevel.ALL; regex.stackPopLevel = StackPopLevel.ALL;
} else { } else {
......
...@@ -55,8 +55,9 @@ public final class Regex implements RegexState { ...@@ -55,8 +55,9 @@ public final class Regex implements RegexState {
int[]repeatRangeLo; int[]repeatRangeLo;
int[]repeatRangeHi; int[]repeatRangeHi;
public WarnCallback warnings; WarnCallback warnings;
public MatcherFactory factory; MatcherFactory factory;
private Analyser analyser;
int options; int options;
int userOptions; int userOptions;
...@@ -140,19 +141,33 @@ public final class Regex implements RegexState { ...@@ -140,19 +141,33 @@ public final class Regex implements RegexState {
this.caseFoldFlag = caseFoldFlag; this.caseFoldFlag = caseFoldFlag;
this.warnings = warnings; this.warnings = warnings;
new Analyser(new ScanEnvironment(this, syntax), chars, p, end).compile(); this.analyser = new Analyser(new ScanEnvironment(this, syntax), chars, p, end);
this.analyser.compile();
this.warnings = null; this.warnings = null;
} }
public void compile() {
if (factory == null && analyser != null) {
Compiler compiler = new ArrayCompiler(analyser);
analyser = null; // only do this once
compiler.compile();
}
}
public Matcher matcher(char[] chars) { public Matcher matcher(char[] chars) {
return matcher(chars, 0, chars.length); return matcher(chars, 0, chars.length);
} }
public Matcher matcher(char[] chars, int p, int end) { public Matcher matcher(char[] chars, int p, int end) {
compile();
return factory.create(this, chars, p, end); return factory.create(this, chars, p, end);
} }
public WarnCallback getWarnings() {
return warnings;
}
public int numberOfCaptures() { public int numberOfCaptures() {
return numMem; return numMem;
} }
......
...@@ -231,12 +231,12 @@ public final class QuantifierNode extends StateNode { ...@@ -231,12 +231,12 @@ public final class QuantifierNode extends StateNode {
break; break;
case DEL: case DEL:
env.reg.warnings.warn(new String(chars, p, end) + env.reg.getWarnings().warn(new String(chars, p, end) +
" redundant nested repeat operator"); " redundant nested repeat operator");
break; break;
default: default:
env.reg.warnings.warn(new String(chars, p, end) + env.reg.getWarnings().warn(new String(chars, p, end) +
" nested repeat operator " + Reduce.PopularQStr[targetQNum] + " nested repeat operator " + Reduce.PopularQStr[targetQNum] +
" and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" + " and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'"); Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
......
/*
* 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-8011714: Regexp decimal escape handling still not correct
*
* @test
* @run
*/
// \0 should be interpreted as <NUL> character here
print(/\08/.test("\x008"));
print(/[\08]/.test("8"));
print(/[\08]/.test("\x00"));
// Can't be converted to octal thus encoded as literal char sequence
print(/\8/.exec("\\8"));
print(/[\8]/.exec("\\"));
print(/[\8]/.exec("8"));
// 0471 is too high for an octal escape so it is \047 outside a character class
// and \\471 inside a character class
print(/\471/.exec("\x271"));
print(/[\471]/.exec("1"));
print(/[\471]/.exec("\x27"));
// 0366 is a valid octal escape (246)
print(/\366/.test("\xf6"));
print(/[\366]/.test("\xf6"));
print(/[\366]/.test("\xf6"));
// more tests for conversion of invalid backreferences to octal escapes or literals
print(/(a)(b)(c)(d)\4/.exec("abcdd"));
print(/(a)(b)(c)(d)\4x/.exec("abcddx"));
print(/(a)(b)(c)(d)\47/.exec("abcdd7"));
print(/(a)(b)(c)(d)\47/.exec("abcd\x27"));
print(/(a)(b)(c)(d)\47xyz/.exec("abcd\x27xyz"));
print(/(a)(b)(c)(d)[\47]/.exec("abcd\x27"));
print(/(a)(b)(c)(d)[\47]xyz/.exec("abcd\x27xyz"));
print(/(a)(b)(c)(d)\48/.exec("abcd\x048"));
print(/(a)(b)(c)(d)\48xyz/.exec("abcd\x048xyz"));
print(/(a)(b)(c)(d)[\48]/.exec("abcd\x04"));
print(/(a)(b)(c)(d)[\48]xyz/.exec("abcd\x04xyz"));
print(/(a)(b)(c)(d)\84/.exec("abcd84"));
print(/(a)(b)(c)(d)\84xyz/.exec("abcd84xyz"));
print(/(a)(b)(c)(d)[\84]/.exec("abcd8"));
print(/(a)(b)(c)(d)[\84]xyz/.exec("abcd8xyz"));
true
true
true
8
null
8
'1
1
'
true
true
true
abcdd,a,b,c,d
abcddx,a,b,c,d
null
abcd',a,b,c,d
abcd'xyz,a,b,c,d
abcd',a,b,c,d
abcd'xyz,a,b,c,d
abcd8,a,b,c,d
abcd8xyz,a,b,c,d
abcd,a,b,c,d
abcdxyz,a,b,c,d
abcd84,a,b,c,d
abcd84xyz,a,b,c,d
abcd8,a,b,c,d
abcd8xyz,a,b,c,d
/*
* 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-8011749: Bugs with empty character class handling
*
* @test
* @run
*/
// empty class in alternative
print(/[]|[^]/.exec("a"));
print(/[]|[]/.test("a"));
print(/[]|[]|[a]/.exec("a"));
// empty class in negative lookahead
print(/(?![])/.test(""));
print(/(?![])./.exec("a"));
/*
* 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-8011756: Wrong characters supported in RegExp \c escape
*
* @test
* @run
*/
// Invalid control letters should be escaped:
print(/\cı/.test("\x09"));
print(/\cı/.test("\\"));
print(/\cſ/.test("\x13"));
print(/\cſ/.test("\\cſ"));
print(/[\cſ]/.test("\x13"));
print(/[\cſ]/.test("\\"));
print(/[\cſ]/.test("c"));
print(/[\cſ]/.test("ſ"));
print(/[\c#]/.test("\\"));
print(/[\c#]/.test("c"));
print(/[\c#]/.test("#"));
// The characters that are supported by other engines are '0'-'9', '_':
print(/[\c0]/.test("\x10"));
print(/[\c1]/.test("\x11"));
print(/[\c2]/.test("\x12"));
print(/[\c3]/.test("\x13"));
print(/[\c4]/.test("\x14"));
print(/[\c5]/.test("\x15"));
print(/[\c6]/.test("\x16"));
print(/[\c7]/.test("\x17"));
print(/[\c8]/.test("\x18"));
print(/[\c9]/.test("\x19"));
print(/[\c_]/.test("\x1F"));
false
true
false
true
false
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
true
/*
* 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-8011960: [2,1].sort(null) should throw TypeError
*
* @test
* @run
*/
function check(func) {
try {
[2,1].sort(func);
fail("should have thrown TypeError for :" + func);
} catch (e) {
if (! (e instanceof TypeError)) {
fail("TypeError not thrown for sort comparefn: " + func);
}
}
}
// should not result in TypeError for undefined
[1, 2].sort(undefined);
// TypeError for null
check(null);
// should result in TypeError other non-callable params
check(32);
check("foo");
check(false);
check({});
check([]);
/*
* 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-8011974: Comparator function returning negative and positive Infinity does not work as expected with Array.prototype.sort
*
* @test
* @run
*/
function compare(x, y) {
return x < y? -Infinity : (x > y? Infinity: 0)
}
var sorted = [5, 4, 3, 2, 1].sort(compare);
if (sorted + '' != "1,2,3,4,5") {
fail("Array.prototype.sort does not work when compare returns +/-Infinity");
}
/*
* 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-8011980: Allow NUL character in character class
*
* @test
* @run
*/
print(RegExp("\0").test("\0"));
print(RegExp("[\0]").test("\0"));
print(RegExp("[\x00]").test("\0"));
print(RegExp("[\u0000]").test("\0"));
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册