tor-browser

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

identifiers-with-extended-unicode-escape.js (6068B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // Simple cases, not using eval.
      6 {
      7    let \u{61} = 123;
      8    assertEq(a, 123);
      9 
     10    let \u{6A} = 123;
     11    assertEq(j, 123);
     12 
     13    let a\u{62} = 456;
     14    assertEq(ab, 456);
     15 
     16    let \u{63}\u{6b} = 789;
     17    assertEq(ck, 789);
     18 }
     19 
     20 const leadingZeros = [0, 1, 2, 3, 4, 100].map(c => "0".repeat(c));
     21 
     22 
     23 // From DerivedCoreProperties.txt (Unicode 9):
     24 // Derived Property: ID_Start
     25 //  Characters that can start an identifier.
     26 //  Generated from:
     27 //      Lu + Ll + Lt + Lm + Lo + Nl
     28 //    + Other_ID_Start
     29 //    - Pattern_Syntax
     30 //    - Pattern_White_Space
     31 const idStart = [
     32    0x0041,     // LATIN CAPITAL LETTER A, Gc=Lu
     33    0x006A,     // LATIN SMALL LETTER J, Gc=Ll
     34    0x00C9,     // LATIN CAPITAL LETTER E WITH ACUTE, Gc=Lu
     35    0x00FF,     // LATIN SMALL LETTER Y WITH DIAERESIS, Gc=Ll
     36    0x01C5,     // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON, Gc=Lt
     37    0x0294,     // LATIN LETTER GLOTTAL STOP, Gc=Lo
     38    0x037A,     // GREEK YPOGEGRAMMENI, Gc=Lm
     39    0x16EE,     // RUNIC ARLAUG SYMBOL, Gc=Nl
     40    0xFF70,     // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK, Gc=Lm
     41 ];
     42 
     43 const idStartSupplemental = [
     44    0x10140,    // GREEK ACROPHONIC ATTIC ONE QUARTER, Gc=Nl
     45    0x10300,    // OLD ITALIC LETTER A, Gc=Lo
     46    0x10400,    // DESERET CAPITAL LETTER LONG I, Gc=Lu
     47    0x10430,    // DESERET SMALL LETTER SHORT A, Gc=Ll
     48    0x16B40,    // PAHAWH HMONG SIGN VOS SEEV, Gc=Lm
     49 ];
     50 
     51 // From PropList.txt (Unicode 9):
     52 const otherIdStart = [
     53    0x1885,     // MONGOLIAN LETTER ALI GALI BALUDA, Gc=Mn
     54    0x1886,     // MONGOLIAN LETTER ALI GALI THREE BALUDA, Gc=Mn
     55    0x2118,     // SCRIPT CAPITAL P, Gc=Sm
     56    0x212E,     // ESTIMATED SYMBOL, Gc=So
     57    0x309B,     // KATAKANA-HIRAGANA VOICED SOUND MARK, Gc=Sk
     58    0x309C,     // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK, Gc=Sk
     59 ];
     60 
     61 // From DerivedCoreProperties.txt (Unicode 9):
     62 // Derived Property: ID_Continue
     63 //  Characters that can continue an identifier.
     64 //  Generated from:
     65 //      ID_Start
     66 //    + Mn + Mc + Nd + Pc
     67 //    + Other_ID_Continue
     68 //    - Pattern_Syntax
     69 //    - Pattern_White_Space
     70 const idContinue = [
     71    0x0030,     // DIGIT ZERO, Gc=Nd
     72    0x0300,     // COMBINING GRAVE ACCENT, Gc=Mn
     73    0x0660,     // ARABIC-INDIC DIGIT ZERO, Gc=Nd
     74    0x0903,     // DEVANAGARI SIGN VISARGA, Gc=Mc
     75    0xFF10,     // FULLWIDTH DIGIT ZERO, Gc=Nd
     76    0xFF3F,     // FULLWIDTH LOW LINE, Gc=Pc
     77 ];
     78 
     79 const idContinueSupplemental = [
     80    0x101FD,    // PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE, Gc=Mn
     81    0x104A0,    // OSMANYA DIGIT ZERO, Gc=Nd
     82    0x11000,    // BRAHMI SIGN CANDRABINDU, Gc=Mc
     83 ];
     84 
     85 // From PropList.txt (Unicode 9):
     86 const otherIdContinue = [
     87    0x00B7,     // MIDDLE DOT, Gc=Po
     88    0x0387,     // GREEK ANO TELEIA, Gc=Po
     89    0x1369,     // ETHIOPIC DIGIT ONE, Gc=No
     90    0x136A,     // ETHIOPIC DIGIT TWO, Gc=No
     91    0x136B,     // ETHIOPIC DIGIT THREE, Gc=No
     92    0x136C,     // ETHIOPIC DIGIT FOUR, Gc=No
     93    0x136D,     // ETHIOPIC DIGIT FIVE, Gc=No
     94    0x136E,     // ETHIOPIC DIGIT SIX, Gc=No
     95    0x136F,     // ETHIOPIC DIGIT SEVEN, Gc=No
     96    0x1370,     // ETHIOPIC DIGIT EIGHT, Gc=No
     97    0x1371,     // ETHIOPIC DIGIT NINE, Gc=No
     98    0x19DA,     // NEW TAI LUE THAM DIGIT ONE, Gc=No
     99 ];
    100 
    101 for (let ident of [...idStart, ...otherIdStart, ...idStartSupplemental]) {
    102    for (let count of leadingZeros) {
    103        let zeros = "0".repeat(count);
    104        eval(`
    105            let \\u{${zeros}${ident.toString(16)}} = 123;
    106            assertEq(${String.fromCodePoint(ident)}, 123);
    107        `);
    108    }
    109 }
    110 
    111 for (let ident of [...idContinue, ...idContinueSupplemental, ...otherIdContinue]) {
    112    for (let zeros of leadingZeros) {
    113        assertThrowsInstanceOf(() => eval(`\\u{${zeros}${ident.toString(16)}}`), SyntaxError);
    114    }
    115 }
    116 
    117 for (let ident of [...idStart, ...otherIdStart, ...idContinue, ...otherIdContinue, ...idStartSupplemental, ...idContinueSupplemental]) {
    118    for (let zeros of leadingZeros) {
    119        eval(`
    120            let A\\u{${zeros}${ident.toString(16)}} = 123;
    121            assertEq(${String.fromCodePoint(0x41, ident)}, 123);
    122        `);
    123    }
    124 }
    125 
    126 
    127 const notIdentifiers = [
    128    0x0000,     // NULL, Gc=Cc
    129    0x000A,     // LINE FEED (LF), Gc=Cc
    130    0x005E,     // CIRCUMFLEX ACCENT, Gc=Sk
    131    0x00B1,     // PLUS-MINUS SIGN, Gc=Sm
    132    0xFF61,     // HALFWIDTH IDEOGRAPHIC FULL STOP, Gc=Po
    133    0x10061,    // Not assigned.
    134    0x10100,    // AEGEAN WORD SEPARATOR LINE, Gc=Po
    135    0x100061,   // <Plane 16 Private Use>, Gc=Co
    136 ];
    137 
    138 for (let ident of notIdentifiers) {
    139    for (let zeros of leadingZeros) {
    140        assertThrowsInstanceOf(() => eval(`\\u{${zeros}${ident.toString(16)}}`), SyntaxError);
    141    }
    142 }
    143 
    144 
    145 const incompleteEscapes = [
    146    "\\u{",
    147    "\\u{6",
    148    "\\u{61",
    149    "\\u{061",
    150    "\\u{0061",
    151    "\\u{00061",
    152    "\\u{000061",
    153    "\\u{0000061",
    154 
    155    "\\u}",
    156 ];
    157 for (let invalid of incompleteEscapes) {
    158    // Ends with EOF.
    159    assertThrowsInstanceOf(() => eval(invalid), SyntaxError);
    160 
    161    // Ends with EOL.
    162    assertThrowsInstanceOf(() => eval(invalid + "\n"), SyntaxError);
    163 
    164    // Ends with space.
    165    assertThrowsInstanceOf(() => eval(invalid + " "), SyntaxError);
    166 }
    167 
    168 
    169 const invalidEscapes = [
    170    // Empty escape.
    171    "",
    172 
    173    // Not hexadecimal characters.
    174    "\0",
    175    "G",
    176    "Z",
    177    "\uFFFF",
    178    "\uDBFF\uDFFF",
    179 
    180    // Has space characters.
    181    " 61",
    182    "61 ",
    183 
    184    // Has newline characters.
    185    "\n61",
    186    "61\n",
    187 
    188    // Exceeds 0x10FFFF, six characters.
    189    "110000",
    190    "110001",
    191    "fffffe",
    192    "ffffff",
    193 
    194    // Exceeds 0x10FFFF, more than six characters.
    195    "10ffff0",
    196    "10ffffabcdef",
    197 ];
    198 
    199 for (let invalid of invalidEscapes) {
    200    for (let zeros of leadingZeros) {
    201        assertThrowsInstanceOf(() => eval(`\\u{${zeros}${invalid}}`), SyntaxError);
    202        assertThrowsInstanceOf(() => eval(`var \\u{${zeros}${invalid}}`), SyntaxError);
    203    }
    204 }
    205 
    206 
    207 if (typeof reportCompare === "function")
    208    reportCompare(0, 0, "ok");