mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Merge pull request #2863 from mbrubeck/2862-null-fun
Don't fail on invalid JS syntax in event handlers. r=Ms2ger
This commit is contained in:
commit
d43db3df30
3 changed files with 60 additions and 15 deletions
|
@ -6,10 +6,12 @@ use dom::bindings::conversions::ToJSValConvertible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::domexception::DOMException;
|
use dom::domexception::DOMException;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSBool};
|
use js::jsapi::{JSContext, JSBool, JSObject};
|
||||||
use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException};
|
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};
|
||||||
|
use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain};
|
||||||
use js::glue::{ReportError};
|
use js::glue::{ReportError};
|
||||||
|
use js::rust::with_compartment;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::ptr;
|
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 {
|
pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool {
|
||||||
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
|
||||||
let message = format!("argument could not be converted to any of: {}", names);
|
let message = format!("argument could not be converted to any of: {}", names);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dom::bindings::callback::CallbackContainer;
|
use dom::bindings::callback::CallbackContainer;
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
|
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::js::JSRef;
|
||||||
use dom::bindings::trace::Traceable;
|
use dom::bindings::trace::Traceable;
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
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];
|
static arg_names: [*c_char, ..1] = [&arg_name as *c_char];
|
||||||
|
|
||||||
let source = source.to_utf16();
|
let source = source.to_utf16();
|
||||||
let handler =
|
let handler = name.with_ref(|name| {
|
||||||
name.with_ref(|name| {
|
url.with_ref(|url| {
|
||||||
url.with_ref(|url| { unsafe {
|
unsafe {
|
||||||
let fun = JS_CompileUCFunction(cx, ptr::mut_null(), name,
|
JS_CompileUCFunction(cx, ptr::mut_null(), name,
|
||||||
nargs, &arg_names as **i8 as *mut *i8, source.as_ptr(),
|
nargs, &arg_names as **i8 as *mut *i8,
|
||||||
source.len() as size_t,
|
source.as_ptr(), source.len() as size_t, url, lineno)
|
||||||
url, lineno);
|
}
|
||||||
assert!(fun.is_not_null());
|
})
|
||||||
JS_GetFunctionObject(fun)
|
});
|
||||||
}})});
|
if handler.is_null() {
|
||||||
let funobj = unsafe { JS_CloneFunctionObject(cx, handler, scope) };
|
report_pending_exception(cx, self.reflector().get_jsobject());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let funobj = unsafe {
|
||||||
|
JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope)
|
||||||
|
};
|
||||||
assert!(funobj.is_not_null());
|
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>(
|
fn set_event_handler_common<T: CallbackContainer>(
|
||||||
|
|
23
src/test/content/test_event_handler_syntax_error.html
Normal file
23
src/test/content/test_event_handler_syntax_error.html
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue