From a9ccd926c2db12d4ec6d54e4fc8b18945b3f5197 Mon Sep 17 00:00:00 2001 From: duonglaiquang Date: Thu, 4 Jan 2024 14:09:33 +0900 Subject: [PATCH] NativeRegExp: fix RegExp.prototype.toString throwing TypeError on NativeObject --- src/org/mozilla/javascript/regexp/NativeRegExp.java | 9 +++++++++ .../org/mozilla/javascript/tests/NativeRegExpTest.java | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/org/mozilla/javascript/regexp/NativeRegExp.java b/src/org/mozilla/javascript/regexp/NativeRegExp.java index 2b7cffdefe..50d7f55760 100644 --- a/src/org/mozilla/javascript/regexp/NativeRegExp.java +++ b/src/org/mozilla/javascript/regexp/NativeRegExp.java @@ -11,6 +11,7 @@ import org.mozilla.javascript.IdFunctionObject; import org.mozilla.javascript.IdScriptableObject; import org.mozilla.javascript.Kit; +import org.mozilla.javascript.NativeObject; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; @@ -2716,6 +2717,14 @@ public Object execIdCall( return realThis(thisObj, f).compile(cx, scope, args); case Id_toString: + if (thisObj instanceof NativeObject) { + Object sourceObj = thisObj.get("source", thisObj); + String source = sourceObj.equals(NOT_FOUND) ? "undefined" : escapeRegExp(sourceObj); + Object flagsObj = thisObj.get("flags", thisObj); + String flags = flagsObj.equals(NOT_FOUND) ? "undefined" : flagsObj.toString(); + + return "/" + source + "/" + flags; + } case Id_toSource: return realThis(thisObj, f).toString(); diff --git a/testsrc/org/mozilla/javascript/tests/NativeRegExpTest.java b/testsrc/org/mozilla/javascript/tests/NativeRegExpTest.java index 944629438d..47d8da1481 100644 --- a/testsrc/org/mozilla/javascript/tests/NativeRegExpTest.java +++ b/testsrc/org/mozilla/javascript/tests/NativeRegExpTest.java @@ -328,6 +328,16 @@ public void flagsPropery() throws Exception { test("0-undefined-true-false-undefined", script); } + /** @throws Exception if an error occurs */ + @Test + public void objectToString() throws Exception { + test("/undefined/undefined", "RegExp.prototype.toString.call({})"); + test("/Foo/undefined", "RegExp.prototype.toString.call({source: 'Foo'})"); + test("/undefined/gy", "RegExp.prototype.toString.call({flags: 'gy'})"); + test("/Foo/g", "RegExp.prototype.toString.call({source: 'Foo', flags: 'g'})"); + test("/Foo/g", "RegExp.prototype.toString.call({source: 'Foo', flags: 'g', sticky: true})"); + } + private static void test(final String expected, final String script) { Utils.runWithAllOptimizationLevels( cx -> {