Skip to content

Commit 0c6bdd1

Browse files
committed
TRegex: treat nested quantifiers as a bailout instead of a syntax error in OracleDBFlavor.
1 parent 25437b3 commit 0c6bdd1

File tree

4 files changed

+50
-58
lines changed

4 files changed

+50
-58
lines changed

regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/OracleDBTests.java

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -132,30 +132,10 @@ public void generatedTests() {
132132
expectSyntaxError("x{4294967296}", "", "x{4294967296}", 0, ErrorCode.InvalidQuantifier);
133133
expectSyntaxError("x{4294967297}", "", "x{4294967297}", 0, ErrorCode.InvalidQuantifier);
134134
test("x??", "", "x", 0, true, 0, 0);
135-
expectSyntaxError("x{2}+", "", "x", 0, ErrorCode.InvalidQuantifier);
136-
expectSyntaxError("x{2}+", "", "xx", 0, ErrorCode.InvalidQuantifier);
137-
expectSyntaxError("x{2}+", "", "xxx", 0, ErrorCode.InvalidQuantifier);
138-
expectSyntaxError("x{2}+", "", "xxxx", 0, ErrorCode.InvalidQuantifier);
139-
expectSyntaxError("x{2}*", "", "xxxx", 0, ErrorCode.InvalidQuantifier);
140-
expectSyntaxError("x{2}*?", "", "xxxx", 0, ErrorCode.InvalidQuantifier);
141-
expectSyntaxError("x{2}*???", "", "xxxx", 0, ErrorCode.InvalidQuantifier);
142135
test("\\A*x\\Z+", "", "x", 0, true, 0, 1);
143136
test("\\A*x\\Z+", "", "xx", 0, true, 1, 2);
144137
test("\\A+x\\Z+", "", "xx", 0, false);
145-
expectSyntaxError("x????", "", "x?", 0, ErrorCode.InvalidQuantifier);
146-
expectSyntaxError("x????", "", "xx?", 0, ErrorCode.InvalidQuantifier);
147-
expectSyntaxError("x??????", "", "x?", 0, ErrorCode.InvalidQuantifier);
148-
expectSyntaxError("x??????", "", "xx?", 0, ErrorCode.InvalidQuantifier);
149138
test("x{2}?", "", "xxxxx", 0, true, 0, 2);
150-
expectSyntaxError("x{2}??", "", "xxxxx", 0, ErrorCode.InvalidQuantifier);
151-
expectSyntaxError("x{2}+", "", "xxxxx", 0, ErrorCode.InvalidQuantifier);
152-
expectSyntaxError("x{2}*", "", "xxxxx", 0, ErrorCode.InvalidQuantifier);
153-
expectSyntaxError("x???", "", "x", 0, ErrorCode.InvalidQuantifier);
154-
expectSyntaxError("x{2}*??", "", "xxxx", 0, ErrorCode.InvalidQuantifier);
155-
expectSyntaxError("x???", "", "x?", 0, ErrorCode.InvalidQuantifier);
156-
expectSyntaxError("x???", "", "xx?", 0, ErrorCode.InvalidQuantifier);
157-
expectSyntaxError("x?????", "", "x?", 0, ErrorCode.InvalidQuantifier);
158-
expectSyntaxError("x?????", "", "xx?", 0, ErrorCode.InvalidQuantifier);
159139
test("(a{0,1})*b\\1", "", "aab", 0, true, 0, 3, 2, 2);
160140
test("(a{0,1})*b\\1", "", "aaba", 0, true, 0, 3, 2, 2);
161141
test("(a{0,1})*b\\1", "", "aabaa", 0, true, 0, 3, 2, 2);
@@ -994,7 +974,6 @@ public void generatedTests() {
994974
test("a(()|()|b|()|())*c", "", "abbc", 0, true, 0, 4, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1);
995975
test("a(()|()|()|b|())*c", "", "abbc", 0, true, 0, 4, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1);
996976
test("a(()|()|()|()|b)*c", "", "abbc", 0, true, 0, 4, 3, 3, 3, 3, -1, -1, -1, -1, -1, -1);
997-
expectSyntaxError("a??+", "", "aaa", 0, ErrorCode.InvalidQuantifier);
998977
test("()??()??()??()??()??()??()??()??\\3\\5\\7", "", "a", 0, true, 0, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1);
999978
test("()*", "", "a", 0, true, 0, 0, 0, 0);
1000979
test("(a|)*", "", "a", 0, true, 0, 1, 1, 1);
@@ -1017,24 +996,11 @@ public void generatedTests() {
1017996
expectSyntaxError("[y-\\{][y-\\{]", "", "I", 0, ErrorCode.InvalidCharacterClass);
1018997
test("a?", "", "aaa", 0, true, 0, 1);
1019998
test("a??", "", "aaa", 0, true, 0, 0);
1020-
expectSyntaxError("a???", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1021999
test("a+?", "", "aaa", 0, true, 0, 1);
1022-
expectSyntaxError("a+??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1023-
expectSyntaxError("a??+", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1024-
expectSyntaxError("a?+", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1025-
expectSyntaxError("a?+?", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1026-
expectSyntaxError("a?+??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1027-
expectSyntaxError("a?*??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1028-
expectSyntaxError("(a?)*??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
10291000
test("((a?)*)??", "", "aaa", 0, true, 0, 0, -1, -1, -1, -1);
10301001
test("((a?)*?)?", "", "aaa", 0, true, 0, 0, 0, 0, -1, -1);
1031-
expectSyntaxError("a?*?", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1032-
expectSyntaxError("a*??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1033-
expectSyntaxError("a+*?", "", "aaa", 0, ErrorCode.InvalidQuantifier);
10341002
test("(a+)*?", "", "aaa", 0, true, 0, 0, -1, -1);
10351003
test("((a+)*)?", "", "aaa", 0, true, 0, 3, 0, 3, 0, 3);
1036-
expectSyntaxError("a+*??", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1037-
expectSyntaxError("a++?", "", "aaa", 0, ErrorCode.InvalidQuantifier);
10381004
expectSyntaxError("[[.\\a.]]", "", ".", 0, ErrorCode.InvalidCharacterClass);
10391005
test("[[...]]", "", ".", 0, true, 0, 1);
10401006
test("[[...]]", "", "[", 0, false);
@@ -1049,12 +1015,6 @@ public void generatedTests() {
10491015
test("[[...]a]a", "", "a", 0, false);
10501016
test("[[...]a]?a", "", "a", 0, true, 0, 1);
10511017
test("[[...]a]|a", "", "a", 0, true, 0, 1);
1052-
expectSyntaxError("a++?", "", "aaa", 0, ErrorCode.InvalidQuantifier);
1053-
expectSyntaxError("\\D|++?", "", "9", 0, ErrorCode.InvalidQuantifier);
1054-
expectSyntaxError("\\D|++?^", "", "9", 0, ErrorCode.InvalidQuantifier);
1055-
expectSyntaxError("\\S|\\D|++?^(3)", "", "9", 0, ErrorCode.InvalidQuantifier);
1056-
expectSyntaxError("\\S|\\D|++?^((3)|[R-_\\(/])t[[:alnum:]]c", "", "9", 0, ErrorCode.InvalidQuantifier);
1057-
expectSyntaxError("(\\d)|5+*?|[[:lower:]][[=l=]]^%", "", "\u0169\u2113%", 0, ErrorCode.InvalidQuantifier);
10581018
test("[[===]]", "", "=", 0, true, 0, 1);
10591019
expectSyntaxError("[[=\\==]]", "", "=", 0, ErrorCode.InvalidCharacterClass);
10601020
expectSyntaxError("[[=\\==]]", "", "\\", 0, ErrorCode.InvalidCharacterClass);
@@ -1099,23 +1059,12 @@ public void generatedTests() {
10991059
test("\\[[b-b]", "", "[b-b]", 0, true, 0, 2);
11001060
test("\\[c-b]", "", "[c-b]", 0, true, 0, 5);
11011061
expectSyntaxError("\\[[c-b]", "", "[c-b]", 0, ErrorCode.InvalidCharacterClass);
1102-
expectSyntaxError("()?*", "", "c", 0, ErrorCode.InvalidQuantifier);
1103-
expectSyntaxError("()?*|", "", "c", 0, ErrorCode.InvalidQuantifier);
1104-
expectSyntaxError("()?*||", "", "c", 0, ErrorCode.InvalidQuantifier);
1105-
expectSyntaxError("()?*||a", "", "b", 0, ErrorCode.InvalidQuantifier);
1106-
expectSyntaxError("()?*||^a\\Zb", "", "c", 0, ErrorCode.InvalidQuantifier);
11071062
test("ac??bc?", "", "abc", 0, true, 0, 3);
11081063
test("ac??bc?", "", "acbc", 0, true, 0, 4);
11091064
test("a?", "", "a", 0, true, 0, 1);
11101065
test("a??", "", "a", 0, true, 0, 0);
1111-
expectSyntaxError("a???", "", "a", 0, ErrorCode.InvalidQuantifier);
1112-
expectSyntaxError("(a)???", "", "a", 0, ErrorCode.InvalidQuantifier);
11131066
test("(a?)??", "", "a", 0, true, 0, 0, -1, -1);
11141067
test("(a??)?", "", "a", 0, true, 0, 0, 0, 0);
1115-
expectSyntaxError("(a???)", "", "a", 0, ErrorCode.InvalidQuantifier);
1116-
expectSyntaxError("a{0,1}??", "", "a", 0, ErrorCode.InvalidQuantifier);
1117-
expectSyntaxError("a??{0,1}", "", "a", 0, ErrorCode.InvalidQuantifier);
1118-
expectSyntaxError("a{0,1}?{0,1}", "", "a", 0, ErrorCode.InvalidQuantifier);
11191068
test("(a{0,1})*", "", "aaaaaa", 0, true, 0, 6, 6, 6);
11201069
test("(a{0,2})*", "", "aaaaaa", 0, true, 0, 6, 6, 6);
11211070
test("(a{1,2})*", "", "aaaaaa", 0, true, 0, 6, 4, 6);
@@ -1706,4 +1655,46 @@ public void bqTransitionExplosion() {
17061655
test("(a(b(b(b(b(b(b(b(b(b(b(b(b(b(b(b(b(b(b(b|)|)|)|)|)|)|)|)|)|)|)|)|)|)|)|)|)|)|){2,2}c)de", "", Map.of("regexDummyLang.QuantifierUnrollLimitGroup", "1"),
17071656
"abbbbbbbcdebbbbbbbf", 0, true, 0, 11, 0, 9, 8, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8);
17081657
}
1658+
1659+
@Test
1660+
public void testNestedQuantifierBailout() {
1661+
expectUnsupported("()?*");
1662+
expectUnsupported("()?*|");
1663+
expectUnsupported("()?*||");
1664+
expectUnsupported("()?*||a");
1665+
expectUnsupported("(a)???");
1666+
expectUnsupported("(a?)*??");
1667+
expectUnsupported("(a???)");
1668+
expectUnsupported("a*??");
1669+
expectUnsupported("a+*?");
1670+
expectUnsupported("a+*??");
1671+
expectUnsupported("a++?");
1672+
expectUnsupported("a+??");
1673+
expectUnsupported("a?*?");
1674+
expectUnsupported("a?*??");
1675+
expectUnsupported("a?+");
1676+
expectUnsupported("a?+?");
1677+
expectUnsupported("a?+??");
1678+
expectUnsupported("a??+");
1679+
expectUnsupported("a???");
1680+
expectUnsupported("a??{0,1}");
1681+
expectUnsupported("a{0,1}??");
1682+
expectUnsupported("a{0,1}?{0,1}");
1683+
expectUnsupported("()?*||^a\\Zb");
1684+
expectUnsupported("\\D|++?");
1685+
expectUnsupported("\\D|++?^");
1686+
expectUnsupported("(\\d)|5+*?|[[:lower:]][[=l=]]^%");
1687+
expectUnsupported("\\S|\\D|++?^(3)");
1688+
expectUnsupported("\\S|\\D|++?^((3)|[R-_\\(/])t[[:alnum:]]c");
1689+
expectUnsupported("x???");
1690+
expectUnsupported("x????");
1691+
expectUnsupported("x?????");
1692+
expectUnsupported("x??????");
1693+
expectUnsupported("x{2}*");
1694+
expectUnsupported("x{2}*?");
1695+
expectUnsupported("x{2}*??");
1696+
expectUnsupported("x{2}*???");
1697+
expectUnsupported("x{2}+");
1698+
expectUnsupported("x{2}??");
1699+
}
17091700
}

regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/RegexTestBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ private static void validateResult(String pattern, String flags, Map<String, Str
260260
// print(pattern, input, fromIndex, result, groupCount, captureGroupBoundsAndLastGroup);
261261
}
262262

263-
void expectUnsupported(String pattern, String flags) {
264-
expectUnsupported(pattern, flags, Collections.emptyMap());
263+
void expectUnsupported(String pattern) {
264+
expectUnsupported(pattern, "", Collections.emptyMap());
265265
}
266266

267267
void expectUnsupported(String pattern, String flags, Map<String, String> options) {

regex/src/com.oracle.truffle.regex.test/src/com/oracle/truffle/regex/tregex/test/RubyTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,9 @@ public void nonRecursiveSubexpressionCalls() {
422422

423423
@Test
424424
public void recursiveSubexpressionCalls() {
425-
expectUnsupported("(a\\g<1>?)(b\\g<2>?)", "");
426-
expectUnsupported("(?<a>a\\g<b>?)(?<b>b\\g<a>?)", "");
427-
expectUnsupported("a\\g<0>?", "");
425+
expectUnsupported("(a\\g<1>?)(b\\g<2>?)");
426+
expectUnsupported("(?<a>a\\g<b>?)(?<b>b\\g<a>?)");
427+
expectUnsupported("a\\g<0>?");
428428
}
429429

430430
@Test
@@ -540,7 +540,7 @@ public void gr39214() {
540540

541541
@Test
542542
public void gr41489() {
543-
expectUnsupported("\\((?>[^)(]+|\\g<0>)*\\)", "");
543+
expectUnsupported("\\((?>[^)(]+|\\g<0>)*\\)");
544544
}
545545

546546
@Test

regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/oracledb/OracleDBRegexParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.oracle.truffle.regex.RegexSource;
4949
import com.oracle.truffle.regex.RegexSyntaxException;
5050
import com.oracle.truffle.regex.RegexSyntaxException.ErrorCode;
51+
import com.oracle.truffle.regex.UnsupportedRegexException;
5152
import com.oracle.truffle.regex.charset.ClassSetContents;
5253
import com.oracle.truffle.regex.charset.CodePointSet;
5354
import com.oracle.truffle.regex.charset.CodePointSetAccumulator;
@@ -169,7 +170,7 @@ public RegexAST parse() throws RegexSyntaxException {
169170
break;
170171
case quantifier:
171172
if (prevKind == Token.Kind.quantifier) {
172-
throw syntaxError(OracleDBErrorMessages.NESTED_QUANTIFIER, ErrorCode.InvalidQuantifier);
173+
throw new UnsupportedRegexException(OracleDBErrorMessages.NESTED_QUANTIFIER);
173174
}
174175
if (astBuilder.getCurTerm() == null || prevKind == Token.Kind.captureGroupBegin) {
175176
// quantifiers without target are ignored

0 commit comments

Comments
 (0)