/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
tests/napi/src/handle_scope.rs
174 строки
5 KB
Bartek Iwańczuk
Revert "fix(ext/napi): implement real V8 handle scopes and callback scopes" (#33363)
22 апр 2026, 21:21
Не верифицирован
22 апр 2026, 21:21
e48bec8
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use std::ptr; use napi_sys::*; use crate::assert_napi_ok; use crate::napi_new_property; /// Test napi_open_handle_scope / napi_close_handle_scope. /// Creates an object inside a handle scope, returns it via the outer scope. extern "C" fn test_open_close_scope( env: napi_env, _info: napi_callback_info, ) -> napi_value { let mut scope: napi_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_handle_scope(env, &mut scope)); let mut value: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_object(env, &mut value)); assert_napi_ok!(napi_close_handle_scope(env, scope)); // Return a value created in the outer (implicit) scope to prove // scope management does not crash. let mut result: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_string_utf8(env, c"ok".as_ptr(), 2, &mut result)); result } /// Test napi_open_escapable_handle_scope + napi_escape_handle. /// Creates a string inside an escapable scope, escapes it, and returns it. extern "C" fn test_escapable_scope( env: napi_env, _info: napi_callback_info, ) -> napi_value { let mut scope: napi_escapable_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_escapable_handle_scope(env, &mut scope)); let mut inner: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_string_utf8( env, c"escaped".as_ptr(), 7, &mut inner )); let mut escaped: napi_value = ptr::null_mut(); assert_napi_ok!(napi_escape_handle(env, scope, inner, &mut escaped)); assert_napi_ok!(napi_close_escapable_handle_scope(env, scope)); escaped } /// Test that calling napi_escape_handle twice returns an error. /// NOTE: Currently panics in Deno instead of returning /// napi_escape_called_twice. Test is marked ignore in JS. extern "C" fn test_escape_twice( env: napi_env, _info: napi_callback_info, ) -> napi_value { let mut scope: napi_escapable_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_escapable_handle_scope(env, &mut scope)); let mut inner: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_string_utf8( env, c"first".as_ptr(), 5, &mut inner )); let mut escaped: napi_value = ptr::null_mut(); assert_napi_ok!(napi_escape_handle(env, scope, inner, &mut escaped)); // Second escape should fail with napi_escape_called_twice. let mut second: napi_value = ptr::null_mut(); let status = unsafe { napi_escape_handle(env, scope, inner, &mut second) }; assert_eq!(status, Status::napi_escape_called_twice); assert_napi_ok!(napi_close_escapable_handle_scope(env, scope)); let mut result: napi_value = ptr::null_mut(); assert_napi_ok!(napi_get_boolean(env, true, &mut result)); result } /// Test nested handle scopes. extern "C" fn test_nested_scopes( env: napi_env, _info: napi_callback_info, ) -> napi_value { let mut outer: napi_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_handle_scope(env, &mut outer)); let mut inner: napi_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_handle_scope(env, &mut inner)); let mut value: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_int32(env, 42, &mut value)); assert_napi_ok!(napi_close_handle_scope(env, inner)); assert_napi_ok!(napi_close_handle_scope(env, outer)); let mut result: napi_value = ptr::null_mut(); assert_napi_ok!(napi_get_boolean(env, true, &mut result)); result } /// Regression test for #33281: values created inside a handle scope /// must remain valid after the scope is closed. With real V8 HandleScopes /// this would be a use-after-free since closing the scope frees all /// handles allocated within it. extern "C" fn test_use_value_after_close( env: napi_env, _info: napi_callback_info, ) -> napi_value { let mut scope: napi_handle_scope = ptr::null_mut(); assert_napi_ok!(napi_open_handle_scope(env, &mut scope)); // Create a string inside the handle scope let mut value: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_string_utf8( env, c"hello".as_ptr(), 5, &mut value )); assert_napi_ok!(napi_close_handle_scope(env, scope)); // Use the value AFTER closing the scope. With real V8 HandleScopes // the handle would be dangling and this would crash or corrupt data. let mut obj: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_object(env, &mut obj)); let mut key: napi_value = ptr::null_mut(); assert_napi_ok!(napi_create_string_utf8( env, c"greeting".as_ptr(), 8, &mut key )); assert_napi_ok!(napi_set_property(env, obj, key, value)); // Read it back to verify the handle is still valid let mut read_back: napi_value = ptr::null_mut(); assert_napi_ok!(napi_get_property(env, obj, key, &mut read_back)); read_back } pub fn init(env: napi_env, exports: napi_value) { let properties = &[ napi_new_property!(env, "test_open_close_scope", test_open_close_scope), napi_new_property!(env, "test_escapable_scope", test_escapable_scope), napi_new_property!(env, "test_escape_twice", test_escape_twice), napi_new_property!(env, "test_nested_scopes", test_nested_scopes), napi_new_property!( env, "test_use_value_after_close", test_use_value_after_close ), ]; assert_napi_ok!(napi_define_properties( env, exports, properties.len(), properties.as_ptr() )); }