Skip to content

Regex acceptor 2018 #202

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<dependency>
<groupId>com.shapesecurity</groupId>
<artifactId>shape-functional-java</artifactId>
<version>2.3.3</version>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,9 @@ protected Either3<Expression, FormalParameters, AssignmentTarget> parsePrimaryEx
throw this.createErrorWithLocation(this.getLocation(), "Invalid regular expression flags");
}
}
if (!PatternAcceptor.acceptRegex(pattern, gFlag, iFlag, mFlag, yFlag, uFlag)) {
throw this.createErrorWithLocation(this.getLocation(), "Invalid regular expression");
}
return Either3.left(this.finishNode(startState, new LiteralRegExpExpression(pattern, gFlag, iFlag, mFlag, yFlag, uFlag)));
default:
throw this.createUnexpected(this.lookahead);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public void testLiterals() throws IllegalAccessException, NoSuchMethodException,
testHelperFromScriptCode("0");
testHelperFromScriptCode("1.5");
testHelperFromScriptCode("/[a-z]/i");
testHelperFromScriptCode("/(?!.){0,}?/u");
testHelperFromScriptCode("/(?!.){0,}?/");
testHelperFromScriptCode("('x')");
testHelperFromScriptCode("('\\\n')");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ public class PassTest {
static final String expectationsDir = "src/test/resources/shift-parser-expectations/expectations/";

static final Set<String> xfail = new HashSet<>(Arrays.asList(
"" // empty line to make git diffs nicer
// Invalid tests
// https://github.com/tc39/test262-parser-tests/issues/20
"e4a43066905a597b.js",
"78c215fabdf13bae.js",
"bf49ec8d96884562.js",
"66e383bfd18e66ab.js"
));

static void assertTreesEqual(Program expected, Program actual) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ public static void testScriptFailureML(@Nonnull String source, int line, int col
fail("Parsing error not found");
}

public static void testScriptFailure(@Nonnull String source, @Nonnull String error) {
try {
Parser.parseScript(source);
} catch (JsError jsError) {
assertEquals(error, jsError.getDescription());
return;
}
fail("Parsing error not found");
}

public static void testScriptFailure(@Nonnull String source, int index, @Nonnull String error) {
testScriptFailureML(source, 1, index, index, error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,200 @@
import com.shapesecurity.shift.es2016.parser.ParserTestCase;
import com.shapesecurity.shift.es2016.parser.JsError;

import com.shapesecurity.shift.es2016.parser.PatternAcceptor;
import org.junit.Test;

import javax.annotation.Nonnull;

public class LiteralRegExpExpressionTest extends ParserTestCase {

private static final String[] expectedToPass = new String[] {
"/./",
"/.|./",
"/.||./",
"/|/",
"/|.||.|/",
"/^$\\b\\B/",
"/^X/",
"/X$/",
"/\\bX/",
"/\\BX/",
"/(?=t|v|X|.|$||)/",
"/(?!t|v|X|.|$||)/",
"/(?<=t|v|X|.|$||)/",
"/(?<!t|v|X|.|$||)/",
"/(?=t|v|X|.|$||)/u",
"/(?!t|v|X|.|$||)/u",
"/(?<=t|v|X|.|$||)/u",
"/(?<!t|v|X|.|$||)/u",
"/(?=t|v|X|.|$||)*/",
"/(?!t|v|X|.|$||)*/",
"/X*/",
"/X+/",
"/X?/",
"/X*?/",
"/X+?/",
"/X??/",
"/X{5}/",
"/X{5,}/",
"/X{5,10}/",
"/X{5}?/",
"/X{5,}?/",
"/X{5,10}?/",
"/./",
"/\\123/",
"/\\0/",
"/\\0/u",
"/\\1()/",
"/\\1()/u",
"/\\2()/",
"/\\2()()/u",
"/\\d/",
"/\\D/",
"/\\s/",
"/\\S/",
"/\\w/",
"/\\W/",
"/\\d/u",
"/\\D/u",
"/\\s/u",
"/\\S/u",
"/\\w/u",
"/\\W/u",
"/[]/",
"/[^]/",
"/[X]/",
"/[^X]/",
"/[-X]/",
"/[^-X]/",
"/[X-]/",
"/[^X-]/",
"/[0-9-a-]/",
"/[^0-9-a-]/",
"/[0-9-a-z]/",
"/[^0-9-a-z]/",
"/[0-9-a-z-]/",
"/[^0-9-a-z-]/",
"/[]/u",
"/[^]/u",
"/[X]/u",
"/[^X]/u",
"/[-X]/u",
"/[^-X]/u",
"/[X-]/u",
"/[^X-]/u",
"/[0-9-a-]/u",
"/[^0-9-a-]/u",
"/[0-9-a-z]/u",
"/[^0-9-a-z]/u",
"/[0-9-a-z-]/u",
"/[^0-9-a-z-]/u",
"/[{}[||)(()\\]?+*.$^]/",
"/[{}[||)(()\\]?+*.$^]/u",
"/[\\b]/",
"/[\\b]/u",
"/\\d]/",
"/[\\D]/",
"/[\\s]/",
"/[\\S]/",
"/[\\w]/",
"/[\\W]/",
"/\\f/",
"/\\n/",
"/\\r/",
"/\\t/",
"/\\v/",
"/\\ca/",
"/\\cZ/",
"/\\xAA/",
"/\\xZZ/",
"/\\x0F/",
"/\\u10AB/",
"/\\u10AB/u",
"/\\uD800/u",
"/\\uDF00/u",
"/\\uD800\\uDF00/u",
"/\\u{001AD}/u",
"/\\u{10FFFF}/u",
"/\\u{0}/u",
"/\\L/",
"/\\$/",
"/\\$/u",
"/[\\s-X]/",
"/{dfwfdf}/",
"/{5.}/",
"/{5,X}/",
"/{5,10X}/",
"/\\c/",
"/[\\c]/",
"/[\\c]/u",
"/[\\5]/",
"/(?:)/",
"/(?:X)/",
"/}*/",
"/]*/",
"/[\\123]/",
"/[\\_]/",
"/[\\1]/",
"/[\\9]/",
"/[\\-]/u",
"/[\\-]/",
"/(?<test>)\\k<test>/",
"/\\ud800\\u1000/u",
"/\\u{10}/u",
"/[\\1]/",
"/[\\7]/",
"/[\\15]/",
"/[\\153]/",
"/[\\72]/"
};

private static final String[] expectedToFail = new String[] {
"/(?=t|v|X|.|$||)*/u",
"/(?!t|v|X|.|$||)*/u",
"/(?<=t|v|X|.|$||)*/",
"/(?<!t|v|X|.|$||)*/",
"/(?<=t|v|X|.|$||)*/u",
"/(?<!t|v|X|.|$||)*/u",
"/X{10,5}/",
"/X{10,5}?/",
"/\\123/u",
"/\\1/u",
"/\\2/u",
"/\\u{110FFFF}/u",
"/\\L/u",
"/[b-a]/",
"/[\\s-X]/u",
"/{dfwfdf}/u",
"/{5,10}/",
"/{5,10}/u",
"/{5.}/u",
"/{5,X}/u",
"/{5,10X}/u",
"/(?:)\\1/u",
"/}*/u",
"/]*/u",
"/[\\123]/u",
"/[\\_]/u",
"/[\\1]/u",
"/[\\9]/u",
"/\\c/u",
"/(?<\">)/",
"/(?<test>)(?<test>)/",
"/\\k<\">/",
"/\\k<f>/",
"/\\xZZ/u",
"/\\ud800\\uZZ/u",
"/\\uZZ/u",
"/\\u{ZZ}/u",
"/5{5,1G}/u"
};

@Test
public void testLiteralRegExpExpressionTest() throws JsError {
testScript("/a/", new LiteralRegExpExpression("a", false, false, false, false, false));
testScript("/\\0/", new LiteralRegExpExpression("\\0", false, false, false, false, false));
testScript("/\\1/u", new LiteralRegExpExpression("\\1", false, false, false, false, true));
testScript("/\\1()/u", new LiteralRegExpExpression("\\1()", false, false, false, false, true));
testScript("/a/;", new LiteralRegExpExpression("a", false, false, false, false, false));
testScript("/a/i", new LiteralRegExpExpression("a", false, true, false, false, false));
testScript("/a/i;", new LiteralRegExpExpression("a", false, true, false, false, false));
Expand All @@ -39,14 +225,25 @@ public void testLiteralRegExpExpressionTest() throws JsError {

testScript("/{/;", new LiteralRegExpExpression("{", false, false, false, false, false));
testScript("/}/;", new LiteralRegExpExpression("}", false, false, false, false, false));
testScript("/}?/u;", new LiteralRegExpExpression("}?", false, false, false, false, true));
testScript("/{*/u;", new LiteralRegExpExpression("{*", false, false, false, false, true));
testScriptFailure("/}?/u;", 5, "Invalid regular expression");
testScriptFailure("/{*/u;", 5, "Invalid regular expression");
testScript("/{}/;", new LiteralRegExpExpression("{}", false, false, false, false, false));
testScript("/.{.}/;", new LiteralRegExpExpression(".{.}", false, false, false, false, false));
testScript("/[\\w-\\s]/;", new LiteralRegExpExpression("[\\w-\\s]", false, false, false, false, false));
testScript("/[\\s-\\w]/;", new LiteralRegExpExpression("[\\s-\\w]", false, false, false, false, false));
testScript("/(?=.)*/;", new LiteralRegExpExpression("(?=.)*", false, false, false, false, false));
testScript("/(?!.){0,}?/;", new LiteralRegExpExpression("(?!.){0,}?", false, false, false, false, false));
testScript("/(?!.){0,}?/u", new LiteralRegExpExpression("(?!.){0,}?", false, false, false, false, true));
testScriptFailure("/(?!.){0,}?/u", 13, "Invalid regular expression");

assertTrue(PatternAcceptor.acceptRegex("]", false, false, false, false, false));


for (String regex : expectedToPass) {
testScript(regex);
}

for (String regex : expectedToFail) {
testScriptFailure(regex, "Invalid regular expression");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ public void testNumericExpression() throws JsError{
public void testLiteralRegExpExpression() throws JsError{
cloneTestScript("/a/");
cloneTestScript("/\\0/");
cloneTestScript("/\\1/u");
cloneTestScript("/\\0/u");
cloneTestScript("/\\1/");
cloneTestScript("/\\1()/u");
cloneTestScript("/a/;");
cloneTestScript("/a/i");
cloneTestScript("/a/i;");
Expand All @@ -139,15 +141,12 @@ public void testLiteralRegExpExpression() throws JsError{
cloneTestScript("/0/g.test");
cloneTestScript("/{/;");
cloneTestScript("/}/;");
cloneTestScript("/}?/u;");
cloneTestScript("/{*/u;");
cloneTestScript("/{}/;");
cloneTestScript("/.{.}/;");
cloneTestScript("/[\\w-\\s]/;");
cloneTestScript("/[\\s-\\w]/;");
cloneTestScript("/(?=.)*/;");
cloneTestScript("/(?!.){0,}?/;");
cloneTestScript("/(?!.){0,}?/u");
}

@Test
Expand Down