@@ -43,6 +43,12 @@ public class OperatorMatches extends Operator {
4343
4444 private static final int PATTERN_ACCESS_THRESHOLD = 1000000 ;
4545
46+ /**
47+ * Maximum number of characters permitted in a regular expression.
48+ * @since 5.2.23
49+ */
50+ private static final int MAX_REGEX_LENGTH = 256 ;
51+
4652 private final ConcurrentMap <String , Pattern > patternCache ;
4753
4854
@@ -78,26 +84,28 @@ public OperatorMatches(ConcurrentMap<String, Pattern> patternCache, int startPos
7884 public BooleanTypedValue getValueInternal (ExpressionState state ) throws EvaluationException {
7985 SpelNodeImpl leftOp = getLeftOperand ();
8086 SpelNodeImpl rightOp = getRightOperand ();
81- String left = leftOp .getValue (state , String .class );
82- Object right = rightOp .getValue (state );
8387
84- if (left == null ) {
88+ String input = leftOp .getValue (state , String .class );
89+ if (input == null ) {
8590 throw new SpelEvaluationException (leftOp .getStartPosition (),
8691 SpelMessage .INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR , (Object ) null );
8792 }
93+
94+ Object right = rightOp .getValue (state );
8895 if (!(right instanceof String )) {
8996 throw new SpelEvaluationException (rightOp .getStartPosition (),
9097 SpelMessage .INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR , right );
9198 }
99+ String regex = (String ) right ;
92100
93101 try {
94- String rightString = (String ) right ;
95- Pattern pattern = this .patternCache .get (rightString );
102+ Pattern pattern = this .patternCache .get (regex );
96103 if (pattern == null ) {
97- pattern = Pattern .compile (rightString );
98- this .patternCache .putIfAbsent (rightString , pattern );
104+ checkRegexLength (regex );
105+ pattern = Pattern .compile (regex );
106+ this .patternCache .putIfAbsent (regex , pattern );
99107 }
100- Matcher matcher = pattern .matcher (new MatcherInput (left , new AccessCount ()));
108+ Matcher matcher = pattern .matcher (new MatcherInput (input , new AccessCount ()));
101109 return BooleanTypedValue .forValue (matcher .matches ());
102110 }
103111 catch (PatternSyntaxException ex ) {
@@ -110,6 +118,13 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
110118 }
111119 }
112120
121+ private void checkRegexLength (String regex ) {
122+ if (regex .length () > MAX_REGEX_LENGTH ) {
123+ throw new SpelEvaluationException (getStartPosition (),
124+ SpelMessage .MAX_REGEX_LENGTH_EXCEEDED , MAX_REGEX_LENGTH );
125+ }
126+ }
127+
113128
114129 private static class AccessCount {
115130
@@ -127,7 +142,7 @@ private static class MatcherInput implements CharSequence {
127142
128143 private final CharSequence value ;
129144
130- private AccessCount access ;
145+ private final AccessCount access ;
131146
132147 public MatcherInput (CharSequence value , AccessCount access ) {
133148 this .value = value ;
0 commit comments