@@ -114,7 +114,21 @@ private Grok(Map<String, String> patternBank, String grokPattern, boolean namedC
114
114
* check for a circular reference.
115
115
*/
116
116
private void forbidCircularReferences (String patternName , List <String > path , String pattern ) {
117
- if (pattern .contains ("%{" + patternName + "}" ) || pattern .contains ("%{" + patternName + ":" )) {
117
+ // first ensure that the pattern bank contains no simple circular references (i.e., any pattern
118
+ // containing an immediate reference to itself) as those can cause the remainder of this algorithm
119
+ // to recurse infinitely
120
+ for (Map .Entry <String , String > entry : patternBank .entrySet ()) {
121
+ if (patternReferencesItself (entry .getValue (), entry .getKey ())) {
122
+ throw new IllegalArgumentException ("circular reference in pattern [" + entry .getKey () + "][" + entry .getValue () + "]" );
123
+ }
124
+ }
125
+
126
+ // next recursively check any other pattern names referenced in the pattern
127
+ innerForbidCircularReferences (patternName , path , pattern );
128
+ }
129
+
130
+ private void innerForbidCircularReferences (String patternName , List <String > path , String pattern ) {
131
+ if (patternReferencesItself (pattern , patternName )) {
118
132
String message ;
119
133
if (path .isEmpty ()) {
120
134
message = "circular reference in pattern [" + patternName + "][" + pattern + "]" ;
@@ -129,17 +143,18 @@ private void forbidCircularReferences(String patternName, List<String> path, Str
129
143
throw new IllegalArgumentException (message );
130
144
}
131
145
146
+ // next check any other pattern names found in the pattern
132
147
for (int i = pattern .indexOf ("%{" ); i != -1 ; i = pattern .indexOf ("%{" , i + 1 )) {
133
148
int begin = i + 2 ;
134
- int brackedIndex = pattern .indexOf ('}' , begin );
149
+ int bracketIndex = pattern .indexOf ('}' , begin );
135
150
int columnIndex = pattern .indexOf (':' , begin );
136
151
int end ;
137
- if (brackedIndex != -1 && columnIndex == -1 ) {
138
- end = brackedIndex ;
139
- } else if (columnIndex != -1 && brackedIndex == -1 ) {
152
+ if (bracketIndex != -1 && columnIndex == -1 ) {
153
+ end = bracketIndex ;
154
+ } else if (columnIndex != -1 && bracketIndex == -1 ) {
140
155
end = columnIndex ;
141
- } else if (brackedIndex != -1 && columnIndex != -1 ) {
142
- end = Math .min (brackedIndex , columnIndex );
156
+ } else if (bracketIndex != -1 && columnIndex != -1 ) {
157
+ end = Math .min (bracketIndex , columnIndex );
143
158
} else {
144
159
throw new IllegalArgumentException ("pattern [" + pattern + "] has circular references to other pattern definitions" );
145
160
}
@@ -149,6 +164,10 @@ private void forbidCircularReferences(String patternName, List<String> path, Str
149
164
}
150
165
}
151
166
167
+ private static boolean patternReferencesItself (String pattern , String patternName ) {
168
+ return pattern .contains ("%{" + patternName + "}" ) || pattern .contains ("%{" + patternName + ":" );
169
+ }
170
+
152
171
public String groupMatch (String name , Region region , String pattern ) {
153
172
try {
154
173
int number = GROK_PATTERN_REGEX .nameToBackrefNumber (name .getBytes (StandardCharsets .UTF_8 ), 0 ,
0 commit comments