Bug 1218086 - Continue parsing Intent if fallback uri is invalid. r=margaret
authorMichael Comella <michael.l.comella@gmail.com>
Wed, 28 Oct 2015 17:52:01 -0700
changeset 304410 fba5a9a4ba80b74853753234a6f47d342abf0eb5
parent 304409 5bf26fca6041fb35d8da4bc3284b94a78e7489dc
child 304411 df3d8c8316968efc61946c02c438d387a8bbddfc
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs1218086
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1218086 - Continue parsing Intent if fallback uri is invalid. r=margaret
mobile/android/base/IntentHelper.java
--- a/mobile/android/base/IntentHelper.java
+++ b/mobile/android/base/IntentHelper.java
@@ -15,16 +15,17 @@ import org.mozilla.gecko.util.WebActivit
 import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.content.Intent;
 import android.net.Uri;
+import android.support.annotation.Nullable;
 import android.support.v4.app.FragmentActivity;
 import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
@@ -47,18 +48,16 @@ public final class IntentHelper implemen
         "Intent:OpenNoHandler",
     };
 
     // via http://developer.android.com/distribute/tools/promote/linking.html
     private static String MARKET_INTENT_URI_PACKAGE_PREFIX = "market://details?id=";
     private static String EXTRA_BROWSER_FALLBACK_URL = "browser_fallback_url";
 
     /** A partial URI to an error page - the encoded error URI should be appended before loading. */
-    private static final String GENERIC_URI_PREFIX = "about:neterror?e=generic&u=";
-    private static final String MALFORMED_URI_PREFIX = "about:neterror?e=malformedURI&u=";
     private static String UNKNOWN_PROTOCOL_URI_PREFIX = "about:neterror?e=unknownProtocolFound&u=";
 
     private static IntentHelper instance;
 
     private final FragmentActivity activity;
 
     private IntentHelper(final FragmentActivity activity) {
         this.activity = activity;
@@ -181,34 +180,20 @@ public final class IntentHelper implemen
             // Don't log the exception to prevent leaking URIs.
             Log.w(LOGTAG, "Unable to parse Intent URI - loading about:neterror");
             callback.sendError(errorUri);
             return;
         }
 
         // For this flow, we follow Chrome's lead:
         //   https://developer.chrome.com/multidevice/android/intents
-        if (intent.hasExtra(EXTRA_BROWSER_FALLBACK_URL)) {
-            final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
-            String urlToLoad;
-            try {
-                final String anyCaseScheme = new URI(fallbackUrl).getScheme();
-                final String scheme = (anyCaseScheme == null) ? null : anyCaseScheme.toLowerCase(Locale.US);
-                if ("http".equals(scheme) || "https".equals(scheme)) {
-                    urlToLoad = fallbackUrl;
-                } else {
-                    Log.w(LOGTAG, "Fallback URI uses unsupported scheme: " + scheme);
-                    urlToLoad = GENERIC_URI_PREFIX + fallbackUrl;
-                }
-            } catch (final URISyntaxException e) {
-                // Do not include Exception to avoid leaking uris.
-                Log.w(LOGTAG, "Exception parsing fallback URI");
-                urlToLoad = MALFORMED_URI_PREFIX + fallbackUrl;
-            }
-            callback.sendError(urlToLoad);
+        final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
+        if (isFallbackUrlValid(fallbackUrl)) {
+            // Opens the page in JS.
+            callback.sendError(fallbackUrl);
 
         } else if (intent.getPackage() != null) {
             // Note on alternative flows: we could get the intent package from a component, however, for
             // security reasons, components are ignored when opening URIs (bug 1168998) so we should
             // ignore it here too.
             //
             // Our old flow used to prompt the user to search for their app in the market by scheme and
             // while this could help the user find a new app, there is not always a correlation in
@@ -227,16 +212,36 @@ public final class IntentHelper implemen
 
         }  else {
             // Don't log the URI to prevent leaking it.
             Log.w(LOGTAG, "Unable to open URI, default case - loading about:neterror");
             callback.sendError(getUnknownProtocolErrorPageUri(intent.getData().toString()));
         }
     }
 
+    private static boolean isFallbackUrlValid(@Nullable final String fallbackUrl) {
+        if (fallbackUrl == null) {
+            return false;
+        }
+
+        try {
+            final String anyCaseScheme = new URI(fallbackUrl).getScheme();
+            final String scheme = (anyCaseScheme == null) ? null : anyCaseScheme.toLowerCase(Locale.US);
+            if ("http".equals(scheme) || "https".equals(scheme)) {
+                return true;
+            } else {
+                Log.w(LOGTAG, "Fallback URI uses unsupported scheme: " + scheme + ". Try http or https.");
+            }
+        } catch (final URISyntaxException e) {
+            // Do not include Exception to avoid leaking uris.
+            Log.w(LOGTAG, "URISyntaxException parsing fallback URI");
+        }
+        return false;
+    }
+
     /**
      * Returns an about:neterror uri with the unknownProtocolFound text as a parameter.
      * @param encodedUri The encoded uri. While the page does not open correctly without specifying
      *                   a uri parameter, it happily accepts the empty String so this argument may
      *                   be the empty String.
      */
     private String getUnknownProtocolErrorPageUri(final String encodedUri) {
         return UNKNOWN_PROTOCOL_URI_PREFIX + encodedUri;