Skip to content

Commit bf48bab

Browse files
committed
sanitizing expression with regex pattern
1 parent c9203a0 commit bf48bab

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

framework/src/main/java/org/checkerframework/framework/util/JavacParseUtil.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.io.IOException;
1010
import java.net.URI;
1111
import java.util.Collections;
12+
import java.util.regex.Pattern;
1213
import javax.tools.JavaCompiler;
1314
import javax.tools.JavaFileObject;
1415
import javax.tools.SimpleJavaFileObject;
@@ -26,6 +27,16 @@ public class JavacParseUtil {
2627
/** Creates a JavacParseUtil. */
2728
public JavacParseUtil() {}
2829

30+
// Pattern to reject clearly invalid expressions before parsing
31+
private static final Pattern EXPRESSION_GATE =
32+
Pattern.compile(
33+
"^(?!.*;)\\s*"
34+
+ "(?!\\[?\\s*error\\s+for\\s+expression:)"
35+
+ "(?:(?!(?:final\\s+)?(?:byte|short|int|long|float|double|boolean|char|var)\\b.*=).)*"
36+
+ "(?:(?!(?:if|switch|for|while|do|try|catch|finally|return|throw|break|continue|class|interface|enum)\\b).)*"
37+
+ ".+\\S.*$",
38+
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
39+
2940
/**
3041
* Parses the given Java expression string and returns it as a {@link ExpressionTree} using the
3142
* {@code javac} compiler API.
@@ -36,16 +47,13 @@ public JavacParseUtil() {}
3647
* @throws RuntimeException if parsing fails or the expression cannot be found in the AST
3748
*/
3849
public static ExpressionTree parseExpression(String expressionSource) {
39-
// This method works by embedding the expression in a dummy class and variable declaration, then
40-
// parsing the resulting source to extract the expression tree.
41-
//
42-
// For example, the input {@code "1 + 2"} is transformed into:
43-
// class Dummy { Object expression = 1 + 2; }
44-
//
45-
// The initializer of the {@code expression} field is then extracted and returned.
50+
String sanitized = expressionSource.replaceAll("#num(\\d+)", "\\$num$1").trim();
51+
52+
// Quick pre-check to skip obvious non-expressions
53+
if (!EXPRESSION_GATE.matcher(sanitized).matches()) {
54+
throw new RuntimeException("Not a valid Java expression: " + expressionSource);
55+
}
4656

47-
// Embed the expression inside a dummy class and variable declaration.
48-
String sanitized = expressionSource.replaceAll("#num(\\d+)", "\\$num$1");
4957
String dummySource = "class Dummy { Object expression = " + sanitized + "; }";
5058

5159
// Obtain the system Java compiler.

0 commit comments

Comments
 (0)