Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix NPE when regexp search has no result #927

Closed
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/org/mozilla/javascript/regexp/NativeRegExp.java
Expand Up @@ -2690,7 +2690,7 @@ public Object execIdCall(
case SymbolId_search:
Scriptable scriptable =
(Scriptable) realThis(thisObj, f).execSub(cx, scope, args, MATCH);
return scriptable.get("index", scriptable);
return scriptable == null ? -1 : scriptable.get("index", scriptable);
}
throw new IllegalArgumentException(String.valueOf(id));
}
Expand Down
92 changes: 50 additions & 42 deletions testsrc/org/mozilla/javascript/tests/es6/NativeRegExpTest.java
Expand Up @@ -15,9 +15,7 @@
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.tests.Utils;

/**
* @author Ronald Brill
*/
/** @author Ronald Brill */
public class NativeRegExpTest {

@Test
Expand All @@ -44,43 +42,34 @@ public void regExIsCallableForBackwardCompatibility() {
Context.exit();
}


@Test
public void regExMinusInRangeBorderCases() {
Context cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_1_8);
ScriptableObject scope = cx.initStandardObjects();

String source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-]+/g, 'x');";
String source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-]+/g, 'x');";
assertEquals("axbxc d efg 1 23", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\s]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\s]+/g, 'x');";
assertEquals("axbxcxdxefgx1x23", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\S]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\S]+/g, 'x');";
assertEquals("x x x x x", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\w]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\w]+/g, 'x');";
assertEquals("x x x x x", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\W]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\W]+/g, 'x');";
assertEquals("axbxcxdxefgx1x23", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\d]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\d]+/g, 'x');";
assertEquals("axbxc d efg x x", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\D]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\D]+/g, 'x');";
assertEquals("x1x23", cx.evaluateString(scope, source, "test", 0, null));

source = "var r = 'a-b_c d efg 1 23';\n"
+ "r.replace(/[_-\\a]+/g, 'x');";
source = "var r = 'a-b_c d efg 1 23';\n" + "r.replace(/[_-\\a]+/g, 'x');";
assertEquals("x-bxc d efg 1 23", cx.evaluateString(scope, source, "test", 0, null));

Context.exit();
Expand All @@ -96,8 +85,7 @@ public void regExIsNotCallable() {
try {
cx.evaluateString(scope, source, "test", 0, null);
fail();
}
catch (EcmaError e) {
} catch (EcmaError e) {
// expected
assertTrue(e.getMessage(), e.getMessage().startsWith("TypeError: "));
}
Expand All @@ -106,8 +94,7 @@ public void regExIsNotCallable() {
try {
cx.evaluateString(scope, source, "test", 0, null);
fail();
}
catch (EcmaError e) {
} catch (EcmaError e) {
// expected
assertTrue(e.getMessage(), e.getMessage().startsWith("TypeError: "));
}
Expand All @@ -116,8 +103,7 @@ public void regExIsNotCallable() {
try {
cx.evaluateString(scope, source, "test", 0, null);
fail();
}
catch (EcmaError e) {
} catch (EcmaError e) {
// expected
assertTrue(e.getMessage(), e.getMessage().startsWith("TypeError: "));
}
Expand All @@ -126,19 +112,16 @@ public void regExIsNotCallable() {
try {
cx.evaluateString(scope, source, "test", 0, null);
fail();
}
catch (EcmaError e) {
} catch (EcmaError e) {
// expected
assertTrue(e.getMessage(), e.getMessage().startsWith("TypeError: "));
}


source = "new new RegExp";
try {
cx.evaluateString(scope, source, "test", 0, null);
fail();
}
catch (EcmaError e) {
} catch (EcmaError e) {
// expected
assertTrue(e.getMessage(), e.getMessage().startsWith("TypeError: "));
}
Expand All @@ -148,16 +131,41 @@ public void regExIsNotCallable() {

@Test
public void lastIndexReadonly() {
final String script = "try { "
+ " var r = /c/g;"
+ " Object.defineProperty(r, 'lastIndex', { writable: false });"
+ " r.exec('abc');"
+ "} catch (e) { e.message }";
Utils.runWithAllOptimizationLevels(_cx -> {
final ScriptableObject scope = _cx.initStandardObjects();
final Object result = _cx.evaluateString(scope, script, "test script", 0, null);
assertEquals("Cannot modify readonly property: lastIndex.", Context.toString(result));
return null;
});
final String script =
"try { "
+ " var r = /c/g;"
+ " Object.defineProperty(r, 'lastIndex', { writable: false });"
+ " r.exec('abc');"
+ "} catch (e) { e.message }";
Utils.runWithAllOptimizationLevels(
_cx -> {
final ScriptableObject scope = _cx.initStandardObjects();
final Object result = _cx.evaluateString(scope, script, "test script", 0, null);
assertEquals(
"Cannot modify readonly property: lastIndex.",
Context.toString(result));
return null;
});
}

@Test
public void search() {
Context cx = Context.enter();
gausie marked this conversation as resolved.
Show resolved Hide resolved
cx.setLanguageVersion(Context.VERSION_ES6);
ScriptableObject scope = cx.initStandardObjects();

String source = "'abc'.search(/b/);";
assertEquals(1, cx.evaluateString(scope, source, "test", 0, null));

source = "/b/[Symbol.search]('abc');";
assertEquals(1, cx.evaluateString(scope, source, "test", 0, null));

source = "'abc'.search(/d/);";
assertEquals(-1, cx.evaluateString(scope, source, "test", 0, null));

source = "/d/[Symbol.search]('abc');";
assertEquals(-1, cx.evaluateString(scope, source, "test", 0, null));

Context.exit();
}
}