/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
runtime/ops/bootstrap.rs
187 строк
5 KB
Bartek Iwańczuk
fix(runtime): suggest --unstable-unsafe-proto after __proto__ access (#35192)
15 июн 2026, 15:50
Не верифицирован
15 июн 2026, 15:50
cffc8d7
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use deno_core::OpState; use deno_core::op2; use deno_terminal::colors::ColorLevel; use crate::BootstrapOptions; deno_core::extension!( deno_bootstrap, ops = [ op_bootstrap_args, op_bootstrap_pid, op_bootstrap_numcpus, op_bootstrap_user_agent, op_bootstrap_language, op_bootstrap_log_level, op_bootstrap_color_depth, op_bootstrap_no_color, op_bootstrap_stdout_no_color, op_bootstrap_stderr_no_color, op_bootstrap_unstable_args, op_bootstrap_is_from_unconfigured_runtime, op_proto_set_attempted, op_proto_get_attempted, op_snapshot_options, ], options = { snapshot_options: Option<SnapshotOptions>, is_from_unconfigured_runtime: bool, }, state = |state, options| { if let Some(snapshot_options) = options.snapshot_options { state.put::<SnapshotOptions>(snapshot_options); } state.put(IsFromUnconfiguredRuntime(options.is_from_unconfigured_runtime)); }, ); #[derive(serde::Serialize)] #[serde(rename_all = "camelCase")] pub struct SnapshotOptions { pub ts_version: String, pub v8_version: &'static str, pub target: String, } struct IsFromUnconfiguredRuntime(bool); impl Default for SnapshotOptions { fn default() -> Self { let arch = std::env::consts::ARCH; let platform = std::env::consts::OS; let target = match platform { "macos" => format!("{}-apple-darwin", arch), "linux" => format!("{}-unknown-linux-gnu", arch), "windows" => format!("{}-pc-windows-msvc", arch), rest => format!("{}-{}", arch, rest), }; Self { ts_version: "n/a".to_owned(), v8_version: deno_core::v8::VERSION_STRING, target, } } } // Note: Called at snapshot time, op perf is not a concern. #[op2] #[serde] pub fn op_snapshot_options(state: &mut OpState) -> SnapshotOptions { // `SnapshotOptions` is only placed into the op state when the runtime is // bootstrapped with a startup snapshot. Embedders that bootstrap without one // (`startup_snapshot: None`) never insert it, so fall back to the default // instead of panicking when the value is absent. state.try_take::<SnapshotOptions>().unwrap_or_default() } #[op2] pub fn op_bootstrap_args(state: &mut OpState) -> Vec<String> { state.borrow::<BootstrapOptions>().args.clone() } #[op2(fast)] #[smi] pub fn op_bootstrap_pid() -> u32 { std::process::id() } #[op2(fast)] #[smi] pub fn op_bootstrap_numcpus(state: &mut OpState) -> u32 { state.borrow::<BootstrapOptions>().cpu_count as u32 } #[op2] #[string] pub fn op_bootstrap_user_agent(state: &mut OpState) -> String { state.borrow::<BootstrapOptions>().user_agent.clone() } #[op2] pub fn op_bootstrap_unstable_args(state: &mut OpState) -> Vec<String> { let options = state.borrow::<BootstrapOptions>(); let mut flags = Vec::with_capacity(options.unstable_features.len()); for unstable_feature in &options.unstable_features { if let Some(granular_flag) = deno_features::UNSTABLE_FEATURES.get((*unstable_feature) as usize) { flags.push(format!("--unstable-{}", granular_flag.name)); } } flags } #[op2] #[string] pub fn op_bootstrap_language(state: &mut OpState) -> String { state.borrow::<BootstrapOptions>().locale.clone() } #[op2(fast)] #[smi] pub fn op_bootstrap_log_level(state: &mut OpState) -> i32 { state.borrow::<BootstrapOptions>().log_level as i32 } #[op2(fast)] pub fn op_bootstrap_color_depth(state: &mut OpState) -> i32 { let options = state.borrow::<BootstrapOptions>(); match options.color_level { ColorLevel::None => 1, ColorLevel::Ansi => 4, ColorLevel::Ansi256 => 8, ColorLevel::TrueColor => 24, } } #[op2(fast)] pub fn op_bootstrap_no_color(_state: &mut OpState) -> bool { !deno_terminal::colors::use_color() } #[op2(fast)] pub fn op_bootstrap_stdout_no_color(_state: &mut OpState) -> bool { if deno_terminal::colors::force_color() { return false; } !deno_terminal::is_stdout_tty() || !deno_terminal::colors::use_color() } #[op2(fast)] pub fn op_bootstrap_stderr_no_color(_state: &mut OpState) -> bool { if deno_terminal::colors::force_color() { return false; } !deno_terminal::is_stderr_tty() || !deno_terminal::colors::use_color() } #[op2(fast)] pub fn op_bootstrap_is_from_unconfigured_runtime(state: &mut OpState) -> bool { state.borrow::<IsFromUnconfiguredRuntime>().0 } // Called (at most once) from the disabled `Object.prototype.__proto__` setter // in 99_main.js when user code assigns to `__proto__`. Records a process-global // flag so that, if the program later crashes, the uncaught-error formatter can // suggest `--unstable-unsafe-proto`. See `crate::fmt_errors::PROTO_SET_ATTEMPTED`. #[op2(fast)] pub fn op_proto_set_attempted() { crate::fmt_errors::PROTO_SET_ATTEMPTED .store(true, std::sync::atomic::Ordering::Relaxed); } // Called (at most once) from the disabled `Object.prototype.__proto__` getter // in 99_main.js when user code reads `__proto__` (the read returns `undefined`). // Records a process-global flag; the uncaught-error formatter only acts on it // when the crashing error also mentions `__proto__`, since reads are common and // usually harmless. See `crate::fmt_errors::PROTO_GET_ATTEMPTED`. #[op2(fast)] pub fn op_proto_get_attempted() { crate::fmt_errors::PROTO_GET_ATTEMPTED .store(true, std::sync::atomic::Ordering::Relaxed); }