michael@0: // Tests illegal UTF-8 sequences michael@0: michael@0: const Cc = Components.Constructor; michael@0: const Ci = Components.interfaces; michael@0: michael@0: const tests = [ michael@0: { inStrings: ["%80", // Illegal or incomplete sequences michael@0: "%8f", michael@0: "%90", michael@0: "%9f", michael@0: "%a0", michael@0: "%bf", michael@0: "%c0", michael@0: "%c1", michael@0: "%c2", michael@0: "%df", michael@0: "%e0", michael@0: "%e0%a0", michael@0: "%e0%bf", michael@0: "%ed%80", michael@0: "%ed%9f", michael@0: "%ef", michael@0: "%ef%bf", michael@0: "%f0", michael@0: "%f0%90", michael@0: "%f0%90%80", michael@0: "%f0%90%bf", michael@0: "%f0%bf", michael@0: "%f0%bf%80", michael@0: "%f0%bf%bf", michael@0: "%f4", michael@0: "%f4%80", michael@0: "%f4%80%80", michael@0: "%f4%80%bf", michael@0: "%f4%8f", michael@0: "%f4%8f%80", michael@0: "%f4%8f%bf", michael@0: "%f5", michael@0: "%f7", michael@0: "%f8", michael@0: "%fb", michael@0: "%fc", michael@0: "%fd"], michael@0: expected: "ABC\ufffdXYZ" }, michael@0: michael@0: { inStrings: ["%c0%af", // Illegal bytes in 2-octet michael@0: "%c1%af"], // sequences michael@0: expected: "ABC\ufffd\ufffdXYZ" }, michael@0: michael@0: { inStrings: ["%e0%80%80", // Illegal bytes in 3-octet michael@0: "%e0%80%af", // sequences michael@0: "%e0%9f%bf", michael@0: // long surrogates michael@0: "%ed%a0%80", // D800 michael@0: "%ed%ad%bf", // DB7F michael@0: "%ed%ae%80", // DB80 michael@0: "%ed%af%bf", // DBFF michael@0: "%ed%b0%80", // DC00 michael@0: "%ed%be%80", // DF80 michael@0: "%ed%bf%bf"], // DFFF michael@0: expected: "ABC\ufffd\ufffd\ufffdXYZ" }, michael@0: michael@0: { inStrings: ["%f0%80%80%80", // Illegal bytes in 4-octet michael@0: "%f0%80%80%af", // sequences michael@0: "%f0%8f%bf%bf", michael@0: "%f4%90%80%80", michael@0: "%f4%bf%bf%bf", michael@0: "%f5%80%80%80", michael@0: "%f7%bf%bf%bf"], michael@0: expected: "ABC\ufffd\ufffd\ufffd\ufffdXYZ" }, michael@0: michael@0: { inStrings: ["%f8%80%80%80%80", // Illegal bytes in 5-octet michael@0: "%f8%80%80%80%af", // sequences michael@0: "%fb%bf%bf%bf%bf"], michael@0: expected: "ABC\ufffd\ufffd\ufffd\ufffd\ufffdXYZ" }, michael@0: michael@0: // Surrogate pairs michael@0: { inStrings: ["%ed%a0%80%ed%b0%80", // D800 DC00 michael@0: "%ed%a0%80%ed%bf%bf", // D800 DFFF michael@0: "%ed%ad%bf%ed%b0%80", // DB7F DC00 michael@0: "%ed%ad%bf%ed%bf%bf", // DB7F DFFF michael@0: "%ed%ae%80%ed%b0%80", // DB80 DC00 michael@0: "%ed%ae%80%ed%bf%bf", // DB80 DFFF michael@0: "%ed%af%bf%ed%b0%80", // DBFF DC00 michael@0: "%ed%ad%bf%ed%bf%bf", // DBFF DFFF michael@0: "%fc%80%80%80%80%80", // Illegal bytes in 6-octet michael@0: "%fc%80%80%80%80%af", // sequences michael@0: "%fd%bf%bf%bf%bf%bf"], michael@0: expected: "ABC\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdXYZ" }, michael@0: ]; michael@0: michael@0: michael@0: function testCaseInputStream(inStr, expected) michael@0: { michael@0: var dataURI = "data:text/plain; charset=UTF-8,ABC" + inStr + "XYZ" michael@0: dump(inStr + "==>"); michael@0: michael@0: var IOService = Cc("@mozilla.org/network/io-service;1", michael@0: "nsIIOService"); michael@0: var ConverterInputStream = michael@0: Cc("@mozilla.org/intl/converter-input-stream;1", michael@0: "nsIConverterInputStream", michael@0: "init"); michael@0: michael@0: var ios = new IOService(); michael@0: var channel = ios.newChannel(dataURI, "", null); michael@0: var testInputStream = channel.open(); michael@0: var testConverter = new ConverterInputStream(testInputStream, michael@0: "UTF-8", michael@0: 16, michael@0: 0xFFFD); michael@0: michael@0: if (!(testConverter instanceof Ci.nsIUnicharLineInputStream)) michael@0: throw "not line input stream"; michael@0: michael@0: var outStr = ""; michael@0: var more; michael@0: do { michael@0: // read the line and check for eof michael@0: var line = {}; michael@0: more = testConverter.readLine(line); michael@0: outStr += line.value; michael@0: } while (more); michael@0: michael@0: dump(outStr + "; expected=" + expected + "\n"); michael@0: do_check_eq(outStr, expected); michael@0: do_check_eq(outStr.length, expected.length); michael@0: } michael@0: michael@0: function run_test() { michael@0: for (var t of tests) { michael@0: for (var inStr of t.inStrings) { michael@0: testCaseInputStream(inStr, t.expected); michael@0: } michael@0: } michael@0: }