Revision: 5547
Author:   [email protected]
Date:     Fri Aug  9 13:29:37 2013
Log: Sanitize canvas style property values rather than requiring exact match.
https://codereview.appspot.com/12699046

Possibly due to recent changes in the CSS sanitizer, 2D canvas would
not accept rgb() and rgba() colors:
<https://code.google.com/p/google-caja/issues/detail?id=1837>

Now, instead of sanitizing the property and requiring the result to be
identical to the input, we just sanitize the property. If there was a
rationale for doing it the former way, I've forgotten it.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=5547

Modified:
 /trunk/src/com/google/caja/plugin/domado.js
 /trunk/tests/com/google/caja/plugin/es53-test-domado-canvas-guest.html

=======================================
--- /trunk/src/com/google/caja/plugin/domado.js Wed Aug  7 15:47:37 2013
+++ /trunk/src/com/google/caja/plugin/domado.js Fri Aug  9 13:29:37 2013
@@ -4672,32 +4672,24 @@
           return specimen;
         }

-        function matchesStyleFully(cssPropertyName, value) {
-          if (typeof value !== "string") { return false; }
+        /** Returns '' if invalid, which native canvas will ignore. */
+        function sanitizeCssValue(cssPropertyName, value) {
+          if (typeof value !== 'string') { return ''; }
           var tokens = lexCss(value);
-          var k = 0;
-          for (var i = 0, n = tokens.length; i < n; ++i) {
-            var tok = tokens[i];
-            if (tok !== ' ') { tokens[k++] = tok; }
-          }
-          tokens.length = k;
-          // sanitizeCssProperty lowercases non-URL/content-string tokens.
-          var unfiltered = tokens.join(' ').toLowerCase();
           sanitizeCssProperty(cssPropertyName, tokens);
-          return unfiltered === tokens.join(' ') ? unfiltered : false;
+          return tokens.join(' ');
         }
-
-        function isFont(value) {
-          return !!matchesStyleFully('font', value);
+        function sanitizeFont(value) {
+          return sanitizeCssValue('font', value);
         }
-        function isColor(value) {
-          // Note: we're testing against the pattern for the CSS "color:"
- // property, but what is actually referenced by the draft canvas spec
-          // is
-          // the CSS syntactic element <color>, which is why we need to
-          // specifically exclude "inherit".
-          var style = matchesStyleFully('color', value);
-          return style && style.toLowerCase() !== 'inherit';
+        function sanitizeColor(value) {
+ // Note: we're sanitizing against the CSS "color:" property, but what
+          // is actually referenced by the draft canvas spec is the CSS
+ // syntactic element <color>, which is why we need to specifically
+          // exclude "inherit".
+          var style = sanitizeCssValue('color', value);
+          if (/\binherit\b/.test(style)) { return ''; }
+          return style;
         }
         var colorNameTable = {
           // http://dev.w3.org/csswg/css3-color/#html4 as cited by
@@ -4835,11 +4827,12 @@
                 throw new Error(INDEX_SIZE_ERROR);
                 // TODO(kpreid): should be a DOMException per spec
               }
-              if (!isColor(color)) {
+              var sanColor = sanitizeColor(color);
+              if (sanColor === '') {
                 throw new Error('SYNTAX_ERR');
                 // TODO(kpreid): should be a DOMException per spec
               }
-              privates.feral.addColorStop(offset, color);
+              privates.feral.addColorStop(offset, sanColor);
             })
           });
           return cajaVM.def(TameGradient);
@@ -5178,8 +5171,9 @@
                 }
               }),
               set: env.amplifying(function(privates, newValue) {
-                if (isColor(newValue)) {
-                  privates.feral[prop] = newValue;
+                var safeColor = sanitizeColor(newValue);
+                if (safeColor !== '') {
+                  privates.feral[prop] = safeColor;
                 } else if (typeof(newValue) === 'object' &&
                            cajaVM.passesGuard(TameGradientT, newValue)) {
                   privates.feral[prop] = taming.untame(newValue);
@@ -5246,11 +5240,11 @@
                 enumerable: true,
                 // TODO(kpreid): Better tools for deriving descriptors
                 get: CP_STYLE(env).get,
-                set: PT.RWCond(isColor)(env).set
+                set: PT.filterProp(identity, sanitizeColor)(env).set
               };
             }),

-            font: PT.RWCond(isFont),
+            font: PT.filterProp(identity, sanitizeFont),
             textAlign: PT.RWCond(
                 StringTest([
                   'start',
=======================================
--- /trunk/tests/com/google/caja/plugin/es53-test-domado-canvas-guest.html Thu May 23 14:04:29 2013 +++ /trunk/tests/com/google/caja/plugin/es53-test-domado-canvas-guest.html Fri Aug 9 13:29:37 2013
@@ -105,13 +105,17 @@
                  ["aardvarks", {toString:function(){return "xor";}}]);

     // context.fillStyle
-    testProperty("fillStyle", "#000000", "#ff0000",
- ["aardvarks", 999, {toString:function(){return "#ff0000";}},
-                  "inherit"]);
+    testProperty('fillStyle', '#000000', '#ff0000',
+                 ['aardvarks', 'rgba()', 999,
+                  {toString:function(){return '#ff0000';}}, "inherit"]);
     context.fillStyle = "black";
     assertEquals("named fillStyle", "#000000", context.fillStyle);
     context.fillStyle = "#FF0000";
     assertEquals("uppercase fillStyle", "#ff0000", context.fillStyle);
+    context.fillStyle = 'rgb(0, 255, 0)';
+    assertEquals('rgb fillStyle', '#00ff00', context.fillStyle);
+    context.fillStyle = 'rgba(0, 0, 255, 0.0)';
+ assertEquals('rgba fillStyle', 'rgba(0, 0, 255, 0)', context.fillStyle);

     // context.strokeStyle
     // assume strokeStyle has the same taming structure as fillStyle,

--

--- You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to