mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
bindings: Allow Guard to take multiple conditions, check for SecureContext in ConstructorEnabled (#33508)
* Update condition handling for exposing values - Let Guard take a list of conditions - Check for secure context condition when exposing constructor Signed-off-by: Daniel Adams <msub2official@gmail.com> * Update WPT expectations Signed-off-by: Daniel Adams <msub2official@gmail.com> * Python tidy Signed-off-by: Daniel Adams <msub2official@gmail.com> * Make interfaces test run in secure context Signed-off-by: Daniel Adams <msub2official@gmail.com> --------- Signed-off-by: Daniel Adams <msub2official@gmail.com>
This commit is contained in:
parent
24ad2a0526
commit
4e4b137eaa
8 changed files with 45 additions and 32 deletions
|
@ -1545,15 +1545,20 @@ def MemberCondition(pref, func, exposed, secure):
|
||||||
assert func is None or isinstance(func, str)
|
assert func is None or isinstance(func, str)
|
||||||
assert exposed is None or isinstance(exposed, set)
|
assert exposed is None or isinstance(exposed, set)
|
||||||
assert func is None or pref is None or exposed is None or secure is None
|
assert func is None or pref is None or exposed is None or secure is None
|
||||||
|
conditions = []
|
||||||
if secure:
|
if secure:
|
||||||
return 'Condition::SecureContext()'
|
conditions.append('Condition::SecureContext()')
|
||||||
if pref:
|
if pref:
|
||||||
return f'Condition::Pref("{pref}")'
|
conditions.append(f'Condition::Pref("{pref}")')
|
||||||
if func:
|
if func:
|
||||||
return f'Condition::Func({func})'
|
conditions.append(f'Condition::Func({func})')
|
||||||
if exposed:
|
if exposed:
|
||||||
return [f"Condition::Exposed(InterfaceObjectMap::Globals::{camel_to_upper_snake(i)})" for i in exposed]
|
conditions.extend([
|
||||||
return "Condition::Satisfied"
|
f"Condition::Exposed(InterfaceObjectMap::Globals::{camel_to_upper_snake(i)})" for i in exposed
|
||||||
|
])
|
||||||
|
if len(conditions) == 0:
|
||||||
|
conditions.append("Condition::Satisfied")
|
||||||
|
return conditions
|
||||||
|
|
||||||
|
|
||||||
class PropertyDefiner:
|
class PropertyDefiner:
|
||||||
|
@ -1639,13 +1644,10 @@ class PropertyDefiner:
|
||||||
currentSpecs.append(specTerminator)
|
currentSpecs.append(specTerminator)
|
||||||
joinedCurrentSpecs = ',\n'.join(currentSpecs)
|
joinedCurrentSpecs = ',\n'.join(currentSpecs)
|
||||||
specs.append(f"&[\n{joinedCurrentSpecs}]\n")
|
specs.append(f"&[\n{joinedCurrentSpecs}]\n")
|
||||||
if isinstance(cond, list):
|
conds = ','.join(cond) if isinstance(cond, list) else cond
|
||||||
for i in cond:
|
prefableSpecs.append(
|
||||||
prefableSpecs.append(
|
prefableTemplate % (f"&[{conds}]", f"{name}_specs", len(specs) - 1)
|
||||||
prefableTemplate % (i, f"{name}_specs", len(specs) - 1))
|
)
|
||||||
else:
|
|
||||||
prefableSpecs.append(
|
|
||||||
prefableTemplate % (cond, f"{name}_specs", len(specs) - 1))
|
|
||||||
|
|
||||||
joinedSpecs = ',\n'.join(specs)
|
joinedSpecs = ',\n'.join(specs)
|
||||||
specsArray = (f"const {name}_specs: &[&[{specType}]] = &[\n"
|
specsArray = (f"const {name}_specs: &[&[{specType}]] = &[\n"
|
||||||
|
@ -2815,6 +2817,15 @@ class CGConstructorEnabled(CGAbstractMethod):
|
||||||
assert isinstance(func, list) and len(func) == 1
|
assert isinstance(func, list) and len(func) == 1
|
||||||
conditions.append(f"{func[0]}(aCx, aObj)")
|
conditions.append(f"{func[0]}(aCx, aObj)")
|
||||||
|
|
||||||
|
secure = iface.getExtendedAttribute("SecureContext")
|
||||||
|
if secure:
|
||||||
|
conditions.append("""
|
||||||
|
unsafe {
|
||||||
|
let in_realm_proof = AlreadyInRealm::assert_for_cx(aCx);
|
||||||
|
GlobalScope::from_context(*aCx, InRealm::Already(&in_realm_proof)).is_secure_context()
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
return CGList((CGGeneric(cond) for cond in conditions), " &&\n")
|
return CGList((CGGeneric(cond) for cond in conditions), " &&\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,23 +13,37 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::realms::{AlreadyInRealm, InRealm};
|
use crate::realms::{AlreadyInRealm, InRealm};
|
||||||
use crate::script_runtime::JSContext;
|
use crate::script_runtime::JSContext;
|
||||||
|
|
||||||
/// A container with a condition.
|
/// A container with a list of conditions.
|
||||||
pub struct Guard<T: Clone + Copy> {
|
pub struct Guard<T: Clone + Copy> {
|
||||||
condition: Condition,
|
conditions: &'static [Condition],
|
||||||
value: T,
|
value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone + Copy> Guard<T> {
|
impl<T: Clone + Copy> Guard<T> {
|
||||||
/// Construct a new guarded value.
|
/// Construct a new guarded value.
|
||||||
pub const fn new(condition: Condition, value: T) -> Self {
|
pub const fn new(conditions: &'static [Condition], value: T) -> Self {
|
||||||
Guard { condition, value }
|
Guard { conditions, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expose the value if the condition is satisfied.
|
/// Expose the value if the conditions are satisfied.
|
||||||
///
|
///
|
||||||
/// The passed handle is the object on which the value may be exposed.
|
/// The passed handle is the object on which the value may be exposed.
|
||||||
pub fn expose(&self, cx: JSContext, obj: HandleObject, global: HandleObject) -> Option<T> {
|
pub fn expose(&self, cx: JSContext, obj: HandleObject, global: HandleObject) -> Option<T> {
|
||||||
if self.condition.is_satisfied(cx, obj, global) {
|
let mut exposed_on_global = false;
|
||||||
|
let conditions_satisfied = self.conditions.iter().all(|c| match c {
|
||||||
|
Condition::Satisfied => {
|
||||||
|
exposed_on_global = true;
|
||||||
|
true
|
||||||
|
},
|
||||||
|
// If there are multiple Exposed conditions, we just need one of them to be true
|
||||||
|
Condition::Exposed(globals) => {
|
||||||
|
exposed_on_global |= is_exposed_in(global, *globals);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
_ => c.is_satisfied(cx, obj, global),
|
||||||
|
});
|
||||||
|
|
||||||
|
if conditions_satisfied && exposed_on_global {
|
||||||
Some(self.value)
|
Some(self.value)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -38,6 +52,7 @@ impl<T: Clone + Copy> Guard<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A condition to expose things.
|
/// A condition to expose things.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub enum Condition {
|
pub enum Condition {
|
||||||
/// The condition is satisfied if the function returns true.
|
/// The condition is satisfied if the function returns true.
|
||||||
Func(fn(JSContext, HandleObject) -> bool),
|
Func(fn(JSContext, HandleObject) -> bool),
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
[webxr_availability.http.sub.html]
|
|
||||||
[Test webxr not available in secure context in insecure context]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test webxr not available in insecure context]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[webxr_availability.http.sub.html]
|
|
||||||
[Test webxr not available in insecure context]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Test webxr not available in secure context in insecure context]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/mozilla/meta/MANIFEST.json
vendored
2
tests/wpt/mozilla/meta/MANIFEST.json
vendored
|
@ -13494,7 +13494,7 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"interfaces.html": [
|
"interfaces.https.html": [
|
||||||
"94f1102da478919d2948ebb96f81450f5d545635",
|
"94f1102da478919d2948ebb96f81450f5d545635",
|
||||||
[
|
[
|
||||||
null,
|
null,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue