diff --git a/rhino/src/main/java/org/mozilla/javascript/ArrayLikeAbstractOperations.java b/rhino/src/main/java/org/mozilla/javascript/ArrayLikeAbstractOperations.java index 5f6e416a5a..c35e29635c 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ArrayLikeAbstractOperations.java +++ b/rhino/src/main/java/org/mozilla/javascript/ArrayLikeAbstractOperations.java @@ -6,7 +6,6 @@ import java.io.Serializable; import java.util.Comparator; -import org.mozilla.javascript.regexp.NativeRegExp; /** Contains implementation of shared methods useful for arrays and typed arrays. */ public class ArrayLikeAbstractOperations { @@ -146,20 +145,23 @@ static Function getCallbackArg(Context cx, Object callbackArg) { if (!(callbackArg instanceof Function)) { throw ScriptRuntime.notFunctionError(callbackArg); } - if (cx.getLanguageVersion() >= Context.VERSION_ES6 - && (callbackArg instanceof NativeRegExp)) { - // Previously, it was allowed to pass RegExp instance as a callback (it implements - // Function) - // But according to ES2015 21.2.6 Properties of RegExp Instances: - // > RegExp instances are ordinary objects that inherit properties from the RegExp - // prototype object. - // > RegExp instances have internal slots [[RegExpMatcher]], [[OriginalSource]], and - // [[OriginalFlags]]. - // so, no [[Call]] for RegExp-s - throw ScriptRuntime.notFunctionError(callbackArg); - } Function f = (Function) callbackArg; + + if (cx.getLanguageVersion() >= Context.VERSION_ES6) { + RegExpProxy reProxy = ScriptRuntime.getRegExpProxy(cx); + if (reProxy != null && reProxy.isRegExp(f)) + // Previously, it was allowed to pass RegExp instance as a callback (it implements + // Function) + // But according to ES2015 21.2.6 Properties of RegExp Instances: + // > RegExp instances are ordinary objects that inherit properties from the RegExp + // prototype object. + // > RegExp instances have internal slots [[RegExpMatcher]], [[OriginalSource]], and + // [[OriginalFlags]]. + // so, no [[Call]] for RegExp-s + throw ScriptRuntime.notFunctionError(callbackArg); + } + return f; } diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeString.java b/rhino/src/main/java/org/mozilla/javascript/NativeString.java index 75c7e5b99e..75288c1379 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeString.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeString.java @@ -13,7 +13,6 @@ import java.text.Normalizer; import java.util.Locale; import org.mozilla.javascript.ScriptRuntime.StringIdOrIndex; -import org.mozilla.javascript.regexp.NativeRegExp; /** * This class implements the String native object. @@ -468,15 +467,20 @@ public Object execIdCall( case Id_endsWith: String thisString = ScriptRuntime.toString(requireObjectCoercible(cx, thisObj, f)); - if (args.length > 0 && args[0] instanceof NativeRegExp) { - if (ScriptableObject.isTrue( - ScriptableObject.getProperty( - ScriptableObject.ensureScriptable(args[0]), - SymbolKey.MATCH))) { - throw ScriptRuntime.typeErrorById( - "msg.first.arg.not.regexp", - String.class.getSimpleName(), - f.getFunctionName()); + + if (args.length > 0) { + RegExpProxy reProxy = ScriptRuntime.getRegExpProxy(cx); + if (reProxy != null && args[0] instanceof Scriptable) { + Scriptable arg0 = (Scriptable) args[0]; + if (reProxy.isRegExp(arg0)) { + if (ScriptableObject.isTrue( + ScriptableObject.getProperty(arg0, SymbolKey.MATCH))) { + throw ScriptRuntime.typeErrorById( + "msg.first.arg.not.regexp", + String.class.getSimpleName(), + f.getFunctionName()); + } + } } } diff --git a/tests/build.gradle b/tests/build.gradle index e015af1570..191d1cab53 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -10,6 +10,10 @@ dependencies { implementation project(':rhino') implementation project(':rhino-tools') implementation project(':rhino-xml') + + testImplementation("com.tngtech.archunit:archunit-junit4:1.2.0") { + exclude group: 'junit' + } } test { diff --git a/tests/src/test/java/org/mozilla/archunit/ArchitectureTest.java b/tests/src/test/java/org/mozilla/archunit/ArchitectureTest.java new file mode 100644 index 0000000000..2826996e55 --- /dev/null +++ b/tests/src/test/java/org/mozilla/archunit/ArchitectureTest.java @@ -0,0 +1,40 @@ +/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.archunit; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + +import com.tngtech.archunit.core.importer.ImportOption; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.ArchUnitRunner; +import com.tngtech.archunit.lang.ArchRule; +import org.junit.runner.RunWith; + +/** + * Architecture tests. + * + * @author Ronald Brill + */ +@RunWith(ArchUnitRunner.class) +@AnalyzeClasses( + packages = "org.mozilla.javascript", + importOptions = ImportOption.DoNotIncludeTests.class) +public class ArchitectureTest { + + /** Use only the RegExpProxy. */ + @ArchTest + public static final ArchRule regExpProxyRule = + noClasses() + .that() + .resideOutsideOfPackage("org.mozilla.javascript.regexp..") + .and() + .doNotHaveFullyQualifiedName("org.mozilla.javascript.RegExpProxy") + .should() + .dependOnClassesThat() + .resideInAnyPackage("org.mozilla.javascript.regexp.."); +}