tor-browser

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

well-formed.js (3921B)


      1 // |reftest| skip-if(!xulRuntime.shell)
      2 function IsLatin1String(str) {
      3  for (var i = 0; i < str.length; ++i) {
      4    if (str.charCodeAt(i) > 0xff) {
      5      return false;
      6    }
      7  }
      8  return true;
      9 }
     10 
     11 function IsTwoByteString(str) {
     12  return !IsLatin1String(str);
     13 }
     14 
     15 const latin1Strings = [
     16  // Empty string.
     17  "",
     18 
     19  // Single character string.
     20  "a",
     21  "\0",
     22  "\u{80}",
     23  "\u{ff}",
     24 
     25  // Inline strings.
     26  "ascii",
     27  "látïñ-¹",
     28 
     29  // Too large for inline string storage.
     30  "This is an ASCII string which is too large for inline storage",
     31  "This is a látïñ-¹ string which is too large for inline storage",
     32 ];
     33 
     34 assertEq(latin1Strings.every(IsLatin1String), true);
     35 
     36 const twoByteStrings = [
     37  // Single code point string.
     38  "\u{100}",
     39  "\u{10ffff}",
     40 
     41  // Leading two-byte character.
     42  ...latin1Strings.map(s => "\u{100}" + s),
     43 
     44  // Trailing two-byte character.
     45  ...latin1Strings.map(s => s + "\u{100}"),
     46 
     47  // Interspersed two-byte character.
     48  ...latin1Strings.map(s => s + "\u{100}" + "-"),
     49  ...latin1Strings.map(s => "-" + "\u{100}" + s),
     50 ];
     51 
     52 assertEq(twoByteStrings.every(IsTwoByteString), true);
     53 
     54 const unpairedSurrogates = [
     55  // LeadSurrogateMin and LeadSurrogateMax
     56  "\u{D800}",
     57  "\u{DBFF}",
     58 
     59  // TrailSurrogateMin and TrailSurrogateMax
     60  "\u{DC00}",
     61  "\u{DFFF}",
     62 ];
     63 
     64 const strings = [
     65  ...latin1Strings,
     66  ...twoByteStrings,
     67 
     68  // In case we've missed some special cases above.
     69  // (Assumes it doesn't return a string with unpaired surrogates.)
     70  ...representativeStringArray(),
     71 ];
     72 
     73 function toRope(string) {
     74  try {
     75    let rope = newRope(string[0], string.slice(1));
     76    return {rope, filler: ""};
     77  } catch {}
     78 
     79  // |newRope| fails if the input is too short. Add some characters to make
     80  // the input large enough.
     81  let filler = "012345678901234567890123456789";
     82  let rope = newRope(string, filler);
     83  return {rope, filler};
     84 }
     85 
     86 for (let string of strings) {
     87  assertEq(string.isWellFormed(), true);
     88  assertEq(string.toWellFormed(), string);
     89 
     90  // Need at least two characters to make a rope.
     91  if (string.length >= 2) {
     92    let {rope, filler} = toRope(string);
     93    assertEq(rope.isWellFormed(), true);
     94    assertEq(rope.toWellFormed(), string + filler);
     95  }
     96 
     97  // Copy the string to create a non-atom string. (Unless |string| is a static string.)
     98  let copy = newString(string);
     99  assertEq(copy.isWellFormed(), true);
    100  assertEq(copy.toWellFormed(), string);
    101 
    102  let twoByte = newString(string, {twoByte: true});
    103  assertEq(twoByte.isWellFormed(), true);
    104  assertEq(twoByte.toWellFormed(), string);
    105 }
    106 
    107 // Single unpaired surrogates.
    108 for (let unpaired of unpairedSurrogates) {
    109  assertEq(unpaired.isWellFormed(), false);
    110  assertEq(unpaired.toWellFormed(), "\u{FFFD}");
    111 }
    112 
    113 // Add unpaired surrogates.
    114 for (let unpaired of unpairedSurrogates.flatMap(unpaired => {
    115  return [
    116    // Single unpaired.
    117    unpaired,
    118 
    119    // Two consecutive unpaired.
    120    unpaired + unpaired,
    121 
    122    // Two separate unpaired.
    123    unpaired + "-" + unpaired
    124  ];
    125 })) {
    126  for (let string of strings.flatMap(string => {
    127    return [
    128      // Leading unpaired.
    129      unpaired + string,
    130 
    131      // Trailing unpaired.
    132      string + unpaired,
    133 
    134      // Interspersed unpaired.
    135      string + unpaired + "-",
    136      "-" + unpaired + string,
    137      string + unpaired + string,
    138    ];
    139  })) {
    140    assertEq(string.isWellFormed(), false);
    141    assertEq(string.toWellFormed() === string, false);
    142 
    143    // Need at least two characters to make a rope.
    144    if (string.length >= 2) {
    145      let {rope, filler} = toRope(string);
    146      assertEq(rope.isWellFormed(), false);
    147      assertEq(rope.toWellFormed() === string + filler, false);
    148    }
    149 
    150    // Copy the string to create a non-atom string. (Unless |string| is a static string.)
    151    let copy = newString(string);
    152    assertEq(copy.isWellFormed(), false);
    153    assertEq(copy.toWellFormed() === string, false);
    154  }
    155 }
    156 
    157 if (typeof reportCompare === "function")
    158  reportCompare(true, true);