Skip to content

Commit 98a5134

Browse files
committed
Fix Inefficient regular expression
Some regular expressions take a long time to match certain input strings to the point where the time it takes to match a string of length n is proportional to nk or even 2n. Such regular expressions can negatively affect performance, or even allow a malicious user to perform a Denial of Service ("DoS") attack by crafting an expensive input string for the regular expression to match. This replaces the problematic regular expression by a little parser that checks for the same results as the regular expression.
1 parent ea1089d commit 98a5134

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PDETextHelper.java

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
import java.util.Map;
1717
import java.util.Set;
18-
import java.util.regex.Matcher;
19-
import java.util.regex.Pattern;
2018

2119
public class PDETextHelper {
2220

@@ -283,13 +281,49 @@ private static boolean isValidTagAttributeList(String text) {
283281
// " att1="value1" att2="value2"
284282
// " att1="value1" att2="value2 /"
285283
// " att1="value1"
284+
while (!text.isBlank()) {
285+
int idx = text.indexOf('=');
286+
if (idx < 0) {
287+
return text.trim().equals("/"); //$NON-NLS-1$
288+
}
289+
String key = text.substring(0, idx).trim();
290+
if (!isValidAttributeKey(key)) {
291+
return false;
292+
}
293+
String remaining = text.substring(idx + 1).trim();
294+
if (!remaining.startsWith("\"")) { //$NON-NLS-1$
295+
return false;
296+
}
297+
int end = remaining.indexOf('"', 1);
298+
if (end < 0) {
299+
return false;
300+
}
301+
text = remaining.substring(end + 1);
302+
}
303+
return true;
304+
}
305+
306+
private static boolean isValidAttributeKey(String key) {
307+
if (key.isEmpty()) {
308+
return false;
309+
}
310+
int length = key.length();
311+
for (int i = 0; i < length; i++) {
312+
char c = key.charAt(i);
313+
if (!isValidAttributeKeyChar(c)) {
314+
return false;
315+
}
316+
}
317+
return true;
318+
}
286319

287-
// space attributeName space = space "attributeValue" space /
288-
String patternString = "^([\\s]+[A-Za-z0-9_:\\-\\.]+[\\s]?=[\\s]?\".+?\")*[\\s]*[/]?$"; //$NON-NLS-1$
289-
Pattern pattern = Pattern.compile(patternString);
290-
Matcher matcher = pattern.matcher(text);
291-
// Determine whether the given attribute list matches the pattern
292-
return matcher.find();
320+
private static boolean isValidAttributeKeyChar(char c) {
321+
return (c >= 'A' && c <= 'Z') || //
322+
(c >= 'a' && c <= 'z') || //
323+
(c >= '0' && c <= '9') || //
324+
c == '_' || //
325+
c == '-' || //
326+
c == ':';
293327
}
294328

295329
private static String getTagName(String buffer) {

0 commit comments

Comments
 (0)