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 340675 0a86d2aee5eb037767c6161b89a6816d64eda887
parent 340674 228556a98ec92b6ca7782e1bd9f8c0dc70aae6a5
child 340676 37846cb483b903ff7ab8df396ede6b4c0889035e
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs932335
milestone49.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 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());