Bug 932335 - Part 1: differentiate between unprivileged (http(s) URLs) and privileged URLs r=nalexander
authorAndrzej Hunt <ahunt@mozilla.com>
Mon, 23 May 2016 14:43:18 -0700
changeset 324138 0a86d2aee5eb037767c6161b89a6816d64eda887
parent 324137 228556a98ec92b6ca7782e1bd9f8c0dc70aae6a5
child 324139 37846cb483b903ff7ab8df396ede6b4c0889035e
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs932335
milestone49.0a1
Bug 932335 - Part 1: differentiate between unprivileged (http(s) URLs) and privileged URLs r=nalexander Privileged URLs can include chrome://, jar://, ..., etc. MozReview-Commit-ID: 3lFR7djRGAH
mobile/android/base/java/org/mozilla/gecko/Tab.java
mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
--- a/mobile/android/base/java/org/mozilla/gecko/Tab.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tab.java
@@ -456,18 +456,26 @@ public class Tab {
 
             Favicons.cancelFaviconLoad(mFaviconLoadId);
             mFaviconUrl = newFavicon.faviconUrl;
         } else {
             // Otherwise, fallback to the default Favicon.
             mFaviconUrl = null;
         }
 
+        final Favicons.LoadType loadType;
+        if (mSiteIdentity.getSecurityMode() == SiteIdentity.SecurityMode.CHROMEUI) {
+            loadType = Favicons.LoadType.PRIVILEGED;
+        } else {
+            loadType = Favicons.LoadType.UNPRIVILEGED;
+        }
+
         int flags = (isPrivate() || mErrorType != ErrorType.NONE) ? 0 : LoadFaviconTask.FLAG_PERSIST;
-        mFaviconLoadId = Favicons.getSizedFavicon(mAppContext, mUrl, mFaviconUrl, Favicons.browserToolbarFaviconSize, flags,
+        mFaviconLoadId = Favicons.getSizedFavicon(mAppContext, mUrl, mFaviconUrl,
+                loadType, Favicons.browserToolbarFaviconSize, flags,
                 new OnFaviconLoadedListener() {
                     @Override
                     public void onFaviconLoaded(String pageUrl, String faviconURL, Bitmap favicon) {
                         // The tab might be pointing to another URL by the time the
                         // favicon is finally loaded, in which case we simply ignore it.
                         if (!pageUrl.equals(mUrl)) {
                             return;
                         }
--- a/mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
+++ b/mobile/android/base/java/org/mozilla/gecko/favicons/Favicons.java
@@ -38,16 +38,21 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 public class Favicons {
     private static final String LOGTAG = "GeckoFavicons";
 
+    public enum LoadType {
+        PRIVILEGED,
+        UNPRIVILEGED
+    }
+
     // A magic URL representing the app's own favicon, used for about: pages.
     private static final String BUILT_IN_FAVICON_URL = "about:favicon";
 
     // A magic URL representing the app's search favicon, used for about:home.
     private static final String BUILT_IN_SEARCH_URL = "about:search";
 
     // Size of the favicon bitmap cache, in bytes (Counting payload only).
     public static final int FAVICON_CACHE_SIZE_BYTES = 512 * 1024;
@@ -209,31 +214,39 @@ public class Favicons {
      * @param faviconURL URL of the Favicon to be downloaded, if known. If none provided, an educated
      *                    guess is made by the system.
      * @param targetSize Target size of the returned Favicon
      * @param listener Listener to call with the result of the load operation, if the result is not
      *                  immediately available.
      * @return The id of the asynchronous task created, NOT_LOADING if none is created, or
      *         LOADED if the value could be dispatched on the current thread.
      */
-    public static int getSizedFavicon(Context context, String pageURL, String faviconURL, int targetSize, int flags, OnFaviconLoadedListener listener) {
+    public static int getSizedFavicon(Context context, String pageURL, String faviconURL,
+                                      LoadType loadType, int targetSize, int flags, OnFaviconLoadedListener listener) {
         // Do we know the favicon URL for this page already?
         String cacheURL = faviconURL;
         if (cacheURL == null) {
             cacheURL = pageURLMappings.get(pageURL);
         }
 
         // If there's no favicon URL given, try and hit the cache with the default one.
         if (cacheURL == null) {
             cacheURL = guessDefaultFaviconURL(pageURL);
         }
 
-        // If it's something we can't even figure out a default URL for, just give up.
         if (cacheURL == null) {
+            // If it's something we can't even figure out a default URL for, just give up.
             return dispatchResult(pageURL, null, defaultFavicon, listener);
+        } else if (loadType != LoadType.PRIVILEGED &&
+                !(cacheURL.startsWith("http://") || cacheURL.startsWith("https://"))) {
+            // Don't load internal / other favicons for non-privileged pages. This is only relevant
+            // for getSizedFavicon since this is the only method that allows using a specific favicon
+            // URL. All other methods operate via the cache, icons will only end up in the cache
+            // if we load them via getSizedFavicon in the first place.
+            return NOT_LOADING;
         }
 
         Bitmap cachedIcon = getSizedFaviconFromCache(cacheURL, targetSize);
         if (cachedIcon != null) {
             return dispatchResult(pageURL, cacheURL, cachedIcon, listener);
         }
 
         // Check if favicon has failed.
@@ -623,16 +636,23 @@ public class Favicons {
         final Map<String, Object> row = metadata.get(url);
 
         String touchIconURL = null;
 
         if (row != null) {
             touchIconURL = (String) row.get(URLMetadataTable.TOUCH_ICON_COLUMN);
         }
 
+        if (touchIconURL != null &&
+            !(touchIconURL.startsWith("http://") || touchIconURL.startsWith("https://"))) {
+            // We definitely don't want to load internal icons for homescreen shortcuts. See
+            // our use of LoadType.PRIVILEGED above for where allow non http(s) icons
+            touchIconURL = null;
+        }
+
         // Retrieve the icon while bypassing the cache. Homescreen icon creation is a one-off event, hence it isn't
         // useful to cache these icons. (Android takes care of storing homescreen icons after a shortcut
         // has been created.)
         // The cache is also (currently) limited to 32dp, hence we explicitly need to avoid accessing those icons.
         // If touchIconURL is null, then Favicons falls back to finding the best possible favicon for
         // the site URI, hence we can use this call even when there is no touchIcon defined.
         getPreferredSizeFaviconForPage(context, url, touchIconURL, onFaviconLoadedListener);
     }
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
@@ -167,17 +167,19 @@ public class SearchEnginePreference exte
                 // ever happen (leaving it at 0), so we fall back.
                 if (Favicons.largestFaviconSize == 0) {
                     desiredWidth = 128;
                 } else {
                     desiredWidth = Favicons.largestFaviconSize;
                 }
             }
 
-            Favicons.getSizedFavicon(getContext(), mIdentifier, iconURI, desiredWidth, 0,
+            Favicons.getSizedFavicon(getContext(), mIdentifier, iconURI,
+                Favicons.LoadType.PRIVILEGED, // We have an internal store of search engine icons, hence we're always loading PRIVILEGED icons here
+                desiredWidth, 0,
                 new OnFaviconLoadedListener() {
                     @Override
                     public void onFaviconLoaded(String url, String faviconURL, Bitmap favicon) {
                         synchronized (bitmapLock) {
                             mIconBitmap = favicon;
 
                             if (mFaviconView != null) {
                                 mFaviconView.updateAndScaleImage(mIconBitmap, getTitle().toString());