layout/style/test/test_parser_diagnostics_unprintables.html

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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

mercurial