deno/ext/fs/lib.rs
David Sherret 48b94c0995
Some checks are pending
ci / pre-build (push) Waiting to run
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (aarch64, test, linux, debug, ubicloud-standard-16-arm) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (aarch64, test, linux, release, ubicloud-standard-16-arm, true) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (aarch64, test, macos, debug, ${{ github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') && 'self-hosted' || 'macos-14' }}) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (aarch64, test, macos, release, ${{ (!contains(github.event.pull_request.labels.*.name, 'ci-full') && (github.event_name == 'pull_request')) && 'ubuntu-24.04' || github.reposit… (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, bench, linux, release, ${{ (!contains(github.event.pull_request.labels.*.name, 'ci-full') && (github.event_name == 'pull_request' && !contains(github.event.pull_reques… (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, lint, linux, debug, ubuntu-24.04) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, lint, macos, debug, macos-13) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, lint, windows, debug, windows-2022) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, linux, debug, ubuntu-24.04, true) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, linux, release, ${{ github.repository == 'denoland/deno' && 'ubuntu-24.04-xl' || 'ubuntu-24.04' }}, true, ${{ !startsWith(github.ref, 'refs/tags/') }}) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, macos, debug, macos-13) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, macos, release, ${{ (!contains(github.event.pull_request.labels.*.name, 'ci-full') && (github.event_name == 'pull_request')) && 'ubuntu-24.04' || 'macos-13' }}, … (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, windows, debug, windows-2022) (push) Blocked by required conditions
ci / ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }}-${{ matrix.arch }} (x86_64, test, windows, release, ${{ (!contains(github.event.pull_request.labels.*.name, 'ci-full') && (github.event_name == 'pull_request')) && 'ubuntu-24.04' || github.reposi… (push) Blocked by required conditions
ci / publish canary (push) Blocked by required conditions
refactor: use boxed_error in some places (#26887)
2024-11-15 23:22:50 -05:00

309 lines
7.7 KiB
Rust

// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
mod in_memory_fs;
mod interface;
mod ops;
mod std_fs;
pub mod sync;
pub use crate::in_memory_fs::InMemoryFs;
pub use crate::interface::AccessCheckCb;
pub use crate::interface::AccessCheckFn;
pub use crate::interface::FileSystem;
pub use crate::interface::FileSystemRc;
pub use crate::interface::FsDirEntry;
pub use crate::interface::FsFileType;
pub use crate::interface::OpenOptions;
pub use crate::ops::FsOpsError;
pub use crate::ops::FsOpsErrorKind;
pub use crate::ops::OperationError;
pub use crate::std_fs::RealFs;
pub use crate::sync::MaybeSend;
pub use crate::sync::MaybeSync;
use crate::ops::*;
use deno_io::fs::FsError;
use deno_permissions::PermissionCheckError;
use std::borrow::Cow;
use std::path::Path;
use std::path::PathBuf;
pub trait FsPermissions {
fn check_open<'a>(
&mut self,
resolved: bool,
read: bool,
write: bool,
path: &'a Path,
api_name: &str,
) -> Result<std::borrow::Cow<'a, Path>, FsError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_read_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
) -> Result<Cow<'a, Path>, PermissionCheckError>;
fn check_read_all(
&mut self,
api_name: &str,
) -> Result<(), PermissionCheckError>;
fn check_read_blind(
&mut self,
p: &Path,
display: &str,
api_name: &str,
) -> Result<(), PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
) -> Result<Cow<'a, Path>, PermissionCheckError>;
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
fn check_write_partial(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError>;
fn check_write_all(
&mut self,
api_name: &str,
) -> Result<(), PermissionCheckError>;
fn check_write_blind(
&mut self,
p: &Path,
display: &str,
api_name: &str,
) -> Result<(), PermissionCheckError>;
fn check<'a>(
&mut self,
resolved: bool,
open_options: &OpenOptions,
path: &'a Path,
api_name: &str,
) -> Result<std::borrow::Cow<'a, Path>, FsError> {
self.check_open(
resolved,
open_options.read,
open_options.write || open_options.append,
path,
api_name,
)
}
}
impl FsPermissions for deno_permissions::PermissionsContainer {
fn check_open<'a>(
&mut self,
resolved: bool,
read: bool,
write: bool,
path: &'a Path,
api_name: &str,
) -> Result<Cow<'a, Path>, FsError> {
if resolved {
self
.check_special_file(path, api_name)
.map_err(FsError::NotCapable)?;
return Ok(Cow::Borrowed(path));
}
// If somehow read or write aren't specified, use read
let read = read || !write;
let mut path: Cow<'a, Path> = Cow::Borrowed(path);
if read {
let resolved_path = FsPermissions::check_read_path(self, &path, api_name)
.map_err(|_| FsError::NotCapable("read"))?;
if let Cow::Owned(resolved_path) = resolved_path {
path = Cow::Owned(resolved_path);
}
}
if write {
let resolved_path =
FsPermissions::check_write_path(self, &path, api_name)
.map_err(|_| FsError::NotCapable("write"))?;
if let Cow::Owned(resolved_path) = resolved_path {
path = Cow::Owned(resolved_path);
}
}
Ok(path)
}
fn check_read(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
}
fn check_read_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_path(
self,
path,
Some(api_name),
)
}
fn check_read_blind(
&mut self,
path: &Path,
display: &str,
api_name: &str,
) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_blind(
self, path, display, api_name,
)
}
fn check_write(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
}
fn check_write_path<'a>(
&mut self,
path: &'a Path,
api_name: &str,
) -> Result<Cow<'a, Path>, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_path(
self, path, api_name,
)
}
fn check_write_partial(
&mut self,
path: &str,
api_name: &str,
) -> Result<PathBuf, PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_partial(
self, path, api_name,
)
}
fn check_write_blind(
&mut self,
p: &Path,
display: &str,
api_name: &str,
) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_blind(
self, p, display, api_name,
)
}
fn check_read_all(
&mut self,
api_name: &str,
) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_read_all(self, api_name)
}
fn check_write_all(
&mut self,
api_name: &str,
) -> Result<(), PermissionCheckError> {
deno_permissions::PermissionsContainer::check_write_all(self, api_name)
}
}
pub const UNSTABLE_FEATURE_NAME: &str = "fs";
deno_core::extension!(deno_fs,
deps = [ deno_web ],
parameters = [P: FsPermissions],
ops = [
op_fs_cwd<P>,
op_fs_umask,
op_fs_chdir<P>,
op_fs_open_sync<P>,
op_fs_open_async<P>,
op_fs_mkdir_sync<P>,
op_fs_mkdir_async<P>,
op_fs_chmod_sync<P>,
op_fs_chmod_async<P>,
op_fs_chown_sync<P>,
op_fs_chown_async<P>,
op_fs_remove_sync<P>,
op_fs_remove_async<P>,
op_fs_copy_file_sync<P>,
op_fs_copy_file_async<P>,
op_fs_stat_sync<P>,
op_fs_stat_async<P>,
op_fs_lstat_sync<P>,
op_fs_lstat_async<P>,
op_fs_realpath_sync<P>,
op_fs_realpath_async<P>,
op_fs_read_dir_sync<P>,
op_fs_read_dir_async<P>,
op_fs_rename_sync<P>,
op_fs_rename_async<P>,
op_fs_link_sync<P>,
op_fs_link_async<P>,
op_fs_symlink_sync<P>,
op_fs_symlink_async<P>,
op_fs_read_link_sync<P>,
op_fs_read_link_async<P>,
op_fs_truncate_sync<P>,
op_fs_truncate_async<P>,
op_fs_utime_sync<P>,
op_fs_utime_async<P>,
op_fs_make_temp_dir_sync<P>,
op_fs_make_temp_dir_async<P>,
op_fs_make_temp_file_sync<P>,
op_fs_make_temp_file_async<P>,
op_fs_write_file_sync<P>,
op_fs_write_file_async<P>,
op_fs_read_file_sync<P>,
op_fs_read_file_async<P>,
op_fs_read_file_text_sync<P>,
op_fs_read_file_text_async<P>,
op_fs_seek_sync,
op_fs_seek_async,
op_fs_file_sync_data_sync,
op_fs_file_sync_data_async,
op_fs_file_sync_sync,
op_fs_file_sync_async,
op_fs_file_stat_sync,
op_fs_file_stat_async,
op_fs_flock_async,
op_fs_flock_sync,
op_fs_funlock_async,
op_fs_funlock_sync,
op_fs_ftruncate_sync,
op_fs_file_truncate_async,
op_fs_futime_sync,
op_fs_futime_async,
],
esm = [ "30_fs.js" ],
options = {
fs: FileSystemRc,
},
state = |state, options| {
state.put(options.fs);
},
);