Index: chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java |
index 1eca2c96dce9aba68b4853176d8e0fab675a370f..059b27b3e487e8b83af1ddd3b9360dd7bd6705ac 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/UrlUtilities.java |
@@ -11,6 +11,7 @@ import org.chromium.base.CollectionUtil; |
import java.net.URI; |
import java.net.URISyntaxException; |
import java.util.HashSet; |
+import java.util.regex.Pattern; |
/** |
* Utilities for working with URIs (and URLs). These methods may be used in security-sensitive |
@@ -207,6 +208,63 @@ public class UrlUtilities { |
return nativeGetDomainAndRegistry(uri, includePrivateRegistries); |
} |
+ /** |
+ * @param url An Android intent:// URL to validate. |
+ * |
+ * @throws URISyntaxException if url is not a valid Android intent:// |
+ * URL, as specified at |
+ * https://developer.chrome.com/multidevice/android/intents#syntax. |
+ */ |
+ public static boolean validateIntentUrl(String url) { |
+ URI parsed = null; |
+ try { |
+ parsed = new URI(url); |
+ } catch (URISyntaxException e) { |
+ return false; |
+ } |
+ |
+ if (!parsed.getScheme().equals("intent")) { |
+ return false; |
+ } |
+ if (!Pattern.matches("^[\\w\\.-]*$", parsed.getHost())) { |
Yaron
2015/04/24 16:04:18
I would build a Matcher and use that since it's re
palmer
2015/04/24 18:05:22
Not exactly; note the allowed "-" (which is legal
|
+ return false; |
+ } |
+ if (!parsed.getPath().isEmpty() && !parsed.getPath().equals("/")) { |
+ return false; |
+ } |
+ |
+ String[] parts = parsed.getFragment().split(";"); |
+ if (parts.length < 3 |
+ || parts.length > 7 |
Jaekyun Seok (inactive)
2015/04/24 02:05:52
parts.length could be bigger than 7 because extra
palmer
2015/04/24 18:05:22
Done.
|
+ || !parts[0].equals("Intent") |
+ || !parts[parts.length - 1].equals("end")) { |
+ return false; |
+ } |
+ |
+ for (int i = 1; i < parts.length - 1; ++i) { |
+ // This is OK *only* because no valid package, action, category, |
+ // component, or scheme contains "=". |
+ String[] pair = parts[i].split("="); |
+ if (2 != pair.length) return false; |
+ |
+ if (pair[0].equals("package")) { |
+ if (!Pattern.matches("^[\\w\\.]+$", pair[1])) return false; |
+ } else if (pair[0].equals("action")) { |
+ if (!Pattern.matches("^[\\w\\.]+$", pair[1])) return false; |
+ } else if (pair[0].equals("category")) { |
+ if (!Pattern.matches("^[\\w\\.]+$", pair[1])) return false; |
+ } else if (pair[0].equals("component")) { |
+ if (!Pattern.matches("^[\\w\\.]+$", pair[1])) return false; |
+ } else if (pair[0].equals("scheme")) { |
+ if (!Pattern.matches("^[a-zA-Z]+$", pair[1])) return false; |
+ } else { |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+ } |
+ |
private static native boolean nativeSameDomainOrHost(String primaryUrl, String secondaryUrl, |
boolean includePrivateRegistries); |
private static native String nativeGetDomainAndRegistry(String url, |