Revision: 5498
Author:   [email protected]
Date:     Wed Jul 17 15:10:25 2013
Log:      fix client-side parsing of minified css
https://codereview.appspot.com/11470043

The client-side css parser has a couple problems handling minified css.

1. ruleset() always skips the token following the selector, which is
expected to be '{', even if it isn't a '{'. This screws up parsing of
problems like
  @foo{x}y{...}
because the x is a selector and the '}' gets skipped, so the y gets
absorbed into @foo.

2. ruleset() always skips the token following the closing '}'. This
is harmless if the token is whitespace, but screws up but if the
next statement is not separated by whitespace.

This fixes
https://code.google.com/p/google-caja/issues/detail?id=1770

R=mikesamuel


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

Modified:
 /trunk/src/com/google/caja/plugin/cssparser.js
 /trunk/tests/com/google/caja/plugin/cssparser_test.js

=======================================
--- /trunk/src/com/google/caja/plugin/cssparser.js      Fri Jun 22 11:39:33 2012
+++ /trunk/src/com/google/caja/plugin/cssparser.js      Wed Jul 17 15:10:25 2013
@@ -171,17 +171,16 @@
       // Skip malformed content per selector calling convention.
       e = ~e;
       // Make sure we skip at least one token.
-      return i === e ? e+1 : e;
+      return e === s ? e+1 : e;
     }
-    i = e;
+    var tok = toks[e];
+    if (tok !== '{') {
+      // Make sure we skip at least one token.
+      return e === s ? e+1 : e;
+    }
+    i = e+1;  // Skip over '{'
     // Don't include any trailing space in the selector slice.
     if (e > s && toks[e-1] === ' ') { --e; }
-    var tok = toks[i];
-    ++i;  // Skip over '{'
-    if (tok !== '{') {
-      // Skips past the '{' when there is a malformed input.
-      return i;
-    }
     if (handler.startRuleset) {
       handler.startRuleset(toks.slice(s, e));
     }
@@ -200,7 +199,7 @@
     if (handler.endRuleset) {
       handler.endRuleset();
     }
-    return i < n ? i+1 : i;
+    return i;
   }

   // selector    : any+;
=======================================
--- /trunk/tests/com/google/caja/plugin/cssparser_test.js Mon Apr 29 12:40:55 2013 +++ /trunk/tests/com/google/caja/plugin/cssparser_test.js Wed Jul 17 15:10:25 2013
@@ -260,3 +260,52 @@
       'input.cl\\:ass[xml\\:lang ~= "en:us"] { color: blue }');
   jsunit.pass();
 });
+
+// https://code.google.com/p/google-caja/issues/detail?id=1770
+// check parsing and error recovery when there are no spaces
+jsunitRegister('testMinifiedCss1', function testMinifiedCss1() {
+  assertParsedCssStylesheet(
+      ['startStylesheet', [],
+       'startRuleset',    [['a']],
+       'endRuleset',      [],
+       'startRuleset',    [['b']],
+       'declaration',     ['color', ['blue']],
+       'endRuleset',      [],
+       'endStylesheet',   []],
+      'a{bogus}b{color:blue}');
+  jsunit.pass();
+});
+
+jsunitRegister('testMinifiedCss2', function testMinifiedCss2() {
+  assertParsedCssStylesheet(
+      ['startStylesheet', [],
+       'startAtrule',     ['@something', []],
+       'startBlock',
+       'startRuleset',    [['a']],
+       'declaration',     ['color', ['red']],
+       'endRuleset',      [],
+       'endBlock',
+       'endAtrule',
+       'startRuleset',    [['b']],
+       'declaration',     ['color', ['blue']],
+       'endRuleset',      [],
+       'endStylesheet',   []],
+      '@something{a{color:red}}b{color:blue}');
+  jsunit.pass();
+});
+
+jsunitRegister('testMinifiedCss3', function testMinifiedCss3() {
+  assertParsedCssStylesheet(
+      ['startStylesheet', [],
+       'startAtrule',     ['@something', []],
+       'startBlock',
+       'endBlock',
+       'endAtrule',
+       'startRuleset',    [['b']],
+       'declaration',     ['color', ['blue']],
+       'endRuleset',      [],
+       'endStylesheet',   []],
+      '@something{bogus}b{color:blue}');
+  jsunit.pass();
+});
+

--

--- 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