Bug 655658 - NetUtil.readInputStreamToString should have aCharset argument as optional. r=sdwilsh, sr=bz

This commit is contained in:
Makoto Kato 2011-11-25 11:23:41 +09:00
parent f9ccb9e0ae
commit e999cc59bc
4 changed files with 94 additions and 1 deletions

View File

@ -45,6 +45,7 @@
#include "nsNetError.h"
#include "mozStorage.h"
#include "nsPluginError.h"
#include "nsIUnicodeDecoder.h"
/***************************************************************************/
/* Quick and dirty mapping of well known result codes to strings. We only

View File

@ -222,3 +222,5 @@ XPC_MSG_DEF(NS_ERROR_STORAGE_CONSTRAINT , "SQLite database operation
/* plugin related codes (from nsPluginError.h) */
XPC_MSG_DEF(NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, "Clearing site data by time range not supported by plugin")
/* character converter related codes (from nsIUnicodeDecoder.h) */
XPC_MSG_DEF(NS_ERROR_ILLEGAL_INPUT , "The input characters have illegal sequences")

View File

@ -274,6 +274,12 @@ const NetUtil = {
* The input stream to read from.
* @param aCount
* The number of bytes to read from the stream.
* @param aOptions [optional]
* charset
* The character encoding of stream data.
* replacement
* The character to replace unknown byte sequences.
* If unset, it causes an exceptions to be thrown.
*
* @return the bytes from the input stream in string form.
*
@ -282,9 +288,11 @@ const NetUtil = {
* block the calling thread (non-blocking mode only).
* @throws NS_ERROR_FAILURE if there are not enough bytes available to read
* aCount amount of data.
* @throws NS_ERROR_ILLEGAL_INPUT if aInputStream has invalid sequences
*/
readInputStreamToString: function NetUtil_readInputStreamToString(aInputStream,
aCount)
aCount,
aOptions)
{
if (!(aInputStream instanceof Ci.nsIInputStream)) {
let exception = new Components.Exception(
@ -304,6 +312,33 @@ const NetUtil = {
throw exception;
}
if (aOptions && "charset" in aOptions) {
let cis = Cc["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Ci.nsIConverterInputStream);
try {
// When replacement is set, the character that is unknown sequence
// replaces with aOptions.replacement character.
if (!("replacement" in aOptions)) {
// aOptions.replacement isn't set.
// If input stream has unknown sequences for aOptions.charset,
// throw NS_ERROR_ILLEGAL_INPUT.
aOptions.replacement = 0;
}
cis.init(aInputStream, aOptions.charset, aCount,
aOptions.replacement);
let str = {};
cis.readString(-1, str);
cis.close();
return str.value;
}
catch (e) {
// Adjust the stack so it throws at the caller's location.
throw new Components.Exception(e.message, e.result,
Components.stack.caller, e.data);
}
}
let sis = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
sis.init(aInputStream);

View File

@ -536,6 +536,59 @@ function test_readInputStreamToString_too_many_bytes()
run_next_test();
}
function test_readInputStreamToString_with_charset()
{
const TEST_DATA = "\uff10\uff11\uff12\uff13";
const TEST_DATA_UTF8 = "\xef\xbc\x90\xef\xbc\x91\xef\xbc\x92\xef\xbc\x93";
const TEST_DATA_SJIS = "\x82\x4f\x82\x50\x82\x51\x82\x52";
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
do_check_eq(NetUtil.readInputStreamToString(istream,
TEST_DATA_UTF8.length,
{ charset: "UTF-8"}),
TEST_DATA);
istream.setData(TEST_DATA_SJIS, TEST_DATA_SJIS.length);
do_check_eq(NetUtil.readInputStreamToString(istream,
TEST_DATA_SJIS.length,
{ charset: "Shift_JIS"}),
TEST_DATA);
run_next_test();
}
function test_readInputStreamToString_invalid_sequence()
{
const TEST_DATA = "\ufffd\ufffd\ufffd\ufffd";
const TEST_DATA_UTF8 = "\xaa\xaa\xaa\xaa";
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
try {
NetUtil.readInputStreamToString(istream,
TEST_DATA_UTF8.length,
{ charset: "UTF-8" });
do_throw("should throw!");
} catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_INPUT);
}
istream.setData(TEST_DATA_UTF8, TEST_DATA_UTF8.length);
do_check_eq(NetUtil.readInputStreamToString(istream,
TEST_DATA_UTF8.length, {
charset: "UTF-8",
replacement: Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER}),
TEST_DATA);
run_next_test();
}
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
@ -565,6 +618,8 @@ function test_readInputStreamToString_too_many_bytes()
test_readInputStreamToString_no_bytes_arg,
test_readInputStreamToString_blocking_stream,
test_readInputStreamToString_too_many_bytes,
test_readInputStreamToString_with_charset,
test_readInputStreamToString_invalid_sequence,
].forEach(add_test);
let index = 0;