From ce27a03c19cb4c63f433908f2313cea65a040ad3 Mon Sep 17 00:00:00 2001 From: Ronald Brill Date: Sun, 12 Nov 2023 11:17:22 +0100 Subject: [PATCH 1/2] make sure to use only the RegExpProxy interface --- build.gradle | 3 ++ src/org/mozilla/javascript/NativeArray.java | 30 ++++++++------- src/org/mozilla/javascript/NativeString.java | 16 +++++--- .../javascript/archunit/ArchitectureTest.java | 37 +++++++++++++++++++ 4 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java diff --git a/build.gradle b/build.gradle index 69f468e48e..3607e3059e 100644 --- a/build.gradle +++ b/build.gradle @@ -59,6 +59,9 @@ sourceSets { dependencies { testImplementation "junit:junit:4.13.2" + testImplementation("com.tngtech.archunit:archunit-junit4:1.2.0") { + exclude group: 'junit' + } testImplementation "org.yaml:snakeyaml:1.28" testImplementation "javax.xml.soap:javax.xml.soap-api:1.4.0" jmhImplementation project diff --git a/src/org/mozilla/javascript/NativeArray.java b/src/org/mozilla/javascript/NativeArray.java index 9096dec92e..348fc9d9ae 100644 --- a/src/org/mozilla/javascript/NativeArray.java +++ b/src/org/mozilla/javascript/NativeArray.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; -import org.mozilla.javascript.regexp.NativeRegExp; + import org.mozilla.javascript.xml.XMLObject; /** @@ -1152,20 +1152,24 @@ private 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/src/org/mozilla/javascript/NativeString.java b/src/org/mozilla/javascript/NativeString.java index 8ee76d7168..c5f4d732ce 100644 --- a/src/org/mozilla/javascript/NativeString.java +++ b/src/org/mozilla/javascript/NativeString.java @@ -12,6 +12,7 @@ import java.text.Collator; import java.text.Normalizer; import java.util.Locale; + import org.mozilla.javascript.ScriptRuntime.StringIdOrIndex; import org.mozilla.javascript.regexp.NativeRegExp; @@ -462,11 +463,16 @@ public Object execIdCall( case Id_endsWith: String thisString = ScriptRuntime.toString(requireObjectCoercible(cx, thisObj, f)); - if (args.length > 0 && args[0] instanceof NativeRegExp) { - 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 + && reProxy.isRegExp((Scriptable) args[0])) { + throw ScriptRuntime.typeErrorById( + "msg.first.arg.not.regexp", + String.class.getSimpleName(), + f.getFunctionName()); + } } int idx = js_indexOf(id, thisString, args); diff --git a/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java b/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java new file mode 100644 index 0000000000..824f1b56ee --- /dev/null +++ b/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java @@ -0,0 +1,37 @@ +/* -*- 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.javascript.archunit; + +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + +import org.junit.runner.RunWith; + +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; + +/** + * 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 corejsPackageRule = noClasses() + .that() + .resideOutsideOfPackage("org.mozilla.javascript.regexp..") + .and().doNotHaveFullyQualifiedName("org.mozilla.javascript.RegExpProxy") + .should().dependOnClassesThat().resideInAnyPackage("org.mozilla.javascript.regexp.."); +} From 0cb587d82ac9b3dd1bcb59cd3dfb4e024e5bb19a Mon Sep 17 00:00:00 2001 From: Ronald Brill Date: Sun, 12 Nov 2023 11:29:04 +0100 Subject: [PATCH 2/2] spotless - what else --- src/org/mozilla/javascript/NativeArray.java | 1 - src/org/mozilla/javascript/NativeString.java | 2 -- .../javascript/archunit/ArchitectureTest.java | 25 +++++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/org/mozilla/javascript/NativeArray.java b/src/org/mozilla/javascript/NativeArray.java index 348fc9d9ae..5cdc23dd6d 100644 --- a/src/org/mozilla/javascript/NativeArray.java +++ b/src/org/mozilla/javascript/NativeArray.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; - import org.mozilla.javascript.xml.XMLObject; /** diff --git a/src/org/mozilla/javascript/NativeString.java b/src/org/mozilla/javascript/NativeString.java index c5f4d732ce..4c153e24af 100644 --- a/src/org/mozilla/javascript/NativeString.java +++ b/src/org/mozilla/javascript/NativeString.java @@ -12,9 +12,7 @@ import java.text.Collator; 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. diff --git a/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java b/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java index 824f1b56ee..a30dc6a0c7 100644 --- a/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java +++ b/testsrc/org/mozilla/javascript/archunit/ArchitectureTest.java @@ -8,13 +8,12 @@ import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; -import org.junit.runner.RunWith; - 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. @@ -22,16 +21,20 @@ * @author Ronald Brill */ @RunWith(ArchUnitRunner.class) -@AnalyzeClasses(packages = "org.mozilla.javascript", importOptions = ImportOption.DoNotIncludeTests.class) +@AnalyzeClasses( + packages = "org.mozilla.javascript", + importOptions = ImportOption.DoNotIncludeTests.class) public class ArchitectureTest { - /** - * Use only the RegExpProxy. - */ + /** Use only the RegExpProxy. */ @ArchTest - public static final ArchRule corejsPackageRule = noClasses() - .that() - .resideOutsideOfPackage("org.mozilla.javascript.regexp..") - .and().doNotHaveFullyQualifiedName("org.mozilla.javascript.RegExpProxy") - .should().dependOnClassesThat().resideInAnyPackage("org.mozilla.javascript.regexp.."); + public static final ArchRule corejsPackageRule = + noClasses() + .that() + .resideOutsideOfPackage("org.mozilla.javascript.regexp..") + .and() + .doNotHaveFullyQualifiedName("org.mozilla.javascript.RegExpProxy") + .should() + .dependOnClassesThat() + .resideInAnyPackage("org.mozilla.javascript.regexp.."); }