henrib commented on code in PR #414:
URL: https://github.com/apache/commons-jexl/pull/414#discussion_r3893897500


##########
src/main/java/org/apache/commons/jexl3/internal/Interpreter.java:
##########
@@ -1377,12 +1378,37 @@ protected Object visit(final ASTEQSNode node, final 
Object data) {
     @Override
     protected Object visit(final ASTERNode node, final Object data) {
         final Object left = node.jjtGetChild(0).jjtAccept(this, data);
-        final Object right = node.jjtGetChild(1).jjtAccept(this, data);
+        final JexlNode rightNode = node.jjtGetChild(1);
+        final Object right = resolvePattern(rightNode, 
rightNode.jjtAccept(this, data));
         // note the arguments inversion between 'in'/'matches' and 'contains'
         // if x in y then y contains x
         return operators.contains(node, JexlOperator.CONTAINS, right, left);
     }
 
+    /**
+     * If the right operand of {@code =~} / {@code !~} is a string literal, 
compile it to a Pattern once and
+     * cache the result in the node's value slot (same mechanism as negated 
numeric literals).
+     * Dynamic string values (from variables) are returned unchanged.
+     * The regex string length is validated before compilation (matches 
JexlArithmetic.REGEX_PATTERN_MAX_LENGTH).
+     */
+    private static Object resolvePattern(final JexlNode rightNode, final 
Object right) {
+        if (right instanceof CharSequence && rightNode instanceof 
JexlNode.Constant) {
+            final Object cached = rightNode.jjtGetValue();
+            if (cached instanceof Pattern) {
+                return cached;
+            }
+            final String regex = right.toString();
+            final int maxLen = 2048;
+            if (regex.length() > maxLen) {
+                throw new ArithmeticException("regular expression too long: " 
+ regex.length() + " > " + maxLen);
+            }
+            final Pattern compiled = Pattern.compile(regex);
+            rightNode.jjtSetValue(compiled);
+            return compiled;
+        }
+        return right;
+    }

Review Comment:
   The value being set through jjtSetValue is volatile and intended to be 
shared; adding double checked locking for stronger guarantees - but no 
difference in effect.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to