Bug 977844 - Make sure snippets response is valid JSON before caching it (or trying to use it). r=bnicholson
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Fri, 28 Feb 2014 17:26:56 -0800
changeset 171794 6de7f6039a6841c6437d7256d1a37f62016657fe
parent 171793 2fb022dbbe729a716567849a62d06f85e91d0fb2
child 171795 6b1b7f585bdad108f11022ecc0eaeda2634e2916
child 171797 e8a7c100b5fe174827b055e73327942db1c046ac
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbnicholson
bugs977844
milestone30.0a1
Bug 977844 - Make sure snippets response is valid JSON before caching it (or trying to use it). r=bnicholson
mobile/android/components/Snippets.js
--- a/mobile/android/components/Snippets.js
+++ b/mobile/android/components/Snippets.js
@@ -113,18 +113,25 @@ function updateCountryCode(callback) {
 }
 
 /**
  * Loads snippets from snippets server, caches the response, and
  * updates the home banner with the new set of snippets.
  */
 function updateSnippets() {
   _httpGetRequest(gSnippetsURL, function(responseText) {
-    cacheSnippets(responseText);
-    updateBanner(responseText);
+    try {
+      let messages = JSON.parse(responseText);
+      updateBanner(messages);
+
+      // Only cache the response if it is valid JSON.
+      cacheSnippets(responseText);
+    } catch (e) {
+      Cu.reportError("Error parsing snippets responseText: " + e);
+    }
   });
 }
 
 /**
  * Caches snippets server response text to `snippets.json` in profile directory.
  *
  * @param response responseText returned from snippets server
  */
@@ -134,50 +141,50 @@ function cacheSnippets(response) {
   promise.then(null, e => Cu.reportError("Error caching snippets: " + e));
 }
 
 /**
  * Loads snippets from cached `snippets.json`.
  */
 function loadSnippetsFromCache() {
   let promise = OS.File.read(gSnippetsPath);
-  promise.then(array => updateBanner(gDecoder.decode(array)), e => {
+  promise.then(array => {
+    let messages = JSON.parse(gDecoder.decode(array));
+    updateBanner(messages);
+  }, e => {
     if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
       Cu.reportError("Couldn't show snippets because cache does not exist yet.");
     } else {
       Cu.reportError("Error loading snippets from cache: " + e);
     }
   });
 }
 
 // Array of the message ids added to the home banner, used to remove
 // older set of snippets when new ones are available.
 var gMessageIds = [];
 
 /**
  * Updates set of snippets in the home banner message rotation.
  *
- * @param response responseText returned from snippets server.
- *   This should be a JSON array of message data JSON objects.
+ * @param messages JSON array of message data JSON objects.
  *   Each message object should have the following properties:
  *     - id (?): Unique identifier for this snippets message
  *     - text (string): Text to show as banner message
  *     - url (string): URL to open when banner is clicked
  *     - icon (data URI): Icon to appear in banner
  *     - target_geo (string): Country code for where this message should be shown (e.g. "US")
  */
-function updateBanner(response) {
+function updateBanner(messages) {
   // Remove the current messages, if there are any.
   gMessageIds.forEach(function(id) {
     Home.banner.remove(id);
   })
   gMessageIds = [];
 
-  let messages = JSON.parse(response);
-
   try {
     let removedSnippetIds = JSON.parse(Services.prefs.getCharPref(SNIPPETS_REMOVED_IDS_PREF));
     messages = messages.filter(function(message) {
       // Only include the snippet if it has not been previously removed.
       return removedSnippetIds.indexOf(message.id) === -1;
     });
   } catch (e) {
     // If the pref doesn't exist, there aren't any snippets to filter out.