Bug 1218324 - Correctly report when a search engine could not be installed due to an invalid format. r?florian draft
authorMark Banner <standard8@mozilla.com>
Wed, 14 Dec 2016 14:55:00 +0000
changeset 479415 d3f1921940913fb4984b2e735a678e236a257951
parent 479141 20a8536b0bfac74389d3a57bd8dd957d98779ce1
child 544675 f3976576cf7de5795a93c586559d8bb69243eee5
push id44245
push userbmo:standard8@mozilla.com
push dateMon, 06 Feb 2017 16:38:38 +0000
reviewersflorian
bugs1218324
milestone54.0a1
Bug 1218324 - Correctly report when a search engine could not be installed due to an invalid format. r?florian MozReview-Commit-ID: Cqw0uKDWguy
browser/components/search/test/browser.ini
browser/components/search/test/browser_webapi.js
browser/components/search/test/testEngine_missing_namespace.xml
toolkit/components/processsingleton/MainProcessSingleton.js
toolkit/components/search/nsSearchService.js
toolkit/locales/en-US/chrome/search/search.properties
--- a/browser/components/search/test/browser.ini
+++ b/browser/components/search/test/browser.ini
@@ -4,16 +4,17 @@ support-files =
   483086-1.xml
   483086-2.xml
   head.js
   opensearch.html
   test.html
   testEngine.xml
   testEngine_diacritics.xml
   testEngine_dupe.xml
+  testEngine_missing_namespace.xml
   testEngine_mozsearch.xml
   tooManyEnginesOffered.html
   webapi.html
 
 [browser_426329.js]
 [browser_483086.js]
 [browser_addEngine.js]
 [browser_amazon.js]
