summaryrefslogtreecommitdiff
path: root/runtime/ops/os/mod.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /runtime/ops/os/mod.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'runtime/ops/os/mod.rs')
-rw-r--r--runtime/ops/os/mod.rs99
1 files changed, 64 insertions, 35 deletions
diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs
index bd9260e97..74c708c53 100644
--- a/runtime/ops/os/mod.rs
+++ b/runtime/ops/os/mod.rs
@@ -1,9 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use super::utils::into_string;
+use crate::sys_info;
use crate::worker::ExitCode;
-use deno_core::error::type_error;
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::v8;
use deno_core::OpState;
@@ -14,8 +12,6 @@ use serde::Serialize;
use std::collections::HashMap;
use std::env;
-mod sys_info;
-
deno_core::extension!(
deno_os,
ops = [
@@ -73,9 +69,27 @@ deno_core::extension!(
},
);
+#[derive(Debug, thiserror::Error)]
+pub enum OsError {
+ #[error(transparent)]
+ Permission(#[from] deno_permissions::PermissionCheckError),
+ #[error("File name or path {0:?} is not valid UTF-8")]
+ InvalidUtf8(std::ffi::OsString),
+ #[error("Key is an empty string.")]
+ EnvEmptyKey,
+ #[error("Key contains invalid characters: {0:?}")]
+ EnvInvalidKey(String),
+ #[error("Value contains invalid characters: {0:?}")]
+ EnvInvalidValue(String),
+ #[error(transparent)]
+ Var(#[from] env::VarError),
+ #[error("{0}")]
+ Io(#[from] std::io::Error),
+}
+
#[op2]
#[string]
-fn op_exec_path(state: &mut OpState) -> Result<String, AnyError> {
+fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
let current_exe = env::current_exe().unwrap();
state
.borrow_mut::<PermissionsContainer>()
@@ -83,7 +97,10 @@ fn op_exec_path(state: &mut OpState) -> Result<String, AnyError> {
// normalize path so it doesn't include '.' or '..' components
let path = normalize_path(current_exe);
- into_string(path.into_os_string())
+ path
+ .into_os_string()
+ .into_string()
+ .map_err(OsError::InvalidUtf8)
}
#[op2(fast)]
@@ -91,20 +108,16 @@ fn op_set_env(
state: &mut OpState,
#[string] key: &str,
#[string] value: &str,
-) -> Result<(), AnyError> {
+) -> Result<(), OsError> {
state.borrow_mut::<PermissionsContainer>().check_env(key)?;
if key.is_empty() {
- return Err(type_error("Key is an empty string."));
+ return Err(OsError::EnvEmptyKey);
}
if key.contains(&['=', '\0'] as &[char]) {
- return Err(type_error(format!(
- "Key contains invalid characters: {key:?}"
- )));
+ return Err(OsError::EnvInvalidKey(key.to_string()));
}
if value.contains('\0') {
- return Err(type_error(format!(
- "Value contains invalid characters: {value:?}"
- )));
+ return Err(OsError::EnvInvalidValue(value.to_string()));
}
env::set_var(key, value);
Ok(())
@@ -112,7 +125,9 @@ fn op_set_env(
#[op2]
#[serde]
-fn op_env(state: &mut OpState) -> Result<HashMap<String, String>, AnyError> {
+fn op_env(
+ state: &mut OpState,
+) -> Result<HashMap<String, String>, deno_core::error::AnyError> {
state.borrow_mut::<PermissionsContainer>().check_env_all()?;
Ok(env::vars().collect())
}
@@ -122,7 +137,7 @@ fn op_env(state: &mut OpState) -> Result<HashMap<String, String>, AnyError> {
fn op_get_env(
state: &mut OpState,
#[string] key: String,
-) -> Result<Option<String>, AnyError> {
+) -> Result<Option<String>, OsError> {
let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key);
if !skip_permission_check {
@@ -130,13 +145,11 @@ fn op_get_env(
}
if key.is_empty() {
- return Err(type_error("Key is an empty string."));
+ return Err(OsError::EnvEmptyKey);
}
if key.contains(&['=', '\0'] as &[char]) {
- return Err(type_error(format!(
- "Key contains invalid characters: {key:?}"
- )));
+ return Err(OsError::EnvInvalidKey(key.to_string()));
}
let r = match env::var(key) {
@@ -150,10 +163,10 @@ fn op_get_env(
fn op_delete_env(
state: &mut OpState,
#[string] key: String,
-) -> Result<(), AnyError> {
+) -> Result<(), OsError> {
state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
if key.is_empty() || key.contains(&['=', '\0'] as &[char]) {
- return Err(type_error("Key contains invalid characters."));
+ return Err(OsError::EnvInvalidKey(key.to_string()));
}
env::remove_var(key);
Ok(())
@@ -173,12 +186,14 @@ fn op_get_exit_code(state: &mut OpState) -> i32 {
#[op2(fast)]
fn op_exit(state: &mut OpState) {
let code = state.borrow::<ExitCode>().get();
- std::process::exit(code)
+ crate::exit(code)
}
#[op2]
#[serde]
-fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> {
+fn op_loadavg(
+ state: &mut OpState,
+) -> Result<(f64, f64, f64), deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("loadavg", "Deno.loadavg()")?;
@@ -187,7 +202,9 @@ fn op_loadavg(state: &mut OpState) -> Result<(f64, f64, f64), AnyError> {
#[op2]
#[string]
-fn op_hostname(state: &mut OpState) -> Result<String, AnyError> {
+fn op_hostname(
+ state: &mut OpState,
+) -> Result<String, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("hostname", "Deno.hostname()")?;
@@ -196,7 +213,9 @@ fn op_hostname(state: &mut OpState) -> Result<String, AnyError> {
#[op2]
#[string]
-fn op_os_release(state: &mut OpState) -> Result<String, AnyError> {
+fn op_os_release(
+ state: &mut OpState,
+) -> Result<String, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("osRelease", "Deno.osRelease()")?;
@@ -207,7 +226,7 @@ fn op_os_release(state: &mut OpState) -> Result<String, AnyError> {
#[serde]
fn op_network_interfaces(
state: &mut OpState,
-) -> Result<Vec<NetworkInterface>, AnyError> {
+) -> Result<Vec<NetworkInterface>, OsError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("networkInterfaces", "Deno.networkInterfaces()")?;
@@ -259,7 +278,7 @@ impl From<netif::Interface> for NetworkInterface {
#[serde]
fn op_system_memory_info(
state: &mut OpState,
-) -> Result<Option<sys_info::MemInfo>, AnyError> {
+) -> Result<Option<sys_info::MemInfo>, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("systemMemoryInfo", "Deno.systemMemoryInfo()")?;
@@ -269,7 +288,9 @@ fn op_system_memory_info(
#[cfg(not(windows))]
#[op2]
#[smi]
-fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
+fn op_gid(
+ state: &mut OpState,
+) -> Result<Option<u32>, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("gid", "Deno.gid()")?;
@@ -283,7 +304,9 @@ fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
#[cfg(windows)]
#[op2]
#[smi]
-fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
+fn op_gid(
+ state: &mut OpState,
+) -> Result<Option<u32>, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("gid", "Deno.gid()")?;
@@ -293,7 +316,9 @@ fn op_gid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
#[cfg(not(windows))]
#[op2]
#[smi]
-fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
+fn op_uid(
+ state: &mut OpState,
+) -> Result<Option<u32>, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("uid", "Deno.uid()")?;
@@ -307,7 +332,9 @@ fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
#[cfg(windows)]
#[op2]
#[smi]
-fn op_uid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
+fn op_uid(
+ state: &mut OpState,
+) -> Result<Option<u32>, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("uid", "Deno.uid()")?;
@@ -485,7 +512,7 @@ fn rss() -> usize {
}
}
-fn os_uptime(state: &mut OpState) -> Result<u64, AnyError> {
+fn os_uptime(state: &mut OpState) -> Result<u64, deno_core::error::AnyError> {
state
.borrow_mut::<PermissionsContainer>()
.check_sys("osUptime", "Deno.osUptime()")?;
@@ -494,6 +521,8 @@ fn os_uptime(state: &mut OpState) -> Result<u64, AnyError> {
#[op2(fast)]
#[number]
-fn op_os_uptime(state: &mut OpState) -> Result<u64, AnyError> {
+fn op_os_uptime(
+ state: &mut OpState,
+) -> Result<u64, deno_core::error::AnyError> {
os_uptime(state)
}