tor-browser

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

test_bug317216.js (4208B)


      1 /* Test case for bug 317216
      2 *
      3 * Uses nsIConverterInputStream to decode UTF-16 text with valid surrogate
      4 * pairs and lone surrogate characters
      5 *
      6 * Sample text is: "A" in Mathematical Bold Capitals (U+1D400)
      7 *
      8 * The test uses buffers of 4 different lengths to test end of buffer in mid-
      9 * UTF16 character and mid-surrogate pair
     10 */
     11 
     12 const { NetUtil } = ChromeUtils.importESModule(
     13  "resource://gre/modules/NetUtil.sys.mjs"
     14 );
     15 
     16 const test = [
     17  // 0: Valid surrogate pair
     18  [
     19    "%D8%35%DC%20%00%2D%00%2D",
     20    //    expected: surrogate pair
     21    "\uD835\uDC20--",
     22  ],
     23  // 1: Lone high surrogate
     24  [
     25    "%D8%35%00%2D%00%2D",
     26    //    expected: one replacement char
     27    "\uFFFD--",
     28  ],
     29  // 2: Lone low surrogate
     30  [
     31    "%DC%20%00%2D%00%2D",
     32    //    expected: one replacement char
     33    "\uFFFD--",
     34  ],
     35  // 3: Two high surrogates
     36  [
     37    "%D8%35%D8%35%00%2D%00%2D",
     38    //    expected: two replacement chars
     39    "\uFFFD\uFFFD--",
     40  ],
     41  // 4: Two low surrogates
     42  [
     43    "%DC%20%DC%20%00%2D%00%2D",
     44    //    expected: two replacement chars
     45    "\uFFFD\uFFFD--",
     46  ],
     47  // 5: Low surrogate followed by high surrogate
     48  [
     49    "%DC%20%D8%35%00%2D%00%2D",
     50    //    expected: two replacement chars
     51    "\uFFFD\uFFFD--",
     52  ],
     53  // 6: Lone high surrogate followed by valid surrogate pair
     54  [
     55    "%D8%35%D8%35%DC%20%00%2D%00%2D",
     56    //    expected: replacement char followed by surrogate pair
     57    "\uFFFD\uD835\uDC20--",
     58  ],
     59  // 7: Lone low surrogate followed by valid surrogate pair
     60  [
     61    "%DC%20%D8%35%DC%20%00%2D%00%2D",
     62    //    expected: replacement char followed by surrogate pair
     63    "\uFFFD\uD835\uDC20--",
     64  ],
     65  // 8: Valid surrogate pair followed by lone high surrogate
     66  [
     67    "%D8%35%DC%20%D8%35%00%2D%00%2D",
     68    //    expected: surrogate pair followed by replacement char
     69    "\uD835\uDC20\uFFFD--",
     70  ],
     71  // 9: Valid surrogate pair followed by lone low surrogate
     72  [
     73    "%D8%35%DC%20%DC%20%00%2D%00%2D",
     74    //    expected: surrogate pair followed by replacement char
     75    "\uD835\uDC20\uFFFD--",
     76  ],
     77  // 10: Lone high surrogate at the end of the input
     78  [
     79    "%D8%35%",
     80    //    expected: one replacement char
     81    "\uFFFD",
     82  ],
     83  // 11: Half code unit at the end of the input
     84  [
     85    "%D8",
     86    //    expected: one replacement char
     87    "\uFFFD",
     88  ],
     89 ];
     90 
     91 const ConverterInputStream = Components.Constructor(
     92  "@mozilla.org/intl/converter-input-stream;1",
     93  "nsIConverterInputStream",
     94  "init"
     95 );
     96 
     97 function testCase(testText, expectedText, bufferLength, charset) {
     98  var dataURI = "data:text/plain;charset=" + charset + "," + testText;
     99  var channel = NetUtil.newChannel({
    100    uri: dataURI,
    101    loadUsingSystemPrincipal: true,
    102  });
    103  var testInputStream = channel.open();
    104  var testConverter = new ConverterInputStream(
    105    testInputStream,
    106    charset,
    107    bufferLength,
    108    0xfffd
    109  );
    110 
    111  if (!(testConverter instanceof Ci.nsIUnicharLineInputStream)) {
    112    throw new Error("not line input stream");
    113  }
    114 
    115  var outStr = "";
    116  var more;
    117  do {
    118    // read the line and check for eof
    119    var line = {};
    120    more = testConverter.readLine(line);
    121    outStr += line.value;
    122  } while (more);
    123 
    124  // escape the strings before comparing for better readability
    125  Assert.equal(escape(outStr), escape(expectedText));
    126 }
    127 
    128 // Add 32 dummy characters to the test text to work around the minimum buffer
    129 // size of an ns*Buffer
    130 const MINIMUM_BUFFER_SIZE = 32;
    131 function padBytes(str) {
    132  var padding = "";
    133  for (var i = 0; i < MINIMUM_BUFFER_SIZE; ++i) {
    134    padding += "%00%2D";
    135  }
    136  return padding + str;
    137 }
    138 
    139 function padUnichars(str) {
    140  var padding = "";
    141  for (var i = 0; i < MINIMUM_BUFFER_SIZE; ++i) {
    142    padding += "-";
    143  }
    144  return padding + str;
    145 }
    146 
    147 // Byte-swap %-encoded utf-16
    148 function flip(str) {
    149  return str.replace(/(%..)(%..)/g, "$2$1");
    150 }
    151 
    152 function run_test() {
    153  for (var i = 0; i < 12; ++i) {
    154    for (
    155      var bufferLength = MINIMUM_BUFFER_SIZE;
    156      bufferLength < MINIMUM_BUFFER_SIZE + 4;
    157      ++bufferLength
    158    ) {
    159      var testText = padBytes(test[i][0]);
    160      var expectedText = padUnichars(test[i][1]);
    161      testCase(testText, expectedText, bufferLength, "UTF-16BE");
    162      testCase(flip(testText), expectedText, bufferLength, "UTF-16LE");
    163    }
    164  }
    165 }