aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/bindings/error.rs51
-rw-r--r--components/script/dom/textdecoder.rs19
-rw-r--r--components/script/dom/textencoder.rs8
-rw-r--r--tests/wpt/metadata/MANIFEST.json4
-rw-r--r--tests/wpt/metadata/encoding/api-replacement-encodings.html.ini16
-rw-r--r--tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini106
-rw-r--r--tests/wpt/web-platform-tests/encoding/api-invalid-label.html14
7 files changed, 78 insertions, 140 deletions
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index 426bff64d95..181d02f0353 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -12,7 +12,7 @@ use util::str::DOMString;
use js::jsapi::{JSContext, JSBool, JSObject};
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException, JS_ReportPendingException};
-use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR};
+use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR, JSEXN_RANGEERR};
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
use js::glue::{ReportError};
use js::rust::with_compartment;
@@ -59,6 +59,8 @@ pub enum Error {
/// TypeError JavaScript Error
Type(DOMString),
+ /// RangeError JavaScript Error
+ Range(DOMString),
/// A JavaScript exception is already pending.
JSFailed,
@@ -95,7 +97,12 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef,
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
throw_type_error(cx, &message);
return;
- }
+ },
+ Error::Range(message) => {
+ assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
+ throw_range_error(cx, &message);
+ return;
+ },
Error::JSFailed => {
assert!(unsafe { JS_IsExceptionPending(cx) } == 1);
return;
@@ -135,7 +142,7 @@ pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
return 0;
}
-/// Format string used to throw `TypeError`s.
+/// Format string used to throw javascript errors.
static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [
'{' as libc::c_char,
'0' as libc::c_char,
@@ -144,29 +151,53 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [
];
/// Format string struct used to throw `TypeError`s.
-static mut ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
+static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
argCount: 1,
exnType: JSEXN_TYPEERR as i16,
};
-/// Callback used to throw `TypeError`s.
+/// Format string struct used to throw `RangeError`s.
+static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString {
+ format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char,
+ argCount: 1,
+ exnType: JSEXN_RANGEERR as i16,
+};
+
+/// Callback used to throw javascript errors.
+/// See throw_js_error for info about error_number.
unsafe extern fn get_error_message(_user_ref: *mut libc::c_void,
_locale: *const libc::c_char,
error_number: libc::c_uint) -> *const JSErrorFormatString
{
- assert_eq!(error_number, 0);
- &ERROR_FORMAT_STRING as *const JSErrorFormatString
+ match error_number as i32 {
+ JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
+ JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString,
+ _ => panic!("Bad js error number given to get_error_message: {}", error_number)
+ }
}
-/// Throw a `TypeError` with the given message.
-pub fn throw_type_error(cx: *mut JSContext, error: &str) {
+/// Helper fn to throw a javascript error with the given message and number.
+/// Reuse the jsapi error codes to distinguish the error_number
+/// passed back to the get_error_message callback.
+/// c_uint is u32, so this cast is safe, as is casting to/from i32 from there.
+fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) {
let error = CString::new(error).unwrap();
unsafe {
JS_ReportErrorNumber(cx,
Some(get_error_message as
unsafe extern "C" fn(*mut libc::c_void, *const libc::c_char,
libc::c_uint) -> *const JSErrorFormatString),
- ptr::null_mut(), 0, error.as_ptr());
+ ptr::null_mut(), error_number, error.as_ptr());
}
}
+
+/// Throw a `TypeError` with the given message.
+pub fn throw_type_error(cx: *mut JSContext, error: &str) {
+ throw_js_error(cx, error, JSEXN_TYPEERR as u32);
+}
+
+/// Throw a `RangeError` with the given message.
+pub fn throw_range_error(cx: *mut JSContext, error: &str) {
+ throw_js_error(cx, error, JSEXN_RANGEERR as u32);
+}
diff --git a/components/script/dom/textdecoder.rs b/components/script/dom/textdecoder.rs
index 714200f9a8f..4b3333234a3 100644
--- a/components/script/dom/textdecoder.rs
+++ b/components/script/dom/textdecoder.rs
@@ -39,6 +39,10 @@ impl TextDecoder {
}
}
+ fn make_range_error() -> Fallible<Temporary<TextDecoder>> {
+ Err(Error::Range("The given encoding is not supported.".to_owned()))
+ }
+
pub fn new(global: GlobalRef, encoding: EncodingRef, fatal: bool) -> Temporary<TextDecoder> {
reflect_dom_object(box TextDecoder::new_inherited(encoding, fatal),
global,
@@ -51,14 +55,23 @@ impl TextDecoder {
options: &TextDecoderBinding::TextDecoderOptions)
-> Fallible<Temporary<TextDecoder>> {
let encoding = match encoding_from_whatwg_label(&label) {
- Some(enc) => enc,
- // FIXME: Should throw a RangeError as per spec
- None => return Err(Error::Syntax),
+ None => return TextDecoder::make_range_error(),
+ Some(enc) => enc
+ };
+ // The rust-encoding crate has WHATWG compatibility, so we are
+ // guaranteed to have a whatwg_name because we successfully got
+ // the encoding from encoding_from_whatwg_label.
+ // Use match + panic! instead of unwrap for better error message
+ match encoding.whatwg_name() {
+ None => panic!("Label {} fits valid encoding without valid name", label),
+ Some("replacement") => return TextDecoder::make_range_error(),
+ _ => ()
};
Ok(TextDecoder::new(global, encoding, options.fatal))
}
}
+
impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> {
fn Encoding(self) -> DOMString {
self.encoding.whatwg_name().unwrap().to_owned()
diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs
index e568a6dfa75..4f1045cc7ac 100644
--- a/components/script/dom/textencoder.rs
+++ b/components/script/dom/textencoder.rs
@@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::TextEncoderBinding;
use dom::bindings::codegen::Bindings::TextEncoderBinding::TextEncoderMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::error::Fallible;
-use dom::bindings::error::Error::IndexSize;
+use dom::bindings::error::Error::Range;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::str::USVString;
use dom::bindings::utils::{Reflector, reflect_dom_object};
@@ -54,8 +54,7 @@ impl TextEncoder {
Some(enc) => enc,
None => {
debug!("Encoding Label Not Supported");
- // TODO: should throw RangeError
- return Err(IndexSize)
+ return Err(Range("The given encoding is not supported.".to_owned()))
}
};
@@ -65,8 +64,7 @@ impl TextEncoder {
}
_ => {
debug!("Encoding Not UTF");
- // TODO: should throw RangeError
- Err(IndexSize)
+ return Err(Range("The encoding must be utf-8, utf-16le, or utf-16be.".to_owned()))
}
}
}
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 0c4dc0c1164..5584274dfb0 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -10952,6 +10952,10 @@
"url": "/encoding/api-basics.html"
},
{
+ "path": "encoding/api-invalid-label.html",
+ "url": "/encoding/api-invalid-label.html"
+ },
+ {
"path": "encoding/api-replacement-encodings.html",
"url": "/encoding/api-replacement-encodings.html"
},
diff --git a/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini b/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini
index 94c7203d3c2..b890466bae1 100644
--- a/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini
+++ b/tests/wpt/metadata/encoding/api-replacement-encodings.html.ini
@@ -1,20 +1,4 @@
[api-replacement-encodings.html]
type: testharness
- [The "replacement" label should not be a known encoding.]
- expected: FAIL
-
- [Label for "replacement" should be rejected by API: csiso2022kr]
- expected: FAIL
-
[Label for "replacement" should be rejected by API: hz-gb-2312]
expected: FAIL
-
- [Label for "replacement" should be rejected by API: iso-2022-cn]
- expected: FAIL
-
- [Label for "replacement" should be rejected by API: iso-2022-cn-ext]
- expected: FAIL
-
- [Label for "replacement" should be rejected by API: iso-2022-kr]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini
index 4d846b4443c..4c84622faf8 100644
--- a/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini
+++ b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini
@@ -1,113 +1,7 @@
[textencoder-constructor-non-utf.html]
type: testharness
- [Non-UTF encodings supported only for decode, not encode: ibm866]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-2]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-3]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-4]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-5]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-6]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-7]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-8]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-8-i]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-10]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-13]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-14]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-15]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-8859-16]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: koi8-r]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: koi8-u]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: macintosh]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-874]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1250]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1251]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1252]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1253]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1254]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1255]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1256]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1257]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: windows-1258]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: x-mac-cyrillic]
- expected: FAIL
-
[Non-UTF encodings supported only for decode, not encode: gbk]
expected: FAIL
- [Non-UTF encodings supported only for decode, not encode: gb18030]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: big5]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: euc-jp]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: iso-2022-jp]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: shift_jis]
- expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: euc-kr]
- expected: FAIL
-
[UTF encodings are supported for encode and decode: utf-16le]
expected: FAIL
-
- [Non-UTF encodings supported only for decode, not encode: x-user-defined]
- expected: FAIL
-
diff --git a/tests/wpt/web-platform-tests/encoding/api-invalid-label.html b/tests/wpt/web-platform-tests/encoding/api-invalid-label.html
new file mode 100644
index 00000000000..d2fa6786cdc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/encoding/api-invalid-label.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>Encoding API: invalid label</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+var invalidLabel = "invalid-invalidLabel"
+
+test(function() {
+ assert_throws({name: 'RangeError'}, function() { new TextEncoder(invalidLabel); });
+ assert_throws({name: 'RangeError'}, function() { new TextDecoder(invalidLabel); });
+}, 'Invalid label "' + invalidLabel + '" should be rejected by API.');
+
+</script>