Bug 1173214, r=seth,bz
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 26 Aug 2015 10:24:04 +0100
changeset 259418 d21ee41c1d04554ed522b2fdb0fbdc695deec36a
parent 259417 920a9f7d4932292e697eb3b66c85f7d6fdf9d574
child 259419 fc1f32837c782176ed0b7ea2f6526ebe06c1b730
push id29278
push userryanvm@gmail.com
push dateThu, 27 Aug 2015 00:28:17 +0000
treeherdermozilla-central@e8ae9c511b50 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth, bz
bugs1173214
milestone43.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 1173214, r=seth,bz
image/decoders/icon/nsIconProtocolHandler.cpp
image/decoders/icon/nsIconURI.cpp
image/decoders/icon/nsIconURI.h
image/test/mochitest/bug415761.ico
image/test/mochitest/chrome.ini
image/test/mochitest/test_bug415761.html
image/test/reftest/icon/win/ImageDocument.css
image/test/reftest/icon/win/bug415761.ico
image/test/reftest/icon/win/bug415761.sjs
image/test/reftest/icon/win/bug415761cleanup.sjs
image/test/reftest/icon/win/reftest.list
image/test/reftest/reftest.list
toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
--- a/image/decoders/icon/nsIconProtocolHandler.cpp
+++ b/image/decoders/icon/nsIconProtocolHandler.cpp
@@ -62,23 +62,32 @@ nsIconProtocolHandler::GetProtocolFlags(
 }
 
 NS_IMETHODIMP
 nsIconProtocolHandler::NewURI(const nsACString& aSpec,
                               const char* aOriginCharset, // ignored
                               nsIURI* aBaseURI,
                               nsIURI** result)
 {
-
-  nsCOMPtr<nsIURI> uri = new nsMozIconURI();
+  nsCOMPtr<nsIMozIconURI> uri = new nsMozIconURI();
   if (!uri) return NS_ERROR_OUT_OF_MEMORY;
 
   nsresult rv = uri->SetSpec(aSpec);
   if (NS_FAILED(rv)) return rv;
 
+  nsCOMPtr<nsIURL> iconURL;
+  uri->GetIconURL(getter_AddRefs(iconURL));
+  if (iconURL) {
+    uri = new nsNestedMozIconURI();
+    rv = uri->SetSpec(aSpec);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  }
+
   NS_ADDREF(*result = uri);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIconProtocolHandler::NewChannel2(nsIURI* url,
                                    nsILoadInfo* aLoadInfo,
                                    nsIChannel** result)
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -7,16 +7,17 @@
 
 #include "mozilla/ArrayUtils.h"
 
 #include "mozilla/ipc/URIUtils.h"
 
 #include "nsIconURI.h"
 #include "nsIIOService.h"
 #include "nsIURL.h"
+#include "nsNetUtil.h"
 #include "prprf.h"
 #include "plstr.h"
 #include <stdlib.h>
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 
 #define DEFAULT_IMAGE_SIZE 16
@@ -642,8 +643,38 @@ nsMozIconURI::Deserialize(const URIParam
   mContentType = params.contentType();
   mFileName = params.fileName();
   mStockIcon = params.stockIcon();
   mIconSize = params.iconSize();
   mIconState = params.iconState();
 
   return true;
 }
+
+////////////////////////////////////////////////////////////
+// Nested version of nsIconURI
+
+nsNestedMozIconURI::nsNestedMozIconURI()
+{ }
+
+nsNestedMozIconURI::~nsNestedMozIconURI()
+{ }
+
+NS_IMPL_ISUPPORTS_INHERITED(nsNestedMozIconURI, nsMozIconURI, nsINestedURI)
+
+NS_IMETHODIMP
+nsNestedMozIconURI::GetInnerURI(nsIURI** aURI)
+{
+  nsCOMPtr<nsIURI> iconURL = do_QueryInterface(mIconURL);
+  if (iconURL) {
+    iconURL.forget(aURI);
+  } else {
+    *aURI = nullptr;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNestedMozIconURI::GetInnermostURI(nsIURI** aURI)
+{
+  return NS_ImplGetInnermostURI(this, aURI);
+}
+
--- a/image/decoders/icon/nsIconURI.h
+++ b/image/decoders/icon/nsIconURI.h
@@ -6,19 +6,20 @@
 
 #ifndef mozilla_image_decoders_icon_nsIconURI_h
 #define mozilla_image_decoders_icon_nsIconURI_h
 
 #include "nsIIconURI.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIIPCSerializableURI.h"
+#include "nsINestedURI.h"
 
-class nsMozIconURI final : public nsIMozIconURI
-                         , public nsIIPCSerializableURI
+class nsMozIconURI : public nsIMozIconURI
+                   , public nsIIPCSerializableURI
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
   NS_DECL_NSIMOZICONURI
   NS_DECL_NSIIPCSERIALIZABLEURI
 
   // nsMozIconURI
@@ -35,9 +36,28 @@ protected:
                        // given a filename with an extension
   nsCString mStockIcon;
   int32_t mIconSize;   // -1 if not specified, otherwise index into
                        // kSizeStrings
   int32_t mIconState;  // -1 if not specified, otherwise index into
                        // kStateStrings
 };
 
+// For moz-icon URIs that point to an actual file on disk and are
+// therefore nested URIs
+class nsNestedMozIconURI final : public nsMozIconURI
+                               , public nsINestedURI
+{
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_FORWARD_NSIURI(nsMozIconURI::)
+  NS_FORWARD_NSIMOZICONURI(nsMozIconURI::)
+  NS_FORWARD_NSIIPCSERIALIZABLEURI(nsMozIconURI::)
+
+  NS_DECL_NSINESTEDURI
+
+  nsNestedMozIconURI();
+
+protected:
+  virtual ~nsNestedMozIconURI();
+
+};
+
 #endif // mozilla_image_decoders_icon_nsIconURI_h
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d3f65abc2306599e947a559422c07ac9b6d3099c
GIT binary patch
literal 766
zc${NkU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdwqbz{G$9G=LF9Lj!~YK_KJ6fdfDq
ZB=R4O82<l<P#_2r0uiHNM1%hW3;++dm6iYi
--- a/image/test/mochitest/chrome.ini
+++ b/image/test/mochitest/chrome.ini
@@ -35,16 +35,20 @@ support-files =
 [test_animSVGImage.html]
 [test_animSVGImage2.html]
 [test_animation.html]
 disabled = bug 1100497
 [test_animation2.html]
 disabled = bug 1101415
 [test_background_image_anim.html]
 [test_bullet_animation.html]
+[test_bug415761.html]
+skip-if = os != "win" || os_version == "6.2"
+support-files =
+  bug415761.ico
 [test_changeOfSource.html]
 [test_changeOfSource2.html]
 [test_has_transparency.html]
 [test_net_failedtoprocess.html]
 [test_removal_ondecode.html]
 [test_removal_onload.html]
 [test_staticClone.html]
 [test_svg_animatedGIF.html]
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/test_bug415761.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for icon filenames</title>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+// We want to make sure that moz-icon URIs with non-ascii characters work. To that
+// end, we compare the rendering of an icon without non-ascii characters to that
+// of one that does include such characters.
+
+// First, obtain the file URI to the ourselves:
+var chromeURI = location.href;
+var io = Components.classes['@mozilla.org/network/io-service;1']
+           .getService(Components.interfaces.nsIIOService);
+chromeURI = io.newURI(chromeURI, null, null);
+var chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+                  .getService(Components.interfaces.nsIChromeRegistry);
+fileURI = chromeReg.convertChromeURL(chromeURI);
+fileURI.QueryInterface(Components.interfaces.nsIFileURL);
+var self = fileURI.file;
+
+// Check if the non-ascii-named icon is still hanging around from a previous test
+var dest = self.parent;
+dest.append("\u263a.ico");
+if (dest.exists()) {
+  dest.remove(false);
+}
+
+// Copy the source icon so that we have an identical icon with non-ascii characters
+// in its name
+var src = self.parent;
+src.append("bug415761.ico");
+src.copyTo(null, dest.leafName);
+
+// Now load both icons in an Image() with a moz-icon URI
+var testImage = new Image();
+var refImage = new Image();
+
+var loadedImages = 0;
+testImage.onload = refImage.onload = function() {
+  loadedImages++;
+  if (loadedImages == 2) {
+    finishTest();
+  }
+};
+testImage.onerror = refImage.onerror = function() {
+  testImage.onload = refImage.onload = function() {};
+
+  ok(false, "Icon did not load successfully");
+  SimpleTest.finish();
+};
+
+function finishTest() {
+  ok(true, "Both icons loaded successfully");
+  // Render the reference to a canvas
+  var refCanvas = document.createElement("canvas");
+  refCanvas.setAttribute("height", 32);
+  refCanvas.setAttribute("width", 32);
+  refCanvas.getContext('2d').drawImage(refImage, 0, 0, 32, 32);
+
+  // Render the icon with a non-ascii character in its name to a canvas
+  var testCanvas = document.createElement("canvas");
+  testCanvas.setAttribute("height", 32);
+  testCanvas.setAttribute("width", 32);
+  testCanvas.getContext('2d').drawImage(testImage, 0, 0, 32, 32);
+
+  // Assert that they should be the same.
+  assertSnapshots(refCanvas, testCanvas, true, 0, "icon", "reference icon");
+  SimpleTest.finish();
+};
+
+var testURI = io.newFileURI(dest).spec;
+var refURI = io.newFileURI(src).spec;
+testImage.src = "moz-icon:" + testURI;
+refImage.src = "moz-icon:" + refURI;
+
+SimpleTest.registerCleanupFunction(function() {
+  // Remove the copied file if it exists.
+  if (dest.exists()) {
+    dest.remove(false);
+  }
+});
+
+</script>
+</pre>
+</body>
+
+</html>
+
deleted file mode 100644
--- a/image/test/reftest/icon/win/ImageDocument.css
+++ /dev/null
@@ -1,16 +0,0 @@
-body {
-  background: #222 url("chrome://global/skin/media/imagedoc-darknoise.png");
-  margin: 0;
-}
-
-body > :first-child {
-  display: block;
-  position: absolute;
-  margin: auto;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
-  color: #222;
-}
deleted file mode 100644
index d3f65abc2306599e947a559422c07ac9b6d3099c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/image/test/reftest/icon/win/bug415761.sjs
+++ /dev/null
@@ -1,21 +0,0 @@
-function handleRequest(request, response)
-{
-  var self = Components.classes["@mozilla.org/file/local;1"]
-                       .createInstance(Components.interfaces.nsILocalFile);
-  self.initWithPath(getState("__LOCATION__"));
-  var dest = self.parent;
-  dest.append("\u263a.ico");
-  if (dest.exists())
-    dest.remove(false);
-  var src = self.parent;
-  src.append("bug415761.ico");
-  src.copyTo(null, dest.leafName);
-  var uri = Components.classes["@mozilla.org/network/io-service;1"]
-                      .getService(Components.interfaces.nsIIOService)
-                      .newFileURI(dest).spec;
-  response.setStatusLine(request.httpVersion, 200, "OK");
-  response.setHeader("Content-Type", "text/html");
-  response.setHeader("Cache-Control", "no-cache");
-  response.write("<link rel=\"stylesheet\" href=\"ImageDocument.css\">");
-  response.write("<img src=\"moz-icon:" + uri + "\" width=\"32\" height=\"32\">");
-}
deleted file mode 100644
--- a/image/test/reftest/icon/win/bug415761cleanup.sjs
+++ /dev/null
@@ -1,12 +0,0 @@
-function handleRequest(request, response)
-{
-  var self = Components.classes["@mozilla.org/file/local;1"]
-                       .createInstance(Components.interfaces.nsILocalFile);
-  self.initWithPath(getState("__LOCATION__"));
-  var dest = self.parent;
-  dest.append("\u263a.ico");
-  if (dest.exists())
-    dest.remove(false);
-  response.setStatusLine(request.httpVersion, 200, "OK");
-  response.setHeader("Content-Type", "text/html");
-}
deleted file mode 100644
--- a/image/test/reftest/icon/win/reftest.list
+++ /dev/null
@@ -1,2 +0,0 @@
-skip-if(!winWidget) skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761.sjs bug415761.ico # See Bug 850194
-skip-if(!winWidget) skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761cleanup.sjs about:blank
--- a/image/test/reftest/reftest.list
+++ b/image/test/reftest/reftest.list
@@ -29,19 +29,16 @@ skip-if(Android) include ico/reftest.lis
 include jpeg/reftest.list
 
 # GIF tests
 include gif/reftest.list
 
 # APNG tests
 include apng/reftest.list
 
-# Icon tests
-include icon/win/reftest.list
-
 # Generic image tests
 include generic/reftest.list
 
 # Color management test
 include color-management/reftest.list
 
 # Downscaling tests
 include downscaling/reftest.list
--- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
+++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -204,13 +204,14 @@ function run_test()
   testStatus(statusFunc, 6, 6, 0, ["Unknown time remaining -- 1.4 of 2.9 KB", Infinity]);
   testStatus(statusFunc, 8, 5, 0, ["Unknown time remaining -- 9.2 of 9.3 GB", Infinity]);
 
   testURI("http://www.mozilla.org/", "mozilla.org", "www.mozilla.org");
   testURI("http://www.city.mikasa.hokkaido.jp/", "city.mikasa.hokkaido.jp", "www.city.mikasa.hokkaido.jp");
   testURI("data:text/html,Hello World", "data resource", "data resource");
   testURI("jar:http://www.mozilla.com/file!/magic", "mozilla.com", "www.mozilla.com");
   testURI("file:///C:/Cool/Stuff/", "local file", "local file");
-  testURI("moz-icon:file:///test.extension", "moz-icon resource", "moz-icon resource");
+  testURI("moz-icon:file:///test.extension", "local file", "local file");
+  testURI("moz-icon://.extension", "moz-icon resource", "moz-icon resource");
   testURI("about:config", "about resource", "about resource");
 
   testAllGetReadableDates();
 }