mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-21 15:04:33 -05:00
feat: Expose the security token API from V8 (#1192)
This commit is contained in:
parent
c2ec15f046
commit
c58f4c08d9
3 changed files with 117 additions and 0 deletions
|
@ -1719,6 +1719,21 @@ void v8__Context__SetPromiseHooks(v8::Context& self,
|
|||
ptr_to_local(after_hook), ptr_to_local(resolve_hook));
|
||||
}
|
||||
|
||||
const v8::Value* v8__Context__GetSecurityToken(const v8::Context& self) {
|
||||
auto value = ptr_to_local(&self)->GetSecurityToken();
|
||||
return local_to_ptr(value);
|
||||
}
|
||||
|
||||
void v8__Context__SetSecurityToken(v8::Context& self,
|
||||
const v8::Value* token) {
|
||||
auto c = ptr_to_local(&self);
|
||||
c->SetSecurityToken(ptr_to_local(token));
|
||||
}
|
||||
|
||||
void v8__Context__UseDefaultSecurityToken(v8::Context& self) {
|
||||
ptr_to_local(&self)->UseDefaultSecurityToken();
|
||||
}
|
||||
|
||||
const v8::Context* v8__Context__FromSnapshot(v8::Isolate* isolate,
|
||||
size_t context_snapshot_index) {
|
||||
v8::MaybeLocal<v8::Context> maybe_local =
|
||||
|
|
|
@ -40,6 +40,14 @@ extern "C" {
|
|||
isolate: *mut Isolate,
|
||||
context_snapshot_index: usize,
|
||||
) -> *const Context;
|
||||
pub(super) fn v8__Context__GetSecurityToken(
|
||||
this: *const Context,
|
||||
) -> *const Value;
|
||||
pub(super) fn v8__Context__SetSecurityToken(
|
||||
this: *const Context,
|
||||
value: *const Value,
|
||||
);
|
||||
pub(super) fn v8__Context__UseDefaultSecurityToken(this: *const Context);
|
||||
}
|
||||
|
||||
impl Context {
|
||||
|
@ -320,6 +328,29 @@ impl Context {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_security_token<'s>(
|
||||
&self,
|
||||
scope: &mut HandleScope<'s, ()>,
|
||||
) -> Local<'s, Value> {
|
||||
unsafe { scope.cast_local(|_| v8__Context__GetSecurityToken(self)) }
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_security_token(&self, token: Local<Value>) {
|
||||
unsafe {
|
||||
v8__Context__SetSecurityToken(self, &*token);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn use_default_security_token(&self) {
|
||||
unsafe {
|
||||
v8__Context__UseDefaultSecurityToken(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContextAnnex {
|
||||
|
|
|
@ -3386,6 +3386,77 @@ fn context_promise_hooks_partial() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn security_token() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
// Define a variable in the parent context
|
||||
let global = {
|
||||
let global = context.global(scope);
|
||||
let variable_key = v8::String::new(scope, "variable").unwrap();
|
||||
let variable_value = v8::String::new(scope, "value").unwrap();
|
||||
global.set(scope, variable_key.into(), variable_value.into());
|
||||
v8::Global::new(scope, global)
|
||||
};
|
||||
// This code will try to access the variable defined in the parent context
|
||||
let source = r#"
|
||||
if (variable !== 'value') {
|
||||
throw new Error('Expected variable to be value');
|
||||
}
|
||||
"#;
|
||||
|
||||
let templ = v8::ObjectTemplate::new(scope);
|
||||
let global = v8::Local::new(scope, global);
|
||||
templ.set_named_property_handler(
|
||||
v8::NamedPropertyHandlerConfiguration::new()
|
||||
.getter(
|
||||
|scope: &mut v8::HandleScope,
|
||||
key: v8::Local<v8::Name>,
|
||||
args: v8::PropertyCallbackArguments,
|
||||
mut rv: v8::ReturnValue| {
|
||||
let obj = v8::Local::<v8::Object>::try_from(args.data()).unwrap();
|
||||
if let Some(val) = obj.get(scope, key.into()) {
|
||||
rv.set(val);
|
||||
}
|
||||
},
|
||||
)
|
||||
.data(global.into()),
|
||||
);
|
||||
|
||||
// Creates a child context
|
||||
{
|
||||
let security_token = context.get_security_token(scope);
|
||||
let child_context = v8::Context::new_from_template(scope, templ);
|
||||
// Without the security context, the variable can not be shared
|
||||
child_context.set_security_token(security_token);
|
||||
let child_scope = &mut v8::ContextScope::new(scope, child_context);
|
||||
let try_catch = &mut v8::TryCatch::new(child_scope);
|
||||
let result = eval(try_catch, source);
|
||||
assert!(!try_catch.has_caught());
|
||||
assert!(result.unwrap().is_undefined());
|
||||
}
|
||||
|
||||
// Runs the same code but without the security token, it should fail
|
||||
{
|
||||
let child_context = v8::Context::new_from_template(scope, templ);
|
||||
let child_scope = &mut v8::ContextScope::new(scope, child_context);
|
||||
let try_catch = &mut v8::TryCatch::new(child_scope);
|
||||
let result = eval(try_catch, source);
|
||||
assert!(try_catch.has_caught());
|
||||
let exc = try_catch.exception().unwrap();
|
||||
let exc = exc.to_string(try_catch).unwrap();
|
||||
let exc = exc.to_rust_string_lossy(try_catch);
|
||||
assert!(exc.contains("no access"));
|
||||
assert!(result.is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_atomics_wait() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
|
|
Loading…
Reference in a new issue