--- a/browser/components/search/test/browser_webapi.js
+++ b/browser/components/search/test/browser_webapi.js
@@ -62,21 +62,22 @@ add_task(function* test_relative() {
   is(dialog.args.text, getString("addEngineConfirmation", "Foo", "example.com"),
      "Should have seen the right install message");
   dialog.document.documentElement.cancelDialog();
 
   gBrowser.removeCurrentTab();
 });
 
 add_task(function* test_invalid() {
-  gBrowser.selectedTab = AddSearchProvider("z://foobar");
+  let url = "z://foobar";
+  gBrowser.selectedTab = AddSearchProvider(url);
 
   let dialog = yield promiseDialogOpened();
   is(dialog.args.promptType, "alert", "Should see the alert dialog.");
-  is(dialog.args.text, getString("error_invalid_engine_msg", brandName),
+  is(dialog.args.text, getString("error_invalid_engine_msg2", brandName, url),
      "Should have seen the right error message")
   dialog.document.documentElement.acceptDialog();
 
   gBrowser.removeCurrentTab();
 });
 
 add_task(function* test_missing() {
   let url = ROOT + "foobar.xml";
@@ -85,8 +86,21 @@ add_task(function* test_missing() {
   let dialog = yield promiseDialogOpened();
   is(dialog.args.promptType, "alert", "Should see the alert dialog.");
   is(dialog.args.text, getString("error_loading_engine_msg2", brandName, url),
      "Should have seen the right error message")
   dialog.document.documentElement.acceptDialog();
 
   gBrowser.removeCurrentTab();
 });
+
+add_task(function* test_missing_namespace() {
+  let url = ROOT + "testEngine_missing_namespace.xml";
+  gBrowser.selectedTab = AddSearchProvider(url);
+
+  let dialog = yield promiseDialogOpened();
+  is(dialog.args.promptType, "alert", "Should see the alert dialog.");
+  is(dialog.args.text, getString("error_invalid_engine_msg2", brandName, url),
+     "Should have seen the right error message")
+  dialog.document.documentElement.acceptDialog();
+
+  gBrowser.removeCurrentTab();
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/testEngine_missing_namespace.xml
@@ -0,0 +1,11 @@
+<OpenSearchDescription>
+  <ShortName>Foo</ShortName>
+  <Description>Foo Search</Description>
+  <InputEncoding>utf-8</InputEncoding>
+  <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
+  <Url type="text/html" method="GET" template="http://mochi.test:8888/browser/browser/components/search/test/?search">
+    <Param name="test" value="{searchTerms}"/>
+  </Url>
+  <moz:SearchForm>http://mochi.test:8888/browser/browser/components/search/test/</moz:SearchForm>
+  <moz:Alias>fooalias</moz:Alias>
+</OpenSearchDescription>
--- a/toolkit/components/processsingleton/MainProcessSingleton.js
+++ b/toolkit/components/processsingleton/MainProcessSingleton.js
@@ -44,19 +44,19 @@ MainProcessSingleton.prototype = {
       if (iconURL && isWeb.indexOf(iconURL.scheme) < 0)
         throw "Unsupported search icon URL: " + iconURL;
     } catch (ex) {
       Cu.reportError("Invalid argument passed to window.external.AddSearchProvider: " + ex);
 
       var searchBundle = Services.strings.createBundle("chrome://global/locale/search/search.properties");
       var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
       var brandName = brandBundle.GetStringFromName("brandShortName");
-      var title = searchBundle.GetStringFromName("error_invalid_engine_title");
-      var msg = searchBundle.formatStringFromName("error_invalid_engine_msg",
-                                                  [brandName], 1);
+      var title = searchBundle.GetStringFromName("error_invalid_format_title");
+      var msg = searchBundle.formatStringFromName("error_invalid_engine_msg2",
+                                                  [brandName, engineURL.spec], 2);
       Services.ww.getNewPrompter(browser.ownerGlobal).alert(title, msg);
       return;
     }
 
     Services.search.init(function(status) {
       if (status != Cr.NS_OK)
         return;
 
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -1606,17 +1606,23 @@ Engine.prototype = {
     aEngine._data = doc.documentElement;
 
     try {
       // Initialize the engine from the obtained data
       aEngine._initFromData();
     } catch (ex) {
       LOG("_onLoad: Failed to init engine!\n" + ex);
       // Report an error to the user
-      promptError();
+      if (ex.result == Cr.NS_ERROR_FILE_CORRUPTED) {
+        promptError({ error: "error_invalid_engine_msg2",
+                      title: "error_invalid_format_title"
+                    });
+      } else {
+        promptError();
+      }
       return;
     }
 
     if (aEngine._engineToUpdate) {
       let engineToUpdate = aEngine._engineToUpdate.wrappedJSObject;
 
       // Make this new engine use the old engine's shortName, and preserve
       // metadata.
@@ -1828,19 +1834,20 @@ Engine.prototype = {
     if ((element.localName == MOZSEARCH_LOCALNAME &&
          element.namespaceURI == MOZSEARCH_NS_10) ||
         (element.localName == OPENSEARCH_LOCALNAME &&
          OPENSEARCH_NAMESPACES.indexOf(element.namespaceURI) != -1)) {
       LOG("_init: Initing search plugin from " + this._location);
 
       this._parse();
 
-    } else
-      FAIL(this._location + " is not a valid search plugin.", Cr.NS_ERROR_FAILURE);
-
+    } else {
+      Cu.reportError("Invalid search plugin due to namespace not matching.");
+      FAIL(this._location + " is not a valid search plugin.", Cr.NS_ERROR_FILE_CORRUPTED);
+    }
     // No need to keep a ref to our data (which in some cases can be a document
     // element) past this point
     this._data = null;
   },
 
   /**
    * Initialize this Engine object from a collection of metadata.
    */
--- a/toolkit/locales/en-US/chrome/search/search.properties
+++ b/toolkit/locales/en-US/chrome/search/search.properties
@@ -8,13 +8,13 @@ addEngineAsCurrentText=Make this the c&u
 addEngineAddButtonLabel=Add
 
 error_loading_engine_title=Download Error
 # LOCALIZATION NOTE (error_loading_engine_msg2): %1$S = brandShortName, %2$S = location
 error_loading_engine_msg2=%S could not download the search plugin from:\n%S
 error_duplicate_engine_msg=%S could not install the search plugin from “%S” because an engine with the same name already exists.
 
 error_invalid_engine_title=Install Error
-# LOCALIZATION NOTE (error_invalid_engine_msg): %S = brandShortName
-error_invalid_engine_msg=This search engine isn’t supported by %S and can’t be installed.
+error_invalid_format_title=Invalid Format
+# LOCALIZATION NOTE (error_invalid_engine_msg2): %1$S = brandShortName, %2$S = location (url)
+error_invalid_engine_msg2=%1$S could not install the search engine from: %2$S
 
 suggestion_label=Suggestions
-