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 }