layout/style/test/test_parser_diagnostics_unprintables.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/test/test_parser_diagnostics_unprintables.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,220 @@
     1.4 +<!doctype html>
     1.5 +<html>
     1.6 +<head>
     1.7 +  <meta charset="utf-8">
     1.8 +  <title>Test for CSS parser diagnostics escaping unprintable
     1.9 +         characters correctly</title>
    1.10 +  <script src="/tests/SimpleTest/SimpleTest.js"></script>
    1.11 +  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
    1.12 +</head>
    1.13 +<body>
    1.14 +<a target="_blank"
    1.15 +   href="https://bugzilla.mozilla.org/show_bug.cgi?id=229827"
    1.16 +>Mozilla Bug 229827</a>
    1.17 +<style id="testbench"></style>
    1.18 +<script type="application/javascript;version=1.8">
    1.19 +// This test has intimate knowledge of how to get the CSS parser to
    1.20 +// emit diagnostics that contain text under control of the user.
    1.21 +// That's not the point of the test, though; the point is only that
    1.22 +// *that text* is properly escaped.
    1.23 +
    1.24 +// There is one "pattern" for each code path through the error reporter
    1.25 +// that might need to escape some kind of user-supplied text.
    1.26 +// Each "pattern" is tested once with each of the "substitution"s below:
    1.27 +// <t>, <i>, and <s> are replaced by the t:, i:, and s: fields of
    1.28 +// each substitution object in turn.
    1.29 +const patterns = [
    1.30 +  // REPORT_UNEXPECTED_P (only ever used in contexts where identifier-like
    1.31 +  // escaping is appropriate)
    1.32 +  { i: "<t>|x{}",                 o: "prefix '<i>'" },
    1.33 +  // REPORT_UNEXPECTED_TOKEN with:
    1.34 +  // _Ident
    1.35 +  { i: "@namespace fnord <t>;",    o: "within @namespace: '<i>'" },
    1.36 +  // _Ref
    1.37 +  { i: "@namespace fnord #<t>;",   o: "within @namespace: '#<i>'" },
    1.38 +  // _Function
    1.39 +  { i: "@namespace fnord <t>();",  o: "within @namespace: '<i>('" },
    1.40 +  // _Dimension
    1.41 +  { i: "@namespace fnord 14<t>;",  o: "within @namespace: '14<i>'" },
    1.42 +  // _AtKeyword
    1.43 +  { i: "x{@<t>: }",        o: "declaration but found '@<i>'." },
    1.44 +  // _String
    1.45 +  { i: "x{ '<t>'}" ,       o: "declaration but found ''<s>''." },
    1.46 +  // _Bad_String
    1.47 +  { i: "x{ '<t>\n}",      o: "declaration but found ''<s>'." },
    1.48 +  // _URL
    1.49 +  { i: "x{ url('<t>')}",   o: "declaration but found 'url('<s>')'." },
    1.50 +  // _Bad_URL
    1.51 +  { i: "x{ url('<t>'.)}" , o: "declaration but found 'url('<s>''." }
    1.52 +];
    1.53 +
    1.54 +// Blocks of characters to test, and how they should be escaped when
    1.55 +// they appear in identifiers and string constants.
    1.56 +const substitutions = [
    1.57 +  // ASCII printables that _can_ normally appear in identifiers,
    1.58 +  // so should of course _not_ be escaped.
    1.59 +  { t: "-_0123456789",               i: "-_0123456789",
    1.60 +                                     s: "-_0123456789" },
    1.61 +  { t: "abcdefghijklmnopqrstuvwxyz", i: "abcdefghijklmnopqrstuvwxyz",
    1.62 +                                     s: "abcdefghijklmnopqrstuvwxyz" },
    1.63 +  { t: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    1.64 +                                     s: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
    1.65 +
    1.66 +  // ASCII printables that are not normally valid as the first character
    1.67 +  // of an identifier, or the character immediately after a leading dash,
    1.68 +  // but can be forced into that position with escapes.
    1.69 +  { t: "\\-",    i: "\\-",    s: "-"  },
    1.70 +  { t: "\\30 ",  i: "\\30 ",  s: "0"  },
    1.71 +  { t: "\\31 ",  i: "\\31 ",  s: "1"  },
    1.72 +  { t: "\\32 ",  i: "\\32 ",  s: "2"  },
    1.73 +  { t: "\\33 ",  i: "\\33 ",  s: "3"  },
    1.74 +  { t: "\\34 ",  i: "\\34 ",  s: "4"  },
    1.75 +  { t: "\\35 ",  i: "\\35 ",  s: "5"  },
    1.76 +  { t: "\\36 ",  i: "\\36 ",  s: "6"  },
    1.77 +  { t: "\\37 ",  i: "\\37 ",  s: "7"  },
    1.78 +  { t: "\\38 ",  i: "\\38 ",  s: "8"  },
    1.79 +  { t: "\\39 ",  i: "\\39 ",  s: "9"  },
    1.80 +  { t: "-\\-",   i: "-\\-",   s: "--" },
    1.81 +  { t: "-\\30 ", i: "-\\30 ", s: "-0" },
    1.82 +  { t: "-\\31 ", i: "-\\31 ", s: "-1" },
    1.83 +  { t: "-\\32 ", i: "-\\32 ", s: "-2" },
    1.84 +  { t: "-\\33 ", i: "-\\33 ", s: "-3" },
    1.85 +  { t: "-\\34 ", i: "-\\34 ", s: "-4" },
    1.86 +  { t: "-\\35 ", i: "-\\35 ", s: "-5" },
    1.87 +  { t: "-\\36 ", i: "-\\36 ", s: "-6" },
    1.88 +  { t: "-\\37 ", i: "-\\37 ", s: "-7" },
    1.89 +  { t: "-\\38 ", i: "-\\38 ", s: "-8" },
    1.90 +  { t: "-\\39 ", i: "-\\39 ", s: "-9" },
    1.91 +
    1.92 +  // ASCII printables that must be escaped in identifiers.
    1.93 +  // Most of these should not be escaped in strings.
    1.94 +  { t: "\\!\\\"\\#\\$",   i: "\\!\\\"\\#\\$",   s: "!\\\"#$" },
    1.95 +  { t: "\\%\\&\\'\\(",    i: "\\%\\&\\'\\(",    s: "%&\\'(" },
    1.96 +  { t: "\\)\\*\\+\\,",    i: "\\)\\*\\+\\,",    s: ")*+," },
    1.97 +  { t: "\\.\\/\\:\\;",    i: "\\.\\/\\:\\;",    s: "./:;" },
    1.98 +  { t: "\\<\\=\\>\\?",    i: "\\<\\=\\>\\?",    s: "<=>?", },
    1.99 +  { t: "\\@\\[\\\\\\]",   i: "\\@\\[\\\\\\]",   s: "@[\\\\]" },
   1.100 +  { t: "\\^\\`\\{\\}\\~", i: "\\^\\`\\{\\}\\~", s: "^`{}~" },
   1.101 +
   1.102 +  // U+0000 - U+0020 (C0 controls, space)
   1.103 +  // U+000A LINE FEED, U+000C FORM FEED, and U+000D CARRIAGE RETURN
   1.104 +  // cannot be put into a CSS token as escaped literal characters, so
   1.105 +  // we do them with hex escapes instead.
   1.106 +  // The parser replaces U+0000 with U+FFFD.
   1.107 +  { t: "\\\x00\\\x01\\\x02\\\x03",       i: "�\\1 \\2 \\3 ",
   1.108 +                                         s: "�\\1 \\2 \\3 " },
   1.109 +  { t: "\\\x04\\\x05\\\x06\\\x07",       i: "\\4 \\5 \\6 \\7 ",
   1.110 +                                         s: "\\4 \\5 \\6 \\7 " },
   1.111 +  { t: "\\\x08\\\x09\\000A\\\x0B",       i: "\\8 \\9 \\A \\B ",
   1.112 +                                         s: "\\8 \\9 \\A \\B " },
   1.113 +  { t: "\\000C\\000D\\\x0E\\\x0F",       i: "\\C \\D \\E \\F ",
   1.114 +                                         s: "\\C \\D \\E \\F " },
   1.115 +  { t: "\\\x10\\\x11\\\x12\\\x13",       i: "\\10 \\11 \\12 \\13 ",
   1.116 +                                         s: "\\10 \\11 \\12 \\13 " },
   1.117 +  { t: "\\\x14\\\x15\\\x16\\\x17",       i: "\\14 \\15 \\16 \\17 ",
   1.118 +                                         s: "\\14 \\15 \\16 \\17 " },
   1.119 +  { t: "\\\x18\\\x19\\\x1A\\\x1B",       i: "\\18 \\19 \\1A \\1B ",
   1.120 +                                         s: "\\18 \\19 \\1A \\1B " },
   1.121 +  { t: "\\\x1C\\\x1D\\\x1E\\\x1F\\ ",    i: "\\1C \\1D \\1E \\1F \\ ",
   1.122 +                                         s: "\\1C \\1D \\1E \\1F  " },
   1.123 +
   1.124 +  // U+007F (DELETE) and U+0080 - U+009F (C1 controls)
   1.125 +  { t: "\\\x7f\\\x80\\\x81\\\x82",       i: "\\7F \\80 \\81 \\82 ",
   1.126 +                                         s: "\\7F \\80 \\81 \\82 " },
   1.127 +  { t: "\\\x83\\\x84\\\x85\\\x86",       i: "\\83 \\84 \\85 \\86 ",
   1.128 +                                         s: "\\83 \\84 \\85 \\86 " },
   1.129 +  { t: "\\\x87\\\x88\\\x89\\\x8A",       i: "\\87 \\88 \\89 \\8A ",
   1.130 +                                         s: "\\87 \\88 \\89 \\8A " },
   1.131 +  { t: "\\\x8B\\\x8C\\\x8D\\\x8E",       i: "\\8B \\8C \\8D \\8E ",
   1.132 +                                         s: "\\8B \\8C \\8D \\8E " },
   1.133 +  { t: "\\\x8F\\\x90\\\x91\\\x92",       i: "\\8F \\90 \\91 \\92 ",
   1.134 +                                         s: "\\8F \\90 \\91 \\92 " },
   1.135 +  { t: "\\\x93\\\x94\\\x95\\\x96",       i: "\\93 \\94 \\95 \\96 ",
   1.136 +                                         s: "\\93 \\94 \\95 \\96 " },
   1.137 +  { t: "\\\x97\\\x98\\\x99\\\x9A",       i: "\\97 \\98 \\99 \\9A ",
   1.138 +                                         s: "\\97 \\98 \\99 \\9A " },
   1.139 +  { t: "\\\x9B\\\x9C\\\x9D\\\x9E\\\x9F", i: "\\9B \\9C \\9D \\9E \\9F ",
   1.140 +                                         s: "\\9B \\9C \\9D \\9E \\9F " },
   1.141 +
   1.142 +  // CSS doesn't bother with the full Unicode rules for identifiers,
   1.143 +  // instead declaring that any code point greater than or equal to
   1.144 +  // U+00A0 is a valid identifier character.  Test a small handful
   1.145 +  // of both basic and astral plane characters.
   1.146 +
   1.147 +  // Arabic (caution to editors: there is a possibly-invisible U+200E
   1.148 +  // LEFT-TO-RIGHT MARK in each string, just before the close quote)
   1.149 +  { t: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
   1.150 +    i: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
   1.151 +    s: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎" },
   1.152 +
   1.153 +  // Box drawing
   1.154 +  { t: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
   1.155 +    i: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
   1.156 +    s: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷" },
   1.157 +
   1.158 +  // CJK Unified Ideographs
   1.159 +  { t: "一丁丂七丄丅丆万丈三上下丌不与丏",
   1.160 +    i: "一丁丂七丄丅丆万丈三上下丌不与丏",
   1.161 +    s: "一丁丂七丄丅丆万丈三上下丌不与丏" },
   1.162 +
   1.163 +  // CJK Unified Ideographs Extension B (astral)
   1.164 +  { t: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
   1.165 +    i: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
   1.166 +    s: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏" },
   1.167 +
   1.168 +  // Devanagari
   1.169 +  { t: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
   1.170 +    i: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
   1.171 +    s: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह" },
   1.172 +
   1.173 +  // Emoticons (astral)
   1.174 +  { t: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
   1.175 +    i: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
   1.176 +    s: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐" },
   1.177 +
   1.178 +  // Greek
   1.179 +  { t: "αβγδεζηθικλμνξοπρςστυφχψω",
   1.180 +    i: "αβγδεζηθικλμνξοπρςστυφχψω",
   1.181 +    s: "αβγδεζηθικλμνξοπρςστυφχψω" }
   1.182 +];
   1.183 +
   1.184 +const npatterns = patterns.length;
   1.185 +const nsubstitutions = substitutions.length;
   1.186 +
   1.187 +function quotemeta(str) {
   1.188 +  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
   1.189 +}
   1.190 +function subst(str, sub) {
   1.191 +  return str.replace("<t>", sub.t)
   1.192 +    .replace("<i>", sub.i)
   1.193 +    .replace("<s>", sub.s);
   1.194 +}
   1.195 +
   1.196 +var curpat = 0;
   1.197 +var cursubst = -1;
   1.198 +var testbench = document.getElementById("testbench");
   1.199 +
   1.200 +function nextTest() {
   1.201 +  cursubst++;
   1.202 +  if (cursubst == nsubstitutions) {
   1.203 +    curpat++;
   1.204 +    cursubst = 0;
   1.205 +  }
   1.206 +  if (curpat == npatterns) {
   1.207 +    SimpleTest.finish();
   1.208 +    return;
   1.209 +  }
   1.210 +
   1.211 +  let css = subst(patterns[curpat].i, substitutions[cursubst]);
   1.212 +  let msg = quotemeta(subst(patterns[curpat].o, substitutions[cursubst]));
   1.213 +
   1.214 +  SimpleTest.expectConsoleMessages(function () { testbench.innerHTML = css },
   1.215 +                                   [{ errorMessage: new RegExp(msg) }],
   1.216 +                                   nextTest);
   1.217 +}
   1.218 +
   1.219 +SimpleTest.waitForExplicitFinish();
   1.220 +nextTest();
   1.221 +</script>
   1.222 +</body>
   1.223 +</html>

mercurial