summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js')
-rw-r--r--js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js208
1 files changed, 208 insertions, 0 deletions
diff --git a/js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js b/js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js
new file mode 100644
index 0000000000..e4b5f46029
--- /dev/null
+++ b/js/src/tests/non262/syntax/identifiers-with-extended-unicode-escape.js
@@ -0,0 +1,208 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Simple cases, not using eval.
+{
+ let \u{61} = 123;
+ assertEq(a, 123);
+
+ let \u{6A} = 123;
+ assertEq(j, 123);
+
+ let a\u{62} = 456;
+ assertEq(ab, 456);
+
+ let \u{63}\u{6b} = 789;
+ assertEq(ck, 789);
+}
+
+const leadingZeros = [0, 1, 2, 3, 4, 100].map(c => "0".repeat(c));
+
+
+// From DerivedCoreProperties.txt (Unicode 9):
+// Derived Property: ID_Start
+// Characters that can start an identifier.
+// Generated from:
+// Lu + Ll + Lt + Lm + Lo + Nl
+// + Other_ID_Start
+// - Pattern_Syntax
+// - Pattern_White_Space
+const idStart = [
+ 0x0041, // LATIN CAPITAL LETTER A, Gc=Lu
+ 0x006A, // LATIN SMALL LETTER J, Gc=Ll
+ 0x00C9, // LATIN CAPITAL LETTER E WITH ACUTE, Gc=Lu
+ 0x00FF, // LATIN SMALL LETTER Y WITH DIAERESIS, Gc=Ll
+ 0x01C5, // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON, Gc=Lt
+ 0x0294, // LATIN LETTER GLOTTAL STOP, Gc=Lo
+ 0x037A, // GREEK YPOGEGRAMMENI, Gc=Lm
+ 0x16EE, // RUNIC ARLAUG SYMBOL, Gc=Nl
+ 0xFF70, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK, Gc=Lm
+];
+
+const idStartSupplemental = [
+ 0x10140, // GREEK ACROPHONIC ATTIC ONE QUARTER, Gc=Nl
+ 0x10300, // OLD ITALIC LETTER A, Gc=Lo
+ 0x10400, // DESERET CAPITAL LETTER LONG I, Gc=Lu
+ 0x10430, // DESERET SMALL LETTER SHORT A, Gc=Ll
+ 0x16B40, // PAHAWH HMONG SIGN VOS SEEV, Gc=Lm
+];
+
+// From PropList.txt (Unicode 9):
+const otherIdStart = [
+ 0x1885, // MONGOLIAN LETTER ALI GALI BALUDA, Gc=Mn
+ 0x1886, // MONGOLIAN LETTER ALI GALI THREE BALUDA, Gc=Mn
+ 0x2118, // SCRIPT CAPITAL P, Gc=Sm
+ 0x212E, // ESTIMATED SYMBOL, Gc=So
+ 0x309B, // KATAKANA-HIRAGANA VOICED SOUND MARK, Gc=Sk
+ 0x309C, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK, Gc=Sk
+];
+
+// From DerivedCoreProperties.txt (Unicode 9):
+// Derived Property: ID_Continue
+// Characters that can continue an identifier.
+// Generated from:
+// ID_Start
+// + Mn + Mc + Nd + Pc
+// + Other_ID_Continue
+// - Pattern_Syntax
+// - Pattern_White_Space
+const idContinue = [
+ 0x0030, // DIGIT ZERO, Gc=Nd
+ 0x0300, // COMBINING GRAVE ACCENT, Gc=Mn
+ 0x0660, // ARABIC-INDIC DIGIT ZERO, Gc=Nd
+ 0x0903, // DEVANAGARI SIGN VISARGA, Gc=Mc
+ 0xFF10, // FULLWIDTH DIGIT ZERO, Gc=Nd
+ 0xFF3F, // FULLWIDTH LOW LINE, Gc=Pc
+];
+
+const idContinueSupplemental = [
+ 0x101FD, // PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, Gc=Mn
+ 0x104A0, // OSMANYA DIGIT ZERO, Gc=Nd
+ 0x11000, // BRAHMI SIGN CANDRABINDU, Gc=Mc
+];
+
+// From PropList.txt (Unicode 9):
+const otherIdContinue = [
+ 0x00B7, // MIDDLE DOT, Gc=Po
+ 0x0387, // GREEK ANO TELEIA, Gc=Po
+ 0x1369, // ETHIOPIC DIGIT ONE, Gc=No
+ 0x136A, // ETHIOPIC DIGIT TWO, Gc=No
+ 0x136B, // ETHIOPIC DIGIT THREE, Gc=No
+ 0x136C, // ETHIOPIC DIGIT FOUR, Gc=No
+ 0x136D, // ETHIOPIC DIGIT FIVE, Gc=No
+ 0x136E, // ETHIOPIC DIGIT SIX, Gc=No
+ 0x136F, // ETHIOPIC DIGIT SEVEN, Gc=No
+ 0x1370, // ETHIOPIC DIGIT EIGHT, Gc=No
+ 0x1371, // ETHIOPIC DIGIT NINE, Gc=No
+ 0x19DA, // NEW TAI LUE THAM DIGIT ONE, Gc=No
+];
+
+for (let ident of [...idStart, ...otherIdStart, ...idStartSupplemental]) {
+ for (let count of leadingZeros) {
+ let zeros = "0".repeat(count);
+ eval(`
+ let \\u{${zeros}${ident.toString(16)}} = 123;
+ assertEq(${String.fromCodePoint(ident)}, 123);
+ `);
+ }
+}
+
+for (let ident of [...idContinue, ...idContinueSupplemental, ...otherIdContinue]) {
+ for (let zeros of leadingZeros) {
+ assertThrowsInstanceOf(() => eval(`\\u{${zeros}${ident.toString(16)}}`), SyntaxError);
+ }
+}
+
+for (let ident of [...idStart, ...otherIdStart, ...idContinue, ...otherIdContinue, ...idStartSupplemental, ...idContinueSupplemental]) {
+ for (let zeros of leadingZeros) {
+ eval(`
+ let A\\u{${zeros}${ident.toString(16)}} = 123;
+ assertEq(${String.fromCodePoint(0x41, ident)}, 123);
+ `);
+ }
+}
+
+
+const notIdentifiers = [
+ 0x0000, // NULL, Gc=Cc
+ 0x000A, // LINE FEED (LF), Gc=Cc
+ 0x005E, // CIRCUMFLEX ACCENT, Gc=Sk
+ 0x00B1, // PLUS-MINUS SIGN, Gc=Sm
+ 0xFF61, // HALFWIDTH IDEOGRAPHIC FULL STOP, Gc=Po
+ 0x10061, // Not assigned.
+ 0x10100, // AEGEAN WORD SEPARATOR LINE, Gc=Po
+ 0x100061, // <Plane 16 Private Use>, Gc=Co
+];
+
+for (let ident of notIdentifiers) {
+ for (let zeros of leadingZeros) {
+ assertThrowsInstanceOf(() => eval(`\\u{${zeros}${ident.toString(16)}}`), SyntaxError);
+ }
+}
+
+
+const incompleteEscapes = [
+ "\\u{",
+ "\\u{6",
+ "\\u{61",
+ "\\u{061",
+ "\\u{0061",
+ "\\u{00061",
+ "\\u{000061",
+ "\\u{0000061",
+
+ "\\u}",
+];
+for (let invalid of incompleteEscapes) {
+ // Ends with EOF.
+ assertThrowsInstanceOf(() => eval(invalid), SyntaxError);
+
+ // Ends with EOL.
+ assertThrowsInstanceOf(() => eval(invalid + "\n"), SyntaxError);
+
+ // Ends with space.
+ assertThrowsInstanceOf(() => eval(invalid + " "), SyntaxError);
+}
+
+
+const invalidEscapes = [
+ // Empty escape.
+ "",
+
+ // Not hexadecimal characters.
+ "\0",
+ "G",
+ "Z",
+ "\uFFFF",
+ "\uDBFF\uDFFF",
+
+ // Has space characters.
+ " 61",
+ "61 ",
+
+ // Has newline characters.
+ "\n61",
+ "61\n",
+
+ // Exceeds 0x10FFFF, six characters.
+ "110000",
+ "110001",
+ "fffffe",
+ "ffffff",
+
+ // Exceeds 0x10FFFF, more than six characters.
+ "10ffff0",
+ "10ffffabcdef",
+];
+
+for (let invalid of invalidEscapes) {
+ for (let zeros of leadingZeros) {
+ assertThrowsInstanceOf(() => eval(`\\u{${zeros}${invalid}}`), SyntaxError);
+ assertThrowsInstanceOf(() => eval(`var \\u{${zeros}${invalid}}`), SyntaxError);
+ }
+}
+
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0, "ok");