Bug 1325586 - Prevent creating IconDescriptor with null url, r=sebastian
authorjwu <topwu.tw@gmail.com>
Mon, 16 Jan 2017 15:56:43 +0800
changeset 377506 ba650eee2f3b1c340bdbcef33ad16c8d552e1e3d
parent 377505 18775df0c5946acc24da018a7c4eb7011663017e
child 377507 69843027051d2c05dd704e943da661a2f950998a
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssebastian
bugs1325586
milestone53.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 1325586 - Prevent creating IconDescriptor with null url, r=sebastian MozReview-Commit-ID: 4y6fKR49DGG
mobile/android/base/java/org/mozilla/gecko/Tab.java
mobile/android/base/java/org/mozilla/gecko/icons/IconDescriptor.java
mobile/android/base/java/org/mozilla/gecko/icons/storage/FailureCache.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
@@ -32,16 +32,17 @@ import org.mozilla.gecko.widget.SiteLogi
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.BitmapDrawable;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 
 public class Tab {
     private static final String LOGTAG = "GeckoTab";
 
     private static Pattern sColorPattern;
@@ -428,23 +429,23 @@ public class Tab {
     public void setHasTouchListeners(boolean aValue) {
         mHasTouchListeners = aValue;
     }
 
     public boolean getHasTouchListeners() {
         return mHasTouchListeners;
     }
 
-    public synchronized void addFavicon(String faviconURL, int faviconSize, String mimeType) {
+    public synchronized void addFavicon(@NonNull String faviconURL, int faviconSize, String mimeType) {
         mIconRequestBuilder
                 .icon(IconDescriptor.createFavicon(faviconURL, faviconSize, mimeType))
                 .deferBuild();
     }
 
-    public synchronized void addTouchicon(String iconUrl, int faviconSize, String mimeType) {
+    public synchronized void addTouchicon(@NonNull String iconUrl, int faviconSize, String mimeType) {
         mIconRequestBuilder
                 .icon(IconDescriptor.createTouchicon(iconUrl, faviconSize, mimeType))
                 .deferBuild();
     }
 
     public void loadFavicon() {
         // Static Favicons never change
         if (AboutPages.isBuiltinIconPage(mUrl) && mFavicon != null) {
--- a/mobile/android/base/java/org/mozilla/gecko/icons/IconDescriptor.java
+++ b/mobile/android/base/java/org/mozilla/gecko/icons/IconDescriptor.java
@@ -1,16 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.icons;
 
 import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 
 /**
  * A class describing the location and properties of an icon that can be loaded.
  */
 public class IconDescriptor {
     @IntDef({ TYPE_GENERIC, TYPE_FAVICON, TYPE_TOUCHICON, TYPE_LOOKUP })
@@ -25,44 +26,44 @@ public class IconDescriptor {
     private final String url;
     private final int size;
     private final String mimeType;
     private final int type;
 
     /**
      * Create a generic icon located at the given URL. No MIME type or size is known.
      */
-    public static IconDescriptor createGenericIcon(String url) {
+    public static IconDescriptor createGenericIcon(@NonNull String url) {
         return new IconDescriptor(TYPE_GENERIC, url, 0, null);
     }
 
     /**
      * Create a favicon located at the given URL and with a known size and MIME type.
      */
-    public static IconDescriptor createFavicon(String url, int size, String mimeType) {
+    public static IconDescriptor createFavicon(@NonNull String url, int size, String mimeType) {
         return new IconDescriptor(TYPE_FAVICON, url, size, mimeType);
     }
 
     /**
      * Create a touch icon located at the given URL and with a known MIME type and size.
      */
-    public static IconDescriptor createTouchicon(String url, int size, String mimeType) {
+    public static IconDescriptor createTouchicon(@NonNull String url, int size, String mimeType) {
         return new IconDescriptor(TYPE_TOUCHICON, url, size, mimeType);
     }
 
     /**
      * Create an icon located at an URL that has been returned from a disk or memory storage. This
      * is an icon with an URL we loaded an icon from previously. Therefore we give it a little higher
      * ranking than a generic icon - even though we do not know the MIME type or size of the icon.
      */
-    public static IconDescriptor createLookupIcon(String url) {
+    public static IconDescriptor createLookupIcon(@NonNull String url) {
         return new IconDescriptor(TYPE_LOOKUP, url, 0, null);
     }
 
-    private IconDescriptor(@IconType int type, String url, int size, String mimeType) {
+    private IconDescriptor(@IconType int type, @NonNull String url, int size, String mimeType) {
         this.type = type;
         this.url = url;
         this.size = size;
         this.mimeType = mimeType;
     }
 
     /**
      * Get the URL of the icon.
--- a/mobile/android/base/java/org/mozilla/gecko/icons/storage/FailureCache.java
+++ b/mobile/android/base/java/org/mozilla/gecko/icons/storage/FailureCache.java
@@ -1,16 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.icons.storage;
 
 import android.os.SystemClock;
+import android.support.annotation.NonNull;
 import android.support.annotation.VisibleForTesting;
 import android.util.LruCache;
 
 /**
  * In-memory cache to remember URLs from which loading icons has failed recently.
  */
 public class FailureCache {
     /**
@@ -34,24 +35,24 @@ public class FailureCache {
 
     private FailureCache() {
         cache = new LruCache<>(MAX_ENTRIES);
     }
 
     /**
      * Remember this icon URL after loading from it (over the network) has failed.
      */
-    public void rememberFailure(String iconUrl) {
+    public void rememberFailure(@NonNull String iconUrl) {
         cache.put(iconUrl, SystemClock.elapsedRealtime());
     }
 
     /**
      * Has loading from this URL failed previously and recently?
      */
-    public boolean isKnownFailure(String iconUrl) {
+    public boolean isKnownFailure(@NonNull String iconUrl) {
         synchronized (cache) {
             final Long failedAt = cache.get(iconUrl);
             if (failedAt == null) {
                 return false;
             }
 
             if (failedAt + FAILURE_RETRY_MILLISECONDS < SystemClock.elapsedRealtime()) {
                 // The wait time has passed and we can retry loading from this URL.
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/SearchEnginePreference.java
@@ -15,16 +15,17 @@ import org.mozilla.gecko.widget.FaviconV
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.support.design.widget.Snackbar;
 import android.text.SpannableString;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 
 /**
  * Represents an element in the list of search engines on the preferences menu.
  */
 public class SearchEnginePreference extends CustomListPreference {
     protected String LOGTAG = "SearchEnginePreference";
@@ -150,16 +151,20 @@ public class SearchEnginePreference exte
         }
 
         final String engineName = geckoEngine.getString("name");
         final SpannableString titleSpannable = new SpannableString(engineName);
 
         setTitle(titleSpannable);
 
         final String iconURI = geckoEngine.getString("iconURI");
+        if (TextUtils.isEmpty(iconURI)) {
+            return;
+        }
+
         // Keep a reference to the bitmap - we'll need it later in onBindView.
         try {
             Icons.with(getContext())
                     .pageUrl(mIdentifier)
                     .icon(IconDescriptor.createGenericIcon(iconURI))
                     .privileged(true)
                     .build()
                     .execute(new IconCallback() {