aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/script/dom/bindings/error.rs20
-rw-r--r--src/components/script/dom/eventtarget.rs32
-rw-r--r--src/test/content/test_event_handler_syntax_error.html23
3 files changed, 60 insertions, 15 deletions
diff --git a/src/components/script/dom/bindings/error.rs b/src/components/script/dom/bindings/error.rs
index f204dc5859a..cef1de163fd 100644
--- a/src/components/script/dom/bindings/error.rs
+++ b/src/components/script/dom/bindings/error.rs
@@ -6,10 +6,12 @@ use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::global::GlobalRef;
use dom::domexception::DOMException;
-use js::jsapi::{JSContext, JSBool};
-use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException};
+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_SaveFrameChain, JS_RestoreFrameChain};
use js::glue::{ReportError};
+use js::rust::with_compartment;
use libc;
use std::ptr;
@@ -46,6 +48,20 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: &GlobalRef,
}
}
+pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) {
+ unsafe {
+ if JS_IsExceptionPending(cx) != 0 {
+ let saved = JS_SaveFrameChain(cx);
+ with_compartment(cx, obj, || {
+ JS_ReportPendingException(cx);
+ });
+ if saved != 0 {
+ JS_RestoreFrameChain(cx);
+ }
+ }
+ }
+}
+
pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
let message = format!("argument could not be converted to any of: {}", names);
diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs
index 1683f280100..75a7319ee23 100644
--- a/src/components/script/dom/eventtarget.rs
+++ b/src/components/script/dom/eventtarget.rs
@@ -5,7 +5,7 @@
use dom::bindings::callback::CallbackContainer;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
-use dom::bindings::error::{Fallible, InvalidState};
+use dom::bindings::error::{Fallible, InvalidState, report_pending_exception};
use dom::bindings::js::JSRef;
use dom::bindings::trace::Traceable;
use dom::bindings::utils::{Reflectable, Reflector};
@@ -181,19 +181,25 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
static arg_names: [*c_char, ..1] = [&arg_name as *c_char];
let source = source.to_utf16();
- let handler =
- name.with_ref(|name| {
- url.with_ref(|url| { unsafe {
- let fun = JS_CompileUCFunction(cx, ptr::mut_null(), name,
- nargs, &arg_names as **i8 as *mut *i8, source.as_ptr(),
- source.len() as size_t,
- url, lineno);
- assert!(fun.is_not_null());
- JS_GetFunctionObject(fun)
- }})});
- let funobj = unsafe { JS_CloneFunctionObject(cx, handler, scope) };
+ let handler = name.with_ref(|name| {
+ url.with_ref(|url| {
+ unsafe {
+ JS_CompileUCFunction(cx, ptr::mut_null(), name,
+ nargs, &arg_names as **i8 as *mut *i8,
+ source.as_ptr(), source.len() as size_t, url, lineno)
+ }
+ })
+ });
+ if handler.is_null() {
+ report_pending_exception(cx, self.reflector().get_jsobject());
+ return;
+ }
+
+ let funobj = unsafe {
+ JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope)
+ };
assert!(funobj.is_not_null());
- self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)))
+ self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
}
fn set_event_handler_common<T: CallbackContainer>(
diff --git a/src/test/content/test_event_handler_syntax_error.html b/src/test/content/test_event_handler_syntax_error.html
new file mode 100644
index 00000000000..f6c8cdffcff
--- /dev/null
+++ b/src/test/content/test_event_handler_syntax_error.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title></title>
+ <meta charset="UTF-8">
+ <script src="harness.js"></script>
+</head>
+<body>
+ <a id="a" onclick="{">link</a>
+ <script>
+ var a = document.getElementById("a");
+ is(a.onclick, null, "invalid onclick attribute");
+
+ document.body.setAttribute("onx", "{");
+ document.body.setAttribute("ony", "}");
+
+ is(document.body.getAttribute("onx"), "{");
+ is(document.body.getAttribute("ony"), "}");
+
+ finish();
+ </script>
+</body>
+</html>