mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-03-09 21:47:00 -04: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));
|
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,
|
const v8::Context* v8__Context__FromSnapshot(v8::Isolate* isolate,
|
||||||
size_t context_snapshot_index) {
|
size_t context_snapshot_index) {
|
||||||
v8::MaybeLocal<v8::Context> maybe_local =
|
v8::MaybeLocal<v8::Context> maybe_local =
|
||||||
|
|
|
@ -40,6 +40,14 @@ extern "C" {
|
||||||
isolate: *mut Isolate,
|
isolate: *mut Isolate,
|
||||||
context_snapshot_index: usize,
|
context_snapshot_index: usize,
|
||||||
) -> *const Context;
|
) -> *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 {
|
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 {
|
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]
|
#[test]
|
||||||
fn allow_atomics_wait() {
|
fn allow_atomics_wait() {
|
||||||
let _setup_guard = setup::parallel_test();
|
let _setup_guard = setup::parallel_test();
|
||||||
|
|
Loading…
Add table
Reference in a new issue