layout/style/test/test_parser_diagnostics_unprintables.html

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 <!doctype html>
     2 <html>
     3 <head>
     4   <meta charset="utf-8">
     5   <title>Test for CSS parser diagnostics escaping unprintable
     6          characters correctly</title>
     7   <script src="/tests/SimpleTest/SimpleTest.js"></script>
     8   <link rel="stylesheet" href="/tests/SimpleTest/test.css">
     9 </head>
    10 <body>
    11 <a target="_blank"
    12    href="https://bugzilla.mozilla.org/show_bug.cgi?id=229827"
    13 >Mozilla Bug 229827</a>
    14 <style id="testbench"></style>
    15 <script type="application/javascript;version=1.8">
    16 // This test has intimate knowledge of how to get the CSS parser to
    17 // emit diagnostics that contain text under control of the user.
    18 // That's not the point of the test, though; the point is only that
    19 // *that text* is properly escaped.
    21 // There is one "pattern" for each code path through the error reporter
    22 // that might need to escape some kind of user-supplied text.
    23 // Each "pattern" is tested once with each of the "substitution"s below:
    24 // <t>, <i>, and <s> are replaced by the t:, i:, and s: fields of
    25 // each substitution object in turn.
    26 const patterns = [
    27   // REPORT_UNEXPECTED_P (only ever used in contexts where identifier-like
    28   // escaping is appropriate)
    29   { i: "<t>|x{}",                 o: "prefix '<i>'" },
    30   // REPORT_UNEXPECTED_TOKEN with:
    31   // _Ident
    32   { i: "@namespace fnord <t>;",    o: "within @namespace: '<i>'" },
    33   // _Ref
    34   { i: "@namespace fnord #<t>;",   o: "within @namespace: '#<i>'" },
    35   // _Function
    36   { i: "@namespace fnord <t>();",  o: "within @namespace: '<i>('" },
    37   // _Dimension
    38   { i: "@namespace fnord 14<t>;",  o: "within @namespace: '14<i>'" },
    39   // _AtKeyword
    40   { i: "x{@<t>: }",        o: "declaration but found '@<i>'." },
    41   // _String
    42   { i: "x{ '<t>'}" ,       o: "declaration but found ''<s>''." },
    43   // _Bad_String
    44   { i: "x{ '<t>\n}",      o: "declaration but found ''<s>'." },
    45   // _URL
    46   { i: "x{ url('<t>')}",   o: "declaration but found 'url('<s>')'." },
    47   // _Bad_URL
    48   { i: "x{ url('<t>'.)}" , o: "declaration but found 'url('<s>''." }
    49 ];
    51 // Blocks of characters to test, and how they should be escaped when
    52 // they appear in identifiers and string constants.
    53 const substitutions = [
    54   // ASCII printables that _can_ normally appear in identifiers,
    55   // so should of course _not_ be escaped.
    56   { t: "-_0123456789",               i: "-_0123456789",
    57                                      s: "-_0123456789" },
    58   { t: "abcdefghijklmnopqrstuvwxyz", i: "abcdefghijklmnopqrstuvwxyz",
    59                                      s: "abcdefghijklmnopqrstuvwxyz" },
    60   { t: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    61                                      s: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
    63   // ASCII printables that are not normally valid as the first character
    64   // of an identifier, or the character immediately after a leading dash,
    65   // but can be forced into that position with escapes.
    66   { t: "\\-",    i: "\\-",    s: "-"  },
    67   { t: "\\30 ",  i: "\\30 ",  s: "0"  },
    68   { t: "\\31 ",  i: "\\31 ",  s: "1"  },
    69   { t: "\\32 ",  i: "\\32 ",  s: "2"  },
    70   { t: "\\33 ",  i: "\\33 ",  s: "3"  },
    71   { t: "\\34 ",  i: "\\34 ",  s: "4"  },
    72   { t: "\\35 ",  i: "\\35 ",  s: "5"  },
    73   { t: "\\36 ",  i: "\\36 ",  s: "6"  },
    74   { t: "\\37 ",  i: "\\37 ",  s: "7"  },
    75   { t: "\\38 ",  i: "\\38 ",  s: "8"  },
    76   { t: "\\39 ",  i: "\\39 ",  s: "9"  },
    77   { t: "-\\-",   i: "-\\-",   s: "--" },
    78   { t: "-\\30 ", i: "-\\30 ", s: "-0" },
    79   { t: "-\\31 ", i: "-\\31 ", s: "-1" },
    80   { t: "-\\32 ", i: "-\\32 ", s: "-2" },
    81   { t: "-\\33 ", i: "-\\33 ", s: "-3" },
    82   { t: "-\\34 ", i: "-\\34 ", s: "-4" },
    83   { t: "-\\35 ", i: "-\\35 ", s: "-5" },
    84   { t: "-\\36 ", i: "-\\36 ", s: "-6" },
    85   { t: "-\\37 ", i: "-\\37 ", s: "-7" },
    86   { t: "-\\38 ", i: "-\\38 ", s: "-8" },
    87   { t: "-\\39 ", i: "-\\39 ", s: "-9" },
    89   // ASCII printables that must be escaped in identifiers.
    90   // Most of these should not be escaped in strings.
    91   { t: "\\!\\\"\\#\\$",   i: "\\!\\\"\\#\\$",   s: "!\\\"#$" },
    92   { t: "\\%\\&\\'\\(",    i: "\\%\\&\\'\\(",    s: "%&\\'(" },
    93   { t: "\\)\\*\\+\\,",    i: "\\)\\*\\+\\,",    s: ")*+," },
    94   { t: "\\.\\/\\:\\;",    i: "\\.\\/\\:\\;",    s: "./:;" },
    95   { t: "\\<\\=\\>\\?",    i: "\\<\\=\\>\\?",    s: "<=>?", },
    96   { t: "\\@\\[\\\\\\]",   i: "\\@\\[\\\\\\]",   s: "@[\\\\]" },
    97   { t: "\\^\\`\\{\\}\\~", i: "\\^\\`\\{\\}\\~", s: "^`{}~" },
    99   // U+0000 - U+0020 (C0 controls, space)
   100   // U+000A LINE FEED, U+000C FORM FEED, and U+000D CARRIAGE RETURN
   101   // cannot be put into a CSS token as escaped literal characters, so
   102   // we do them with hex escapes instead.
   103   // The parser replaces U+0000 with U+FFFD.
   104   { t: "\\\x00\\\x01\\\x02\\\x03",       i: "�\\1 \\2 \\3 ",
   105                                          s: "�\\1 \\2 \\3 " },
   106   { t: "\\\x04\\\x05\\\x06\\\x07",       i: "\\4 \\5 \\6 \\7 ",
   107                                          s: "\\4 \\5 \\6 \\7 " },
   108   { t: "\\\x08\\\x09\\000A\\\x0B",       i: "\\8 \\9 \\A \\B ",
   109                                          s: "\\8 \\9 \\A \\B " },
   110   { t: "\\000C\\000D\\\x0E\\\x0F",       i: "\\C \\D \\E \\F ",
   111                                          s: "\\C \\D \\E \\F " },
   112   { t: "\\\x10\\\x11\\\x12\\\x13",       i: "\\10 \\11 \\12 \\13 ",
   113                                          s: "\\10 \\11 \\12 \\13 " },
   114   { t: "\\\x14\\\x15\\\x16\\\x17",       i: "\\14 \\15 \\16 \\17 ",
   115                                          s: "\\14 \\15 \\16 \\17 " },
   116   { t: "\\\x18\\\x19\\\x1A\\\x1B",       i: "\\18 \\19 \\1A \\1B ",
   117                                          s: "\\18 \\19 \\1A \\1B " },
   118   { t: "\\\x1C\\\x1D\\\x1E\\\x1F\\ ",    i: "\\1C \\1D \\1E \\1F \\ ",
   119                                          s: "\\1C \\1D \\1E \\1F  " },
   121   // U+007F (DELETE) and U+0080 - U+009F (C1 controls)
   122   { t: "\\\x7f\\\x80\\\x81\\\x82",       i: "\\7F \\80 \\81 \\82 ",
   123                                          s: "\\7F \\80 \\81 \\82 " },
   124   { t: "\\\x83\\\x84\\\x85\\\x86",       i: "\\83 \\84 \\85 \\86 ",
   125                                          s: "\\83 \\84 \\85 \\86 " },
   126   { t: "\\\x87\\\x88\\\x89\\\x8A",       i: "\\87 \\88 \\89 \\8A ",
   127                                          s: "\\87 \\88 \\89 \\8A " },
   128   { t: "\\\x8B\\\x8C\\\x8D\\\x8E",       i: "\\8B \\8C \\8D \\8E ",
   129                                          s: "\\8B \\8C \\8D \\8E " },
   130   { t: "\\\x8F\\\x90\\\x91\\\x92",       i: "\\8F \\90 \\91 \\92 ",
   131                                          s: "\\8F \\90 \\91 \\92 " },
   132   { t: "\\\x93\\\x94\\\x95\\\x96",       i: "\\93 \\94 \\95 \\96 ",
   133                                          s: "\\93 \\94 \\95 \\96 " },
   134   { t: "\\\x97\\\x98\\\x99\\\x9A",       i: "\\97 \\98 \\99 \\9A ",
   135                                          s: "\\97 \\98 \\99 \\9A " },
   136   { t: "\\\x9B\\\x9C\\\x9D\\\x9E\\\x9F", i: "\\9B \\9C \\9D \\9E \\9F ",
   137                                          s: "\\9B \\9C \\9D \\9E \\9F " },
   139   // CSS doesn't bother with the full Unicode rules for identifiers,
   140   // instead declaring that any code point greater than or equal to
   141   // U+00A0 is a valid identifier character.  Test a small handful
   142   // of both basic and astral plane characters.
   144   // Arabic (caution to editors: there is a possibly-invisible U+200E
   145   // LEFT-TO-RIGHT MARK in each string, just before the close quote)
   146   { t: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
   147     i: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
   148     s: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎" },
   150   // Box drawing
   151   { t: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
   152     i: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
   153     s: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷" },
   155   // CJK Unified Ideographs
   156   { t: "一丁丂七丄丅丆万丈三上下丌不与丏",
   157     i: "一丁丂七丄丅丆万丈三上下丌不与丏",
   158     s: "一丁丂七丄丅丆万丈三上下丌不与丏" },
   160   // CJK Unified Ideographs Extension B (astral)
   161   { t: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
   162     i: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
   163     s: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏" },
   165   // Devanagari
   166   { t: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
   167     i: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
   168     s: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह" },
   170   // Emoticons (astral)
   171   { t: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
   172     i: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
   173     s: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐" },
   175   // Greek
   176   { t: "αβγδεζηθικλμνξοπρςστυφχψω",
   177     i: "αβγδεζηθικλμνξοπρςστυφχψω",
   178     s: "αβγδεζηθικλμνξοπρςστυφχψω" }
   179 ];
   181 const npatterns = patterns.length;
   182 const nsubstitutions = substitutions.length;
   184 function quotemeta(str) {
   185   return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
   186 }
   187 function subst(str, sub) {
   188   return str.replace("<t>", sub.t)
   189     .replace("<i>", sub.i)
   190     .replace("<s>", sub.s);
   191 }
   193 var curpat = 0;
   194 var cursubst = -1;
   195 var testbench = document.getElementById("testbench");
   197 function nextTest() {
   198   cursubst++;
   199   if (cursubst == nsubstitutions) {
   200     curpat++;
   201     cursubst = 0;
   202   }
   203   if (curpat == npatterns) {
   204     SimpleTest.finish();
   205     return;
   206   }
   208   let css = subst(patterns[curpat].i, substitutions[cursubst]);
   209   let msg = quotemeta(subst(patterns[curpat].o, substitutions[cursubst]));
   211   SimpleTest.expectConsoleMessages(function () { testbench.innerHTML = css },
   212                                    [{ errorMessage: new RegExp(msg) }],
   213                                    nextTest);
   214 }
   216 SimpleTest.waitForExplicitFinish();
   217 nextTest();
   218 </script>
   219 </body>
   220 </html>

mercurial