Bug 1404386 - Sanitize theme accentcolor to prevent the window from becoming transparent. r?jaws draft
authorDão Gottwald <dao@mozilla.com>
Fri, 29 Sep 2017 18:49:55 +0200
changeset 672706 0a29febb51ea2863476ef2bababa3ec9ddad8cc8
parent 672686 935eca685536793ab7df8bfc9fb52d70128f7756
child 733892 3053f073fc218babaed9081dc30706e945945e52
push id82343
push userdgottwald@mozilla.com
push dateFri, 29 Sep 2017 16:50:24 +0000
reviewersjaws
bugs1404386
milestone58.0a1
Bug 1404386 - Sanitize theme accentcolor to prevent the window from becoming transparent. r?jaws MozReview-Commit-ID: ChV3SOGSbjN
toolkit/modules/LightweightThemeConsumer.jsm
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -118,19 +118,19 @@ LightweightThemeConsumer.prototype = {
     let active = !!aData.headerURL;
     let stateChanging = (active != this._active);
 
     // We need to clear these either way: either because the theme is being removed,
     // or because we are applying a new theme and the data might be bogus CSS,
     // so if we don't reset first, it'll keep the old value.
     root.style.removeProperty("--lwt-text-color");
     root.style.removeProperty("--lwt-accent-color");
-    let textcolor = aData.textcolor || "black";
+    let textcolor = this._sanitizeCSSColor(aData.textcolor) || "black";
     _setProperty(root, active, "--lwt-text-color", textcolor);
-    _setProperty(root, active, "--lwt-accent-color", aData.accentcolor || "white");
+    _setProperty(root, active, "--lwt-accent-color", this._sanitizeCSSColor(aData.accentcolor) || "white");
     if (active) {
       let dummy = this._doc.createElement("dummy");
       dummy.style.color = textcolor;
       let [r, g, b] = _parseRGB(this._doc.defaultView.getComputedStyle(dummy).color);
       let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
       root.setAttribute("lwthemetextcolor", luminance <= 110 ? "dark" : "bright");
       root.setAttribute("lwtheme", "true");
     } else {
@@ -178,16 +178,29 @@ LightweightThemeConsumer.prototype = {
           root.setAttribute("chromemargin", defaultChromemargin);
         } else {
           root.removeAttribute("chromemargin");
         }
       }
     }
     Services.obs.notifyObservers(this._win, "lightweight-theme-window-updated",
                                  JSON.stringify(aData));
+  },
+
+  _sanitizeCSSColor(cssColor) {
+    // style.color normalizes color values and rejects invalid ones, so a
+    // simple round trip gets us a sanitized color value.
+    let span = this._doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
+    span.style.color = cssColor;
+    cssColor = span.style.color;
+    if (cssColor == "transparent" ||
+        cssColor == "rgba(0, 0, 0, 0)") {
+      return "";
+    }
+    return cssColor;
   }
 }
 
 function _setImage(aRoot, aActive, aVariableName, aURLs) {
   if (aURLs && !Array.isArray(aURLs)) {
     aURLs = [aURLs];
   }
   _setProperty(aRoot, aActive, aVariableName, aURLs && aURLs.map(v => `url("${v.replace(/"/g, '\\"')}")`).join(","));