tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_parser_diagnostics_unprintables.html (9832B)


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