Fix performance issue in StringAuthLeakDetector
authorMatthew Gharrity <gharrma@google.com>
Tue, 9 Jul 2019 19:34:01 +0000 (12:34 -0700)
committerMatthew Gharrity <gharrma@google.com>
Thu, 1 Aug 2019 22:55:00 +0000 (22:55 +0000)
Java regex matching can actually be quite slow.
In the case of StringAuthLeakDetector, it could take
10s to match a string of length 50k. We fix this by
only looking at strings of length 512 or less, which
take less than 10ms to match.

Test: existing (StringAuthLeakDetectorTest), and manual timing tests
Fixes: 133377376
Change-Id: I4ea4abf41a7a7015bdc8407c61aa6409fa5f6337
(cherry picked from commit 173358c301b2e0a7819b96edf924f86243de4960)

lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/StringAuthLeakDetector.java

index 3c7ea3997f435bd0b435d29640e2bac5058c358c..ad38dba8bd41f8eefa53232cfa6dae7d441d9f5f 100644 (file)
@@ -62,7 +62,13 @@ public class StringAuthLeakDetector extends Detector implements SourceCodeScanne
         @Override
         public void visitLiteralExpression(@NonNull ULiteralExpression node) {
             if (node.getValue() instanceof String) {
-                Matcher matcher = AUTH_REGEXP.matcher((String) node.getValue());
+                String str = (String) node.getValue();
+                if (str.length() > 512) {
+                    // Java regex matching can be very slow, so abort if the string is too long.
+                    // See https://swtch.com/~rsc/regexp/regexp1.html for details.
+                    return;
+                }
+                Matcher matcher = AUTH_REGEXP.matcher(str);
                 if (matcher.find()) {
                     String password = matcher.group(3);
                     if (password == null || (password.startsWith("%") && password.endsWith("s"))) {