|
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 test = [ |
|
13 // 0: Valid surrogate pair |
|
14 ["%D8%35%DC%20%00%2D%00%2D", |
|
15 // expected: surrogate pair |
|
16 "\uD835\uDC20--"], |
|
17 // 1: Lone high surrogate |
|
18 ["%D8%35%00%2D%00%2D", |
|
19 // expected: one replacement char |
|
20 "\uFFFD--"], |
|
21 // 2: Lone low surrogate |
|
22 ["%DC%20%00%2D%00%2D", |
|
23 // expected: one replacement char |
|
24 "\uFFFD--"], |
|
25 // 3: Two high surrogates |
|
26 ["%D8%35%D8%35%00%2D%00%2D", |
|
27 // expected: two replacement chars |
|
28 "\uFFFD\uFFFD--"], |
|
29 // 4: Two low surrogates |
|
30 ["%DC%20%DC%20%00%2D%00%2D", |
|
31 // expected: two replacement chars |
|
32 "\uFFFD\uFFFD--"], |
|
33 // 5: Low surrogate followed by high surrogate |
|
34 ["%DC%20%D8%35%00%2D%00%2D", |
|
35 // expected: two replacement chars |
|
36 "\uFFFD\uFFFD--"], |
|
37 // 6: Lone high surrogate followed by valid surrogate pair |
|
38 ["%D8%35%D8%35%DC%20%00%2D%00%2D", |
|
39 // expected: replacement char followed by surrogate pair |
|
40 "\uFFFD\uD835\uDC20--"], |
|
41 // 7: Lone low surrogate followed by valid surrogate pair |
|
42 ["%DC%20%D8%35%DC%20%00%2D%00%2D", |
|
43 // expected: replacement char followed by surrogate pair |
|
44 "\uFFFD\uD835\uDC20--"], |
|
45 // 8: Valid surrogate pair followed by lone high surrogate |
|
46 ["%D8%35%DC%20%D8%35%00%2D%00%2D", |
|
47 // expected: surrogate pair followed by replacement char |
|
48 "\uD835\uDC20\uFFFD--"], |
|
49 // 9: Valid surrogate pair followed by lone low surrogate |
|
50 ["%D8%35%DC%20%DC%20%00%2D%00%2D", |
|
51 // expected: surrogate pair followed by replacement char |
|
52 "\uD835\uDC20\uFFFD--"], |
|
53 // 10: Lone high surrogate at the end of the input |
|
54 ["%D8%35%", |
|
55 // expected: nothing |
|
56 ""], |
|
57 // 11: Half code unit at the end of the input |
|
58 ["%D8", |
|
59 // expected: nothing |
|
60 ""]]; |
|
61 |
|
62 const IOService = Components.Constructor("@mozilla.org/network/io-service;1", |
|
63 "nsIIOService"); |
|
64 const ConverterInputStream = |
|
65 Components.Constructor("@mozilla.org/intl/converter-input-stream;1", |
|
66 "nsIConverterInputStream", |
|
67 "init"); |
|
68 const ios = new IOService(); |
|
69 |
|
70 function testCase(testText, expectedText, bufferLength, charset) |
|
71 { |
|
72 var dataURI = "data:text/plain;charset=" + charset + "," + testText; |
|
73 |
|
74 var channel = ios.newChannel(dataURI, "", null); |
|
75 var testInputStream = channel.open(); |
|
76 var testConverter = new ConverterInputStream(testInputStream, |
|
77 charset, |
|
78 bufferLength, |
|
79 0xFFFD); |
|
80 |
|
81 if (!(testConverter instanceof |
|
82 Components.interfaces.nsIUnicharLineInputStream)) |
|
83 throw "not line input stream"; |
|
84 |
|
85 var outStr = ""; |
|
86 var more; |
|
87 do { |
|
88 // read the line and check for eof |
|
89 var line = {}; |
|
90 more = testConverter.readLine(line); |
|
91 outStr += line.value; |
|
92 } while (more); |
|
93 |
|
94 // escape the strings before comparing for better readability |
|
95 do_check_eq(escape(outStr), escape(expectedText)); |
|
96 } |
|
97 |
|
98 // Add 32 dummy characters to the test text to work around the minimum buffer |
|
99 // size of an ns*Buffer |
|
100 const MINIMUM_BUFFER_SIZE=32; |
|
101 function padBytes(str) |
|
102 { |
|
103 var padding = ""; |
|
104 for (var i = 0; i < MINIMUM_BUFFER_SIZE; ++i) { |
|
105 padding += "%00%2D"; |
|
106 } |
|
107 return padding + str; |
|
108 } |
|
109 |
|
110 function padUnichars(str) |
|
111 { |
|
112 var padding = ""; |
|
113 for (var i = 0; i < MINIMUM_BUFFER_SIZE; ++i) { |
|
114 padding += "-"; |
|
115 } |
|
116 return padding + str; |
|
117 } |
|
118 |
|
119 // Byte-swap %-encoded utf-16 |
|
120 function flip(str) { return str.replace(/(%..)(%..)/g, "$2$1"); } |
|
121 |
|
122 function run_test() |
|
123 { |
|
124 for (var i = 0; i < 12; ++i) { |
|
125 for (var bufferLength = MINIMUM_BUFFER_SIZE; |
|
126 bufferLength < MINIMUM_BUFFER_SIZE + 4; |
|
127 ++ bufferLength) { |
|
128 var testText = padBytes(test[i][0]); |
|
129 var expectedText = padUnichars(test[i][1]); |
|
130 testCase(testText, expectedText, bufferLength, "UTF-16BE"); |
|
131 testCase(flip(testText), expectedText, bufferLength, "UTF-16LE"); |
|
132 } |
|
133 } |
|
134 } |