mirror of
https://github.com/denoland/deno.git
synced 2025-01-07 06:46:59 -05:00
Merge branch 'main' into cjs_suggestions_for_mjs
This commit is contained in:
commit
63115d2960
96 changed files with 1467 additions and 962 deletions
|
@ -68,7 +68,7 @@
|
|||
"third_party"
|
||||
],
|
||||
"plugins": [
|
||||
"https://plugins.dprint.dev/typescript-0.93.1.wasm",
|
||||
"https://plugins.dprint.dev/typescript-0.93.2.wasm",
|
||||
"https://plugins.dprint.dev/json-0.19.4.wasm",
|
||||
"https://plugins.dprint.dev/markdown-0.17.8.wasm",
|
||||
"https://plugins.dprint.dev/toml-0.6.3.wasm",
|
||||
|
|
4
.github/workflows/ci.generate.ts
vendored
4
.github/workflows/ci.generate.ts
vendored
|
@ -14,6 +14,7 @@ const windowsX86Runner = "windows-2022";
|
|||
const windowsX86XlRunner = "windows-2022-xl";
|
||||
const macosX86Runner = "macos-13";
|
||||
const macosArmRunner = "macos-14";
|
||||
const selfHostedMacosArmRunner = "self-hosted";
|
||||
|
||||
const Runners = {
|
||||
linuxX86: {
|
||||
|
@ -40,7 +41,8 @@ const Runners = {
|
|||
macosArm: {
|
||||
os: "macos",
|
||||
arch: "aarch64",
|
||||
runner: macosArmRunner,
|
||||
runner:
|
||||
`\${{ github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`,
|
||||
},
|
||||
windowsX86: {
|
||||
os: "windows",
|
||||
|
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
@ -68,12 +68,12 @@ jobs:
|
|||
skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}'
|
||||
- os: macos
|
||||
arch: aarch64
|
||||
runner: macos-14
|
||||
runner: '${{ github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}'
|
||||
job: test
|
||||
profile: debug
|
||||
- os: macos
|
||||
arch: aarch64
|
||||
runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || ''macos-14'' }}'
|
||||
runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}'
|
||||
job: test
|
||||
profile: release
|
||||
skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}'
|
||||
|
|
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -1387,9 +1387,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.37.2"
|
||||
version = "0.38.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5900bfb37538d83b19ba0b157cdc785770e38422ee4632411e3bd3d90ac0f537"
|
||||
checksum = "966825073480a6ac7e01977a3879d13edc8d6ea2d65ea164b37156a5fb206e9a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_package_json",
|
||||
|
@ -1418,9 +1418,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_core"
|
||||
version = "0.316.0"
|
||||
version = "0.318.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94f68061c88ced959c6b0417f0f0d0b3dbeaeb18013b55f86c505e9fba705cf8"
|
||||
checksum = "10cae2393219ff9278123f7b24799cdfab37c7d6561b69ca06ced115cac92111"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
|
@ -1921,9 +1921,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.192.0"
|
||||
version = "0.194.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdb7096887508456349d7e7e09e326d157d4dba46ef1f5849bc544592ea3042a"
|
||||
checksum = "f760b492bd638c1dc3e992d11672c259fbe9a233162099a8347591c9e22d0391"
|
||||
dependencies = [
|
||||
"proc-macro-rules",
|
||||
"proc-macro2",
|
||||
|
@ -1972,6 +1972,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"which 4.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -2608,9 +2609,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.93.1"
|
||||
version = "0.93.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5abfd78fe3cde4f5a6699d65f760c8d44da130cf446b6f80a7a9bc6580e156ab"
|
||||
checksum = "3ff29fd136541e59d51946f0d2d353fefc886776f61a799ebfb5838b06cef13b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
|
@ -6169,9 +6170,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_v8"
|
||||
version = "0.225.0"
|
||||
version = "0.227.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce4b71200ef49a9e629edaea3d13fc98c25ede07e1496558df7f09354e37976f"
|
||||
checksum = "0a8294c2223c53bed343be8b80564ece4dc0d03b643b06fa86c4ccc0e064eda0"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
|
|
|
@ -46,7 +46,7 @@ repository = "https://github.com/denoland/deno"
|
|||
|
||||
[workspace.dependencies]
|
||||
deno_ast = { version = "=0.43.3", features = ["transpiling"] }
|
||||
deno_core = { version = "0.316.0" }
|
||||
deno_core = { version = "0.318.0" }
|
||||
|
||||
deno_bench_util = { version = "0.169.0", path = "./bench_util" }
|
||||
deno_lockfile = "=0.23.1"
|
||||
|
|
|
@ -70,7 +70,7 @@ winres.workspace = true
|
|||
[dependencies]
|
||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||
deno_cache_dir = { workspace = true }
|
||||
deno_config = { version = "=0.37.2", features = ["workspace", "sync"] }
|
||||
deno_config = { version = "=0.38.2", features = ["workspace", "sync"] }
|
||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "0.156.0", default-features = false, features = ["rust", "html", "syntect"] }
|
||||
deno_graph = { version = "=0.84.1" }
|
||||
|
@ -107,7 +107,7 @@ dotenvy = "0.15.7"
|
|||
dprint-plugin-json = "=0.19.4"
|
||||
dprint-plugin-jupyter = "=0.1.5"
|
||||
dprint-plugin-markdown = "=0.17.8"
|
||||
dprint-plugin-typescript = "=0.93.1"
|
||||
dprint-plugin-typescript = "=0.93.2"
|
||||
env_logger = "=0.10.0"
|
||||
fancy-regex = "=0.10.0"
|
||||
faster-hex.workspace = true
|
||||
|
|
|
@ -3388,8 +3388,7 @@ fn permission_args(app: Command, requires: Option<&'static str>) -> Command {
|
|||
.value_name("IP_OR_HOSTNAME")
|
||||
.help("Allow network access. Optionally specify allowed IP addresses and host names, with ports as necessary")
|
||||
.value_parser(flags_net::validator)
|
||||
.hide(true)
|
||||
;
|
||||
.hide(true);
|
||||
if let Some(requires) = requires {
|
||||
arg = arg.requires(requires)
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
|
|||
}
|
||||
} else {
|
||||
NetDescriptor::parse(&host_and_port).map_err(|e| {
|
||||
clap::Error::raw(clap::error::ErrorKind::InvalidValue, format!("{e:?}"))
|
||||
clap::Error::raw(clap::error::ErrorKind::InvalidValue, e.to_string())
|
||||
})?;
|
||||
out.push(host_and_port)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
? Deno.args
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
? Deno.args
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
? Deno.args
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-console
|
||||
// deno-lint-ignore-file no-console no-process-globals
|
||||
|
||||
const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
|
||||
let [total, count] = typeof Deno !== "undefined"
|
||||
|
|
|
@ -863,7 +863,10 @@ impl Inner {
|
|||
// We ignore these directories by default because there is a
|
||||
// high likelihood they aren't relevant. Someone can opt-into
|
||||
// them by specifying one of them as an enabled path.
|
||||
if matches!(dir_name.as_str(), "vendor" | "node_modules" | ".git") {
|
||||
if matches!(
|
||||
dir_name.as_str(),
|
||||
"vendor" | "coverage" | "node_modules" | ".git"
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
// ignore cargo target directories for anyone using Deno with Rust
|
||||
|
@ -3944,7 +3947,9 @@ mod tests {
|
|||
fn test_walk_workspace() {
|
||||
let temp_dir = TempDir::new();
|
||||
temp_dir.create_dir_all("root1/vendor/");
|
||||
temp_dir.create_dir_all("root1/coverage/");
|
||||
temp_dir.write("root1/vendor/mod.ts", ""); // no, vendor
|
||||
temp_dir.write("root1/coverage/mod.ts", ""); // no, coverage
|
||||
|
||||
temp_dir.create_dir_all("root1/node_modules/");
|
||||
temp_dir.write("root1/node_modules/mod.ts", ""); // no, node_modules
|
||||
|
|
|
@ -89,7 +89,7 @@ impl CliNpmResolver for CliByonmNpmResolver {
|
|||
.components()
|
||||
.any(|c| c.as_os_str().to_ascii_lowercase() == "node_modules")
|
||||
{
|
||||
permissions.check_read_path(path)
|
||||
permissions.check_read_path(path).map_err(Into::into)
|
||||
} else {
|
||||
Ok(Cow::Borrowed(path))
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ impl RegistryReadPermissionChecker {
|
|||
}
|
||||
}
|
||||
|
||||
permissions.check_read_path(path)
|
||||
permissions.check_read_path(path).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1035,12 +1035,18 @@ fn junction_or_symlink_dir(
|
|||
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
|
||||
{
|
||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
junction::create(old_path, new_path).map_err(Into::into)
|
||||
junction::create(old_path, new_path)
|
||||
.context("Failed creating junction in node_modules folder")
|
||||
}
|
||||
Err(symlink_err) => {
|
||||
log::warn!(
|
||||
"{} Unexpected error symlinking node_modules: {symlink_err}",
|
||||
colors::yellow("Warning")
|
||||
);
|
||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
junction::create(old_path, new_path)
|
||||
.context("Failed creating junction in node_modules folder")
|
||||
}
|
||||
Err(symlink_err) => Err(
|
||||
AnyError::from(symlink_err)
|
||||
.context("Failed creating symlink in node_modules folder"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -353,6 +353,21 @@ fn format_yaml(
|
|||
file_text: &str,
|
||||
fmt_options: &FmtOptionsConfig,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let ignore_file = file_text
|
||||
.lines()
|
||||
.take_while(|line| line.starts_with('#'))
|
||||
.any(|line| {
|
||||
line
|
||||
.strip_prefix('#')
|
||||
.unwrap()
|
||||
.trim()
|
||||
.starts_with("deno-fmt-ignore-file")
|
||||
});
|
||||
|
||||
if ignore_file {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let formatted_str =
|
||||
pretty_yaml::format_text(file_text, &get_resolved_yaml_config(fmt_options))
|
||||
.map_err(AnyError::from)?;
|
||||
|
|
|
@ -645,10 +645,12 @@ impl<'a> GraphDisplayContext<'a> {
|
|||
let message = match err {
|
||||
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
|
||||
Decode(_) => "(loading decode error)",
|
||||
Loader(err) => match deno_core::error::get_custom_error_class(err) {
|
||||
Some("NotCapable") => "(not capable, requires --allow-import)",
|
||||
_ => "(loading error)",
|
||||
},
|
||||
Loader(err) => {
|
||||
match deno_runtime::errors::get_error_class_name(err) {
|
||||
Some("NotCapable") => "(not capable, requires --allow-import)",
|
||||
_ => "(loading error)",
|
||||
}
|
||||
}
|
||||
Jsr(_) => "(loading error)",
|
||||
NodeUnknownBuiltinModule(_) => "(unknown node built-in error)",
|
||||
Npm(_) => "(npm loading error)",
|
||||
|
|
|
@ -12,7 +12,9 @@ use deno_core::futures::StreamExt;
|
|||
use deno_path_util::url_to_file_path;
|
||||
use deno_semver::jsr::JsrPackageReqReference;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::package::PackageReq;
|
||||
use deno_semver::Version;
|
||||
use deno_semver::VersionReq;
|
||||
use jsonc_parser::cst::CstObject;
|
||||
use jsonc_parser::cst::CstObjectProp;
|
||||
|
@ -455,15 +457,32 @@ pub async fn add(
|
|||
match package_and_version {
|
||||
PackageAndVersion::NotFound {
|
||||
package: package_name,
|
||||
found_npm_package,
|
||||
help,
|
||||
package_req,
|
||||
} => {
|
||||
if found_npm_package {
|
||||
bail!("{} was not found, but a matching npm package exists. Did you mean `{}`?", crate::colors::red(package_name), crate::colors::yellow(format!("deno {cmd_name} npm:{package_req}")));
|
||||
} else {
|
||||
bail!("{} was not found.", crate::colors::red(package_name));
|
||||
} => match help {
|
||||
Some(NotFoundHelp::NpmPackage) => {
|
||||
bail!(
|
||||
"{} was not found, but a matching npm package exists. Did you mean `{}`?",
|
||||
crate::colors::red(package_name),
|
||||
crate::colors::yellow(format!("deno {cmd_name} npm:{package_req}"))
|
||||
);
|
||||
}
|
||||
}
|
||||
Some(NotFoundHelp::JsrPackage) => {
|
||||
bail!(
|
||||
"{} was not found, but a matching jsr package exists. Did you mean `{}`?",
|
||||
crate::colors::red(package_name),
|
||||
crate::colors::yellow(format!("deno {cmd_name} jsr:{package_req}"))
|
||||
)
|
||||
}
|
||||
Some(NotFoundHelp::PreReleaseVersion(version)) => {
|
||||
bail!(
|
||||
"{} has only pre-release versions available. Try specifying a version: `{}`",
|
||||
crate::colors::red(&package_name),
|
||||
crate::colors::yellow(format!("deno {cmd_name} {package_name}@^{version}"))
|
||||
)
|
||||
}
|
||||
None => bail!("{} was not found.", crate::colors::red(package_name)),
|
||||
},
|
||||
PackageAndVersion::Selected(selected) => {
|
||||
selected_packages.push(selected);
|
||||
}
|
||||
|
@ -511,76 +530,144 @@ struct SelectedPackage {
|
|||
selected_version: String,
|
||||
}
|
||||
|
||||
enum NotFoundHelp {
|
||||
NpmPackage,
|
||||
JsrPackage,
|
||||
PreReleaseVersion(Version),
|
||||
}
|
||||
|
||||
enum PackageAndVersion {
|
||||
NotFound {
|
||||
package: String,
|
||||
found_npm_package: bool,
|
||||
package_req: PackageReq,
|
||||
help: Option<NotFoundHelp>,
|
||||
},
|
||||
Selected(SelectedPackage),
|
||||
}
|
||||
|
||||
fn best_version<'a>(
|
||||
versions: impl Iterator<Item = &'a Version>,
|
||||
) -> Option<&'a Version> {
|
||||
let mut maybe_best_version: Option<&Version> = None;
|
||||
for version in versions {
|
||||
let is_best_version = maybe_best_version
|
||||
.as_ref()
|
||||
.map(|best_version| (*best_version).cmp(version).is_lt())
|
||||
.unwrap_or(true);
|
||||
if is_best_version {
|
||||
maybe_best_version = Some(version);
|
||||
}
|
||||
}
|
||||
maybe_best_version
|
||||
}
|
||||
|
||||
trait PackageInfoProvider {
|
||||
const SPECIFIER_PREFIX: &str;
|
||||
/// The help to return if a package is found by this provider
|
||||
const HELP: NotFoundHelp;
|
||||
async fn req_to_nv(&self, req: &PackageReq) -> Option<PackageNv>;
|
||||
async fn latest_version<'a>(&self, req: &PackageReq) -> Option<Version>;
|
||||
}
|
||||
|
||||
impl PackageInfoProvider for Arc<JsrFetchResolver> {
|
||||
const HELP: NotFoundHelp = NotFoundHelp::JsrPackage;
|
||||
const SPECIFIER_PREFIX: &str = "jsr";
|
||||
async fn req_to_nv(&self, req: &PackageReq) -> Option<PackageNv> {
|
||||
(**self).req_to_nv(req).await
|
||||
}
|
||||
|
||||
async fn latest_version<'a>(&self, req: &PackageReq) -> Option<Version> {
|
||||
let info = self.package_info(&req.name).await?;
|
||||
best_version(
|
||||
info
|
||||
.versions
|
||||
.iter()
|
||||
.filter(|(_, version_info)| !version_info.yanked)
|
||||
.map(|(version, _)| version),
|
||||
)
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl PackageInfoProvider for Arc<NpmFetchResolver> {
|
||||
const HELP: NotFoundHelp = NotFoundHelp::NpmPackage;
|
||||
const SPECIFIER_PREFIX: &str = "npm";
|
||||
async fn req_to_nv(&self, req: &PackageReq) -> Option<PackageNv> {
|
||||
(**self).req_to_nv(req).await
|
||||
}
|
||||
|
||||
async fn latest_version<'a>(&self, req: &PackageReq) -> Option<Version> {
|
||||
let info = self.package_info(&req.name).await?;
|
||||
best_version(info.versions.keys()).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_package_and_select_version_for_req(
|
||||
jsr_resolver: Arc<JsrFetchResolver>,
|
||||
npm_resolver: Arc<NpmFetchResolver>,
|
||||
add_package_req: AddRmPackageReq,
|
||||
) -> Result<PackageAndVersion, AnyError> {
|
||||
match add_package_req.value {
|
||||
AddRmPackageReqValue::Jsr(req) => {
|
||||
let jsr_prefixed_name = format!("jsr:{}", &req.name);
|
||||
let Some(nv) = jsr_resolver.req_to_nv(&req).await else {
|
||||
if npm_resolver.req_to_nv(&req).await.is_some() {
|
||||
async fn select<T: PackageInfoProvider, S: PackageInfoProvider>(
|
||||
main_resolver: T,
|
||||
fallback_resolver: S,
|
||||
add_package_req: AddRmPackageReq,
|
||||
) -> Result<PackageAndVersion, AnyError> {
|
||||
let req = match &add_package_req.value {
|
||||
AddRmPackageReqValue::Jsr(req) => req,
|
||||
AddRmPackageReqValue::Npm(req) => req,
|
||||
};
|
||||
let prefixed_name = format!("{}:{}", T::SPECIFIER_PREFIX, req.name);
|
||||
let help_if_found_in_fallback = S::HELP;
|
||||
let Some(nv) = main_resolver.req_to_nv(req).await else {
|
||||
if fallback_resolver.req_to_nv(req).await.is_some() {
|
||||
// it's in the other registry
|
||||
return Ok(PackageAndVersion::NotFound {
|
||||
package: prefixed_name,
|
||||
help: Some(help_if_found_in_fallback),
|
||||
package_req: req.clone(),
|
||||
});
|
||||
}
|
||||
if req.version_req.version_text() == "*" {
|
||||
if let Some(pre_release_version) =
|
||||
main_resolver.latest_version(req).await
|
||||
{
|
||||
return Ok(PackageAndVersion::NotFound {
|
||||
package: jsr_prefixed_name,
|
||||
found_npm_package: true,
|
||||
package_req: req,
|
||||
package: prefixed_name,
|
||||
package_req: req.clone(),
|
||||
help: Some(NotFoundHelp::PreReleaseVersion(
|
||||
pre_release_version.clone(),
|
||||
)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(PackageAndVersion::NotFound {
|
||||
package: jsr_prefixed_name,
|
||||
found_npm_package: false,
|
||||
package_req: req,
|
||||
});
|
||||
};
|
||||
let range_symbol = if req.version_req.version_text().starts_with('~') {
|
||||
"~"
|
||||
} else if req.version_req.version_text() == nv.version.to_string() {
|
||||
""
|
||||
} else {
|
||||
"^"
|
||||
};
|
||||
Ok(PackageAndVersion::Selected(SelectedPackage {
|
||||
import_name: add_package_req.alias,
|
||||
package_name: jsr_prefixed_name,
|
||||
version_req: format!("{}{}", range_symbol, &nv.version),
|
||||
selected_version: nv.version.to_string(),
|
||||
}))
|
||||
return Ok(PackageAndVersion::NotFound {
|
||||
package: prefixed_name,
|
||||
help: None,
|
||||
package_req: req.clone(),
|
||||
});
|
||||
};
|
||||
let range_symbol = if req.version_req.version_text().starts_with('~') {
|
||||
"~"
|
||||
} else if req.version_req.version_text() == nv.version.to_string() {
|
||||
""
|
||||
} else {
|
||||
"^"
|
||||
};
|
||||
Ok(PackageAndVersion::Selected(SelectedPackage {
|
||||
import_name: add_package_req.alias,
|
||||
package_name: prefixed_name,
|
||||
version_req: format!("{}{}", range_symbol, &nv.version),
|
||||
selected_version: nv.version.to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
match &add_package_req.value {
|
||||
AddRmPackageReqValue::Jsr(_) => {
|
||||
select(jsr_resolver, npm_resolver, add_package_req).await
|
||||
}
|
||||
AddRmPackageReqValue::Npm(req) => {
|
||||
let npm_prefixed_name = format!("npm:{}", &req.name);
|
||||
let Some(nv) = npm_resolver.req_to_nv(&req).await else {
|
||||
return Ok(PackageAndVersion::NotFound {
|
||||
package: npm_prefixed_name,
|
||||
found_npm_package: false,
|
||||
package_req: req,
|
||||
});
|
||||
};
|
||||
|
||||
let range_symbol = if req.version_req.version_text().starts_with('~') {
|
||||
"~"
|
||||
} else if req.version_req.version_text() == nv.version.to_string() {
|
||||
""
|
||||
} else {
|
||||
"^"
|
||||
};
|
||||
|
||||
Ok(PackageAndVersion::Selected(SelectedPackage {
|
||||
import_name: add_package_req.alias,
|
||||
package_name: npm_prefixed_name,
|
||||
version_req: format!("{}{}", range_symbol, &nv.version),
|
||||
selected_version: nv.version.to_string(),
|
||||
}))
|
||||
AddRmPackageReqValue::Npm(_) => {
|
||||
select(npm_resolver, jsr_resolver, add_package_req).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -801,13 +801,18 @@ delete Object.prototype.__proto__;
|
|||
if (logDebug) {
|
||||
debug(`host.getScriptSnapshot("${specifier}")`);
|
||||
}
|
||||
const sourceFile = sourceFileCache.get(specifier);
|
||||
if (sourceFile) {
|
||||
if (!assetScopes.has(specifier)) {
|
||||
assetScopes.set(specifier, lastRequestScope);
|
||||
if (specifier.startsWith(ASSETS_URL_PREFIX)) {
|
||||
const sourceFile = this.getSourceFile(
|
||||
specifier,
|
||||
ts.ScriptTarget.ESNext,
|
||||
);
|
||||
if (sourceFile) {
|
||||
if (!assetScopes.has(specifier)) {
|
||||
assetScopes.set(specifier, lastRequestScope);
|
||||
}
|
||||
// This case only occurs for assets.
|
||||
return ts.ScriptSnapshot.fromString(sourceFile.text);
|
||||
}
|
||||
// This case only occurs for assets.
|
||||
return ts.ScriptSnapshot.fromString(sourceFile.text);
|
||||
}
|
||||
let sourceText = sourceTextCache.get(specifier);
|
||||
if (sourceText == undefined) {
|
||||
|
|
37
cli/tsc/dts/lib.deno.ns.d.ts
vendored
37
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -556,14 +556,23 @@ declare namespace Deno {
|
|||
*/
|
||||
env?: "inherit" | boolean | string[];
|
||||
|
||||
/** Specifies if the `sys` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `sys` permission will be inherited.
|
||||
* If set to `true`, the global `sys` permission will be requested.
|
||||
* If set to `false`, the global `sys` permission will be revoked.
|
||||
/** Specifies if the `ffi` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `ffi` permission will be inherited.
|
||||
* If set to `true`, the global `ffi` permission will be requested.
|
||||
* If set to `false`, the global `ffi` permission will be revoked.
|
||||
*
|
||||
* @default {false}
|
||||
*/
|
||||
sys?: "inherit" | boolean | string[];
|
||||
ffi?: "inherit" | boolean | Array<string | URL>;
|
||||
|
||||
/** Specifies if the `import` permission should be requested or revoked.
|
||||
* If set to `"inherit"` the current `import` permission will be inherited.
|
||||
* If set to `true`, the global `import` permission will be requested.
|
||||
* If set to `false`, the global `import` permission will be revoked.
|
||||
* If set to `Array<string>`, the `import` permissions will be requested with the
|
||||
* specified domains.
|
||||
*/
|
||||
import?: "inherit" | boolean | Array<string>;
|
||||
|
||||
/** Specifies if the `net` permission should be requested or revoked.
|
||||
* if set to `"inherit"`, the current `net` permission will be inherited.
|
||||
|
@ -638,15 +647,6 @@ declare namespace Deno {
|
|||
*/
|
||||
net?: "inherit" | boolean | string[];
|
||||
|
||||
/** Specifies if the `ffi` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `ffi` permission will be inherited.
|
||||
* If set to `true`, the global `ffi` permission will be requested.
|
||||
* If set to `false`, the global `ffi` permission will be revoked.
|
||||
*
|
||||
* @default {false}
|
||||
*/
|
||||
ffi?: "inherit" | boolean | Array<string | URL>;
|
||||
|
||||
/** Specifies if the `read` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `read` permission will be inherited.
|
||||
* If set to `true`, the global `read` permission will be requested.
|
||||
|
@ -667,6 +667,15 @@ declare namespace Deno {
|
|||
*/
|
||||
run?: "inherit" | boolean | Array<string | URL>;
|
||||
|
||||
/** Specifies if the `sys` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `sys` permission will be inherited.
|
||||
* If set to `true`, the global `sys` permission will be requested.
|
||||
* If set to `false`, the global `sys` permission will be revoked.
|
||||
*
|
||||
* @default {false}
|
||||
*/
|
||||
sys?: "inherit" | boolean | string[];
|
||||
|
||||
/** Specifies if the `write` permission should be requested or revoked.
|
||||
* If set to `"inherit"`, the current `write` permission will be inherited.
|
||||
* If set to `true`, the global `write` permission will be requested.
|
||||
|
|
|
@ -565,7 +565,9 @@ pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> {
|
|||
use std::os::windows::fs::symlink_dir;
|
||||
symlink_dir(oldpath, newpath).map_err(|err| {
|
||||
if let Some(code) = err.raw_os_error() {
|
||||
if code as u32 == winapi::shared::winerror::ERROR_PRIVILEGE_NOT_HELD {
|
||||
if code as u32 == winapi::shared::winerror::ERROR_PRIVILEGE_NOT_HELD
|
||||
|| code as u32 == winapi::shared::winerror::ERROR_INVALID_FUNCTION
|
||||
{
|
||||
return err_mapper(err, Some(ErrorKind::PermissionDenied));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ use deno_core::OpState;
|
|||
use deno_core::RcRef;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use deno_tls::rustls::RootCertStore;
|
||||
use deno_tls::Proxy;
|
||||
use deno_tls::RootCertStoreProvider;
|
||||
|
@ -149,7 +150,7 @@ pub enum FetchError {
|
|||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] PermissionCheckError),
|
||||
#[error("NetworkError when attempting to fetch resource")]
|
||||
NetworkError,
|
||||
#[error("Fetching files only supports the GET method: received {0}")]
|
||||
|
@ -346,13 +347,13 @@ pub trait FetchPermissions {
|
|||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check_read<'a>(
|
||||
&mut self,
|
||||
p: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, deno_core::error::AnyError>;
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl FetchPermissions for deno_permissions::PermissionsContainer {
|
||||
|
@ -361,7 +362,7 @@ impl FetchPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
|
||||
}
|
||||
|
||||
|
@ -370,7 +371,7 @@ impl FetchPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, deno_core::error::AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read_path(
|
||||
self,
|
||||
path,
|
||||
|
@ -414,9 +415,7 @@ where
|
|||
"file" => {
|
||||
let path = url.to_file_path().map_err(|_| FetchError::NetworkError)?;
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
let path = permissions
|
||||
.check_read(&path, "fetch()")
|
||||
.map_err(FetchError::Permission)?;
|
||||
let path = permissions.check_read(&path, "fetch()")?;
|
||||
let url = match path {
|
||||
Cow::Owned(path) => Url::from_file_path(path).unwrap(),
|
||||
Cow::Borrowed(_) => url,
|
||||
|
@ -442,9 +441,7 @@ where
|
|||
}
|
||||
"http" | "https" => {
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_net_url(&url, "fetch()")
|
||||
.map_err(FetchError::Resource)?;
|
||||
permissions.check_net_url(&url, "fetch()")?;
|
||||
|
||||
let maybe_authority = extract_authority(&mut url);
|
||||
let uri = url
|
||||
|
@ -863,9 +860,7 @@ where
|
|||
if let Some(proxy) = args.proxy.clone() {
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
let url = Url::parse(&proxy.url)?;
|
||||
permissions
|
||||
.check_net_url(&url, "Deno.createHttpClient()")
|
||||
.map_err(FetchError::Permission)?;
|
||||
permissions.check_net_url(&url, "Deno.createHttpClient()")?;
|
||||
}
|
||||
|
||||
let options = state.borrow::<Options>();
|
||||
|
|
|
@ -32,7 +32,9 @@ pub enum CallError {
|
|||
#[error("Invalid FFI symbol name: '{0}'")]
|
||||
InvalidSymbol(String),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
Callback(#[from] super::CallbackError),
|
||||
}
|
||||
|
@ -301,9 +303,7 @@ where
|
|||
{
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(CallError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
};
|
||||
|
||||
let symbol = PtrSymbol::new(pointer, &def)?;
|
||||
|
@ -347,7 +347,7 @@ pub fn op_ffi_call_nonblocking(
|
|||
let resource = state
|
||||
.resource_table
|
||||
.get::<DynamicLibraryResource>(rid)
|
||||
.map_err(CallError::Permission)?;
|
||||
.map_err(CallError::Resource)?;
|
||||
let symbols = &resource.symbols;
|
||||
*symbols
|
||||
.get(&symbol)
|
||||
|
@ -401,9 +401,7 @@ where
|
|||
{
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(CallError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
};
|
||||
|
||||
let symbol = PtrSymbol::new(pointer, &def)?;
|
||||
|
|
|
@ -38,7 +38,7 @@ pub enum CallbackError {
|
|||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
}
|
||||
|
@ -572,9 +572,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(CallbackError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
let thread_id: u32 = LOCAL_THREAD_ID.with(|s| {
|
||||
let value = *s.borrow();
|
||||
|
|
|
@ -30,7 +30,7 @@ pub enum DlfcnError {
|
|||
#[error(transparent)]
|
||||
Dlopen(#[from] dlopen2::Error),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
}
|
||||
|
@ -133,9 +133,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
let path = permissions
|
||||
.check_partial_with_path(&args.path)
|
||||
.map_err(DlfcnError::Permission)?;
|
||||
let path = permissions.check_partial_with_path(&args.path)?;
|
||||
|
||||
let lib = Library::open(&path).map_err(|e| {
|
||||
dlopen2::Error::OpeningLibraryError(std::io::Error::new(
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::c_short;
|
||||
|
@ -31,6 +29,7 @@ use symbol::Symbol;
|
|||
|
||||
pub use call::CallError;
|
||||
pub use callback::CallbackError;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
pub use dlfcn::DlfcnError;
|
||||
pub use ir::IRError;
|
||||
pub use r#static::StaticError;
|
||||
|
@ -48,17 +47,17 @@ const _: () = {
|
|||
pub const UNSTABLE_FEATURE_NAME: &str = "ffi";
|
||||
|
||||
pub trait FfiPermissions {
|
||||
fn check_partial_no_path(&mut self) -> Result<(), AnyError>;
|
||||
fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check_partial_with_path(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> Result<PathBuf, PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl FfiPermissions for deno_permissions::PermissionsContainer {
|
||||
#[inline(always)]
|
||||
fn check_partial_no_path(&mut self) -> Result<(), AnyError> {
|
||||
fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_ffi_partial_no_path(self)
|
||||
}
|
||||
|
||||
|
@ -66,7 +65,7 @@ impl FfiPermissions for deno_permissions::PermissionsContainer {
|
|||
fn check_partial_with_path(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_ffi_partial_with_path(
|
||||
self, path,
|
||||
)
|
||||
|
|
|
@ -46,7 +46,7 @@ pub enum ReprError {
|
|||
#[error("Invalid pointer pointer, pointer is null")]
|
||||
InvalidPointer,
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
|
@ -58,9 +58,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
Ok(ptr_number as *mut c_void)
|
||||
}
|
||||
|
@ -75,9 +73,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
Ok(a == b)
|
||||
}
|
||||
|
@ -91,9 +87,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
Ok(buf as *mut c_void)
|
||||
}
|
||||
|
@ -107,9 +101,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
let Some(buf) = buf.get_backing_store() else {
|
||||
return Ok(0 as _);
|
||||
|
@ -130,9 +122,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidOffset);
|
||||
|
@ -162,9 +152,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
Ok(ptr as usize)
|
||||
}
|
||||
|
@ -181,9 +169,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidArrayBuffer);
|
||||
|
@ -215,9 +201,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if src.is_null() {
|
||||
Err(ReprError::InvalidArrayBuffer)
|
||||
|
@ -246,9 +230,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidCString);
|
||||
|
@ -272,9 +254,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidBool);
|
||||
|
@ -294,9 +274,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidU8);
|
||||
|
@ -318,9 +296,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidI8);
|
||||
|
@ -342,9 +318,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidU16);
|
||||
|
@ -366,9 +340,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidI16);
|
||||
|
@ -390,9 +362,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidU32);
|
||||
|
@ -412,9 +382,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidI32);
|
||||
|
@ -437,9 +405,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidU64);
|
||||
|
@ -465,9 +431,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidI64);
|
||||
|
@ -490,9 +454,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidF32);
|
||||
|
@ -512,9 +474,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidF64);
|
||||
|
@ -534,9 +494,7 @@ where
|
|||
FP: FfiPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions
|
||||
.check_partial_no_path()
|
||||
.map_err(ReprError::Permission)?;
|
||||
permissions.check_partial_no_path()?;
|
||||
|
||||
if ptr.is_null() {
|
||||
return Err(ReprError::InvalidPointer);
|
||||
|
|
|
@ -22,8 +22,8 @@ pub use crate::sync::MaybeSync;
|
|||
|
||||
use crate::ops::*;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_io::fs::FsError;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
@ -42,45 +42,51 @@ pub trait FsPermissions {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> 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>, AnyError>;
|
||||
fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError>;
|
||||
) -> 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<(), AnyError>;
|
||||
) -> 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, AnyError>;
|
||||
) -> 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>, AnyError>;
|
||||
) -> 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, AnyError>;
|
||||
fn check_write_all(&mut self, api_name: &str) -> Result<(), AnyError>;
|
||||
) -> 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<(), AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
|
||||
fn check<'a>(
|
||||
&mut self,
|
||||
|
@ -140,7 +146,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
|
||||
}
|
||||
|
||||
|
@ -148,7 +154,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read_path(
|
||||
self,
|
||||
path,
|
||||
|
@ -160,7 +166,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
path: &Path,
|
||||
display: &str,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read_blind(
|
||||
self, path, display, api_name,
|
||||
)
|
||||
|
@ -170,7 +176,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
|
||||
}
|
||||
|
||||
|
@ -178,7 +184,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_path(
|
||||
self, path, api_name,
|
||||
)
|
||||
|
@ -188,7 +194,7 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_partial(
|
||||
self, path, api_name,
|
||||
)
|
||||
|
@ -199,17 +205,23 @@ impl FsPermissions for deno_permissions::PermissionsContainer {
|
|||
p: &Path,
|
||||
display: &str,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_blind(
|
||||
self, p, display, api_name,
|
||||
)
|
||||
}
|
||||
|
||||
fn check_read_all(&mut self, api_name: &str) -> Result<(), AnyError> {
|
||||
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<(), AnyError> {
|
||||
fn check_write_all(
|
||||
&mut self,
|
||||
api_name: &str,
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_all(self, api_name)
|
||||
}
|
||||
}
|
||||
|
|
217
ext/fs/ops.rs
217
ext/fs/ops.rs
|
@ -10,6 +10,12 @@ use std::path::PathBuf;
|
|||
use std::path::StripPrefixError;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::interface::AccessCheckFn;
|
||||
use crate::interface::FileSystemRc;
|
||||
use crate::interface::FsDirEntry;
|
||||
use crate::interface::FsFileType;
|
||||
use crate::FsPermissions;
|
||||
use crate::OpenOptions;
|
||||
use deno_core::op2;
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::CancelHandle;
|
||||
|
@ -20,18 +26,12 @@ use deno_core::ToJsBuffer;
|
|||
use deno_io::fs::FileResource;
|
||||
use deno_io::fs::FsError;
|
||||
use deno_io::fs::FsStat;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use rand::rngs::ThreadRng;
|
||||
use rand::thread_rng;
|
||||
use rand::Rng;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::interface::AccessCheckFn;
|
||||
use crate::interface::FileSystemRc;
|
||||
use crate::interface::FsDirEntry;
|
||||
use crate::interface::FsFileType;
|
||||
use crate::FsPermissions;
|
||||
use crate::OpenOptions;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum FsOpsError {
|
||||
#[error("{0}")]
|
||||
|
@ -39,7 +39,7 @@ pub enum FsOpsError {
|
|||
#[error("{0}")]
|
||||
OperationError(#[source] OperationError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error("File name or path {0:?} is not valid UTF-8")]
|
||||
|
@ -150,8 +150,7 @@ where
|
|||
let path = fs.cwd()?;
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_blind(&path, "CWD", "Deno.cwd()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read_blind(&path, "CWD", "Deno.cwd()")?;
|
||||
let path_str = path_into_string(path.into_os_string())?;
|
||||
Ok(path_str)
|
||||
}
|
||||
|
@ -166,8 +165,7 @@ where
|
|||
{
|
||||
let d = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(directory, "Deno.chdir()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(directory, "Deno.chdir()")?;
|
||||
state
|
||||
.borrow::<FileSystemRc>()
|
||||
.chdir(&d)
|
||||
|
@ -253,8 +251,7 @@ where
|
|||
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.mkdirSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(&path, "Deno.mkdirSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.mkdir_sync(&path, recursive, Some(mode))
|
||||
|
@ -277,10 +274,7 @@ where
|
|||
|
||||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.mkdir()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = state.borrow_mut::<P>().check_write(&path, "Deno.mkdir()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -302,8 +296,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.chmodSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(&path, "Deno.chmodSync()")?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.chmod_sync(&path, mode).context_path("chmod", &path)?;
|
||||
Ok(())
|
||||
|
@ -320,10 +313,7 @@ where
|
|||
{
|
||||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.chmod()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = state.borrow_mut::<P>().check_write(&path, "Deno.chmod()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
fs.chmod_async(path.clone(), mode)
|
||||
|
@ -344,8 +334,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.chownSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(&path, "Deno.chownSync()")?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.chown_sync(&path, uid, gid)
|
||||
.context_path("chown", &path)?;
|
||||
|
@ -364,10 +353,7 @@ where
|
|||
{
|
||||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.chown()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = state.borrow_mut::<P>().check_write(&path, "Deno.chown()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
fs.chown_async(path.clone(), uid, gid)
|
||||
|
@ -387,8 +373,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(path, "Deno.removeSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(path, "Deno.removeSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.remove_sync(&path, recursive)
|
||||
|
@ -411,13 +396,11 @@ where
|
|||
let path = if recursive {
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.remove()")
|
||||
.map_err(FsOpsError::Permission)?
|
||||
.check_write(&path, "Deno.remove()")?
|
||||
} else {
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_partial(&path, "Deno.remove()")
|
||||
.map_err(FsOpsError::Permission)?
|
||||
.check_write_partial(&path, "Deno.remove()")?
|
||||
};
|
||||
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
|
@ -440,12 +423,8 @@ where
|
|||
P: FsPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let from = permissions
|
||||
.check_read(from, "Deno.copyFileSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let to = permissions
|
||||
.check_write(to, "Deno.copyFileSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let from = permissions.check_read(from, "Deno.copyFileSync()")?;
|
||||
let to = permissions.check_write(to, "Deno.copyFileSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.copy_file_sync(&from, &to)
|
||||
|
@ -466,12 +445,8 @@ where
|
|||
let (fs, from, to) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let from = permissions
|
||||
.check_read(&from, "Deno.copyFile()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let to = permissions
|
||||
.check_write(&to, "Deno.copyFile()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let from = permissions.check_read(&from, "Deno.copyFile()")?;
|
||||
let to = permissions.check_write(&to, "Deno.copyFile()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), from, to)
|
||||
};
|
||||
|
||||
|
@ -493,8 +468,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.statSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.statSync()")?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
let stat = fs.stat_sync(&path).context_path("stat", &path)?;
|
||||
let serializable_stat = SerializableStat::from(stat);
|
||||
|
@ -514,9 +488,7 @@ where
|
|||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let path = permissions
|
||||
.check_read(&path, "Deno.stat()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = permissions.check_read(&path, "Deno.stat()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
let stat = fs
|
||||
|
@ -537,8 +509,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.lstatSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.lstatSync()")?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
let stat = fs.lstat_sync(&path).context_path("lstat", &path)?;
|
||||
let serializable_stat = SerializableStat::from(stat);
|
||||
|
@ -558,9 +529,7 @@ where
|
|||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let path = permissions
|
||||
.check_read(&path, "Deno.lstat()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = permissions.check_read(&path, "Deno.lstat()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
let stat = fs
|
||||
|
@ -581,13 +550,9 @@ where
|
|||
{
|
||||
let fs = state.borrow::<FileSystemRc>().clone();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let path = permissions
|
||||
.check_read(&path, "Deno.realPathSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = permissions.check_read(&path, "Deno.realPathSync()")?;
|
||||
if path.is_relative() {
|
||||
permissions
|
||||
.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPathSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPathSync()")?;
|
||||
}
|
||||
|
||||
let resolved_path =
|
||||
|
@ -610,13 +575,9 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let fs = state.borrow::<FileSystemRc>().clone();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let path = permissions
|
||||
.check_read(&path, "Deno.realPath()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = permissions.check_read(&path, "Deno.realPath()")?;
|
||||
if path.is_relative() {
|
||||
permissions
|
||||
.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPath()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions.check_read_blind(&fs.cwd()?, "CWD", "Deno.realPath()")?;
|
||||
}
|
||||
(fs, path)
|
||||
};
|
||||
|
@ -640,8 +601,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.readDirSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.readDirSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
let entries = fs.read_dir_sync(&path).context_path("readdir", &path)?;
|
||||
|
@ -662,8 +622,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.readDir()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.readDir()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -685,15 +644,9 @@ where
|
|||
P: FsPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
let _ = permissions
|
||||
.check_read(&oldpath, "Deno.renameSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let oldpath = permissions
|
||||
.check_write(&oldpath, "Deno.renameSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let newpath = permissions
|
||||
.check_write(&newpath, "Deno.renameSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let _ = permissions.check_read(&oldpath, "Deno.renameSync()")?;
|
||||
let oldpath = permissions.check_write(&oldpath, "Deno.renameSync()")?;
|
||||
let newpath = permissions.check_write(&newpath, "Deno.renameSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.rename_sync(&oldpath, &newpath)
|
||||
|
@ -714,15 +667,9 @@ where
|
|||
let (fs, oldpath, newpath) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
_ = permissions
|
||||
.check_read(&oldpath, "Deno.rename()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let oldpath = permissions
|
||||
.check_write(&oldpath, "Deno.rename()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let newpath = permissions
|
||||
.check_write(&newpath, "Deno.rename()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
_ = permissions.check_read(&oldpath, "Deno.rename()")?;
|
||||
let oldpath = permissions.check_write(&oldpath, "Deno.rename()")?;
|
||||
let newpath = permissions.check_write(&newpath, "Deno.rename()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), oldpath, newpath)
|
||||
};
|
||||
|
||||
|
@ -743,18 +690,10 @@ where
|
|||
P: FsPermissions + 'static,
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
_ = permissions
|
||||
.check_read(oldpath, "Deno.linkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let oldpath = permissions
|
||||
.check_write(oldpath, "Deno.linkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
_ = permissions
|
||||
.check_read(newpath, "Deno.linkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let newpath = permissions
|
||||
.check_write(newpath, "Deno.linkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
_ = permissions.check_read(oldpath, "Deno.linkSync()")?;
|
||||
let oldpath = permissions.check_write(oldpath, "Deno.linkSync()")?;
|
||||
_ = permissions.check_read(newpath, "Deno.linkSync()")?;
|
||||
let newpath = permissions.check_write(newpath, "Deno.linkSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.link_sync(&oldpath, &newpath)
|
||||
|
@ -775,18 +714,10 @@ where
|
|||
let (fs, oldpath, newpath) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
_ = permissions
|
||||
.check_read(&oldpath, "Deno.link()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let oldpath = permissions
|
||||
.check_write(&oldpath, "Deno.link()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
_ = permissions
|
||||
.check_read(&newpath, "Deno.link()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let newpath = permissions
|
||||
.check_write(&newpath, "Deno.link()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
_ = permissions.check_read(&oldpath, "Deno.link()")?;
|
||||
let oldpath = permissions.check_write(&oldpath, "Deno.link()")?;
|
||||
_ = permissions.check_read(&newpath, "Deno.link()")?;
|
||||
let newpath = permissions.check_write(&newpath, "Deno.link()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), oldpath, newpath)
|
||||
};
|
||||
|
||||
|
@ -811,12 +742,8 @@ where
|
|||
let newpath = PathBuf::from(newpath);
|
||||
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_write_all("Deno.symlinkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions
|
||||
.check_read_all("Deno.symlinkSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions.check_write_all("Deno.symlinkSync()")?;
|
||||
permissions.check_read_all("Deno.symlinkSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.symlink_sync(&oldpath, &newpath, file_type)
|
||||
|
@ -841,12 +768,8 @@ where
|
|||
let fs = {
|
||||
let mut state = state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_write_all("Deno.symlink()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions
|
||||
.check_read_all("Deno.symlink()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
permissions.check_write_all("Deno.symlink()")?;
|
||||
permissions.check_read_all("Deno.symlink()")?;
|
||||
state.borrow::<FileSystemRc>().clone()
|
||||
};
|
||||
|
||||
|
@ -868,8 +791,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.readLink()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.readLink()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
|
||||
|
@ -891,8 +813,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read(&path, "Deno.readLink()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_read(&path, "Deno.readLink()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -915,8 +836,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(path, "Deno.truncateSync()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(path, "Deno.truncateSync()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.truncate_sync(&path, len)
|
||||
|
@ -938,8 +858,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.truncate()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write(&path, "Deno.truncate()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -962,10 +881,7 @@ pub fn op_fs_utime_sync<P>(
|
|||
where
|
||||
P: FsPermissions + 'static,
|
||||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(path, "Deno.utime()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = state.borrow_mut::<P>().check_write(path, "Deno.utime()")?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.utime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)
|
||||
|
@ -988,10 +904,7 @@ where
|
|||
{
|
||||
let (fs, path) = {
|
||||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(&path, "Deno.utime()")
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
let path = state.borrow_mut::<P>().check_write(&path, "Deno.utime()")?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -1219,16 +1132,12 @@ where
|
|||
{
|
||||
let fs = state.borrow::<FileSystemRc>().clone();
|
||||
let dir = match dir {
|
||||
Some(dir) => state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(dir, api_name)
|
||||
.map_err(FsOpsError::Permission)?,
|
||||
Some(dir) => state.borrow_mut::<P>().check_write(dir, api_name)?,
|
||||
None => {
|
||||
let dir = fs.tmp_dir().context("tmpdir")?;
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_blind(&dir, "TMP", api_name)
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write_blind(&dir, "TMP", api_name)?;
|
||||
dir
|
||||
}
|
||||
};
|
||||
|
@ -1246,16 +1155,12 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let fs = state.borrow::<FileSystemRc>().clone();
|
||||
let dir = match dir {
|
||||
Some(dir) => state
|
||||
.borrow_mut::<P>()
|
||||
.check_write(dir, api_name)
|
||||
.map_err(FsOpsError::Permission)?,
|
||||
Some(dir) => state.borrow_mut::<P>().check_write(dir, api_name)?,
|
||||
None => {
|
||||
let dir = fs.tmp_dir().context("tmpdir")?;
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_blind(&dir, "TMP", api_name)
|
||||
.map_err(FsOpsError::Permission)?;
|
||||
.check_write_blind(&dir, "TMP", api_name)?;
|
||||
dir
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ use deno_core::futures::Stream;
|
|||
use deno_core::OpState;
|
||||
use deno_fetch::create_http_client;
|
||||
use deno_fetch::CreateHttpClientOptions;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use deno_tls::rustls::RootCertStore;
|
||||
use deno_tls::Proxy;
|
||||
use deno_tls::RootCertStoreProvider;
|
||||
|
@ -45,17 +46,17 @@ impl HttpOptions {
|
|||
}
|
||||
|
||||
pub trait RemoteDbHandlerPermissions {
|
||||
fn check_env(&mut self, var: &str) -> Result<(), AnyError>;
|
||||
fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError>;
|
||||
fn check_net_url(
|
||||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer {
|
||||
#[inline(always)]
|
||||
fn check_env(&mut self, var: &str) -> Result<(), AnyError> {
|
||||
fn check_env(&mut self, var: &str) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_env(self, var)
|
||||
}
|
||||
|
||||
|
@ -64,7 +65,7 @@ impl RemoteDbHandlerPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +104,9 @@ impl<P: RemoteDbHandlerPermissions + 'static> denokv_remote::RemotePermissions
|
|||
fn check_net_url(&self, url: &Url) -> Result<(), anyhow::Error> {
|
||||
let mut state = self.state.borrow_mut();
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions.check_net_url(url, "Deno.openKv")
|
||||
permissions
|
||||
.check_net_url(url, "Deno.openKv")
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,20 +13,20 @@ use std::sync::Arc;
|
|||
use std::sync::Mutex;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use crate::DatabaseHandler;
|
||||
use async_trait::async_trait;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::OpState;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
pub use denokv_sqlite::SqliteBackendError;
|
||||
use denokv_sqlite::SqliteConfig;
|
||||
use denokv_sqlite::SqliteNotifier;
|
||||
use rand::SeedableRng;
|
||||
use rusqlite::OpenFlags;
|
||||
|
||||
use crate::DatabaseHandler;
|
||||
|
||||
static SQLITE_NOTIFIERS_MAP: OnceLock<Mutex<HashMap<PathBuf, SqliteNotifier>>> =
|
||||
OnceLock::new();
|
||||
|
||||
|
@ -42,13 +42,13 @@ pub trait SqliteDbHandlerPermissions {
|
|||
&mut self,
|
||||
p: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> Result<PathBuf, PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check_write<'a>(
|
||||
&mut self,
|
||||
p: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError>;
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
|
||||
|
@ -57,7 +57,7 @@ impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
p: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read(self, p, api_name)
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ impl SqliteDbHandlerPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
p: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_path(self, p, api_name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub enum NApiError {
|
|||
#[error("Unable to find register Node-API module at {}", .0.display())]
|
||||
ModuleNotFound(PathBuf),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] PermissionCheckError),
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
|
@ -55,6 +55,7 @@ use libloading::os::windows::*;
|
|||
// Expose common stuff for ease of use.
|
||||
// `use deno_napi::*`
|
||||
pub use deno_core::v8;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
pub use std::ffi::CStr;
|
||||
pub use std::os::raw::c_char;
|
||||
pub use std::os::raw::c_void;
|
||||
|
@ -508,20 +509,14 @@ deno_core::extension!(deno_napi,
|
|||
|
||||
pub trait NapiPermissions {
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError>;
|
||||
fn check(&mut self, path: &str) -> Result<PathBuf, PermissionCheckError>;
|
||||
}
|
||||
|
||||
// NOTE(bartlomieju): for now, NAPI uses `--allow-ffi` flag, but that might
|
||||
// change in the future.
|
||||
impl NapiPermissions for deno_permissions::PermissionsContainer {
|
||||
#[inline(always)]
|
||||
fn check(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
fn check(&mut self, path: &str) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_ffi(self, path)
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +548,7 @@ where
|
|||
let (async_work_sender, cleanup_hooks, external_ops_tracker, path) = {
|
||||
let mut op_state = op_state.borrow_mut();
|
||||
let permissions = op_state.borrow_mut::<NP>();
|
||||
let path = permissions.check(&path).map_err(NApiError::Permission)?;
|
||||
let path = permissions.check(&path)?;
|
||||
let napi_state = op_state.borrow::<NapiState>();
|
||||
(
|
||||
op_state.borrow::<V8CrossThreadTaskSpawner>().clone(),
|
||||
|
|
|
@ -11,6 +11,7 @@ mod tcp;
|
|||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::OpState;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use deno_tls::rustls::RootCertStore;
|
||||
use deno_tls::RootCertStoreProvider;
|
||||
use std::borrow::Cow;
|
||||
|
@ -25,25 +26,25 @@ pub trait NetPermissions {
|
|||
&mut self,
|
||||
host: &(T, Option<u16>),
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check_read(
|
||||
&mut self,
|
||||
p: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> Result<PathBuf, PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn check_write(
|
||||
&mut self,
|
||||
p: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> 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,
|
||||
p: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError>;
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl NetPermissions for deno_permissions::PermissionsContainer {
|
||||
|
@ -52,7 +53,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
host: &(T, Option<u16>),
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_net(self, host, api_name)
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read(self, path, api_name)
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write(self, path, api_name)
|
||||
}
|
||||
|
||||
|
@ -79,7 +80,7 @@ impl NetPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &'a Path,
|
||||
api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_path(
|
||||
self, path, api_name,
|
||||
)
|
||||
|
|
|
@ -81,8 +81,8 @@ pub enum NetError {
|
|||
Io(#[from] std::io::Error),
|
||||
#[error("Another accept task is ongoing")]
|
||||
AcceptTaskOngoing,
|
||||
#[error("{0}")]
|
||||
Permission(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error("{0}")]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error("No resolved address found")]
|
||||
|
@ -195,12 +195,10 @@ where
|
|||
{
|
||||
{
|
||||
let mut s = state.borrow_mut();
|
||||
s.borrow_mut::<NP>()
|
||||
.check_net(
|
||||
&(&addr.hostname, Some(addr.port)),
|
||||
"Deno.DatagramConn.send()",
|
||||
)
|
||||
.map_err(NetError::Permission)?;
|
||||
s.borrow_mut::<NP>().check_net(
|
||||
&(&addr.hostname, Some(addr.port)),
|
||||
"Deno.DatagramConn.send()",
|
||||
)?;
|
||||
}
|
||||
let addr = resolve_addr(&addr.hostname, addr.port)
|
||||
.await?
|
||||
|
@ -369,8 +367,7 @@ where
|
|||
let mut state_ = state.borrow_mut();
|
||||
state_
|
||||
.borrow_mut::<NP>()
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")
|
||||
.map_err(NetError::Permission)?;
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")?;
|
||||
}
|
||||
|
||||
let addr = resolve_addr(&addr.hostname, addr.port)
|
||||
|
@ -420,8 +417,7 @@ where
|
|||
}
|
||||
state
|
||||
.borrow_mut::<NP>()
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")
|
||||
.map_err(NetError::Permission)?;
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")?;
|
||||
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
||||
.next()
|
||||
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||
|
@ -449,8 +445,7 @@ where
|
|||
{
|
||||
state
|
||||
.borrow_mut::<NP>()
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")
|
||||
.map_err(NetError::Permission)?;
|
||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")?;
|
||||
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
||||
.next()
|
||||
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||
|
@ -647,9 +642,7 @@ where
|
|||
let socker_addr = &ns.socket_addr;
|
||||
let ip = socker_addr.ip().to_string();
|
||||
let port = socker_addr.port();
|
||||
perm
|
||||
.check_net(&(ip, Some(port)), "Deno.resolveDns()")
|
||||
.map_err(NetError::Permission)?;
|
||||
perm.check_net(&(ip, Some(port)), "Deno.resolveDns()")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,6 +827,7 @@ mod tests {
|
|||
use deno_core::futures::FutureExt;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use socket2::SockRef;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::Ipv6Addr;
|
||||
|
@ -1041,7 +1035,7 @@ mod tests {
|
|||
&mut self,
|
||||
_host: &(T, Option<u16>),
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1049,7 +1043,7 @@ mod tests {
|
|||
&mut self,
|
||||
p: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
Ok(PathBuf::from(p))
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1051,7 @@ mod tests {
|
|||
&mut self,
|
||||
p: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
Ok(PathBuf::from(p))
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1059,7 @@ mod tests {
|
|||
&mut self,
|
||||
p: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, deno_core::error::AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
Ok(Cow::Borrowed(p))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ pub mod ops;
|
|||
mod polyfill;
|
||||
|
||||
pub use deno_package_json::PackageJson;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
pub use node_resolver::PathClean;
|
||||
pub use ops::ipc::ChildPipeFd;
|
||||
pub use ops::ipc::IpcJsonStreamResource;
|
||||
|
@ -45,10 +46,13 @@ pub trait NodePermissions {
|
|||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
#[inline(always)]
|
||||
fn check_read(&mut self, path: &str) -> Result<PathBuf, AnyError> {
|
||||
fn check_read(
|
||||
&mut self,
|
||||
path: &str,
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
self.check_read_with_api_name(path, None)
|
||||
}
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
|
@ -56,20 +60,24 @@ pub trait NodePermissions {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: Option<&str>,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> 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,
|
||||
) -> Result<Cow<'a, Path>, AnyError>;
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError>;
|
||||
fn query_read_all(&mut self) -> bool;
|
||||
fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError>;
|
||||
fn check_sys(
|
||||
&mut self,
|
||||
kind: &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_with_api_name(
|
||||
&mut self,
|
||||
path: &str,
|
||||
api_name: Option<&str>,
|
||||
) -> Result<PathBuf, AnyError>;
|
||||
) -> Result<PathBuf, PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl NodePermissions for deno_permissions::PermissionsContainer {
|
||||
|
@ -78,7 +86,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
url: &Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
|
||||
}
|
||||
|
||||
|
@ -87,7 +95,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: Option<&str>,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read_with_api_name(
|
||||
self, path, api_name,
|
||||
)
|
||||
|
@ -96,7 +104,7 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
|
|||
fn check_read_path<'a>(
|
||||
&mut self,
|
||||
path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_read_path(self, path, None)
|
||||
}
|
||||
|
||||
|
@ -109,13 +117,17 @@ impl NodePermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
path: &str,
|
||||
api_name: Option<&str>,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_write_with_api_name(
|
||||
self, path, api_name,
|
||||
)
|
||||
}
|
||||
|
||||
fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), AnyError> {
|
||||
fn check_sys(
|
||||
&mut self,
|
||||
kind: &str,
|
||||
api_name: &str,
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_sys(self, kind, api_name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::NodePermissions;
|
|||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum FsError {
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[cfg(windows)]
|
||||
|
@ -53,8 +53,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.exists()"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.exists()"))?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -72,12 +71,10 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_read_with_api_name(path, Some("node:fs.cpSync"))?;
|
||||
let new_path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(new_path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(new_path, Some("node:fs.cpSync"))?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.cp_sync(&path, &new_path)?;
|
||||
|
@ -97,12 +94,10 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.cpSync"))?;
|
||||
let new_path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&new_path, Some("node:fs.cpSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(&new_path, Some("node:fs.cpSync"))?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path, new_path)
|
||||
};
|
||||
|
||||
|
@ -136,12 +131,10 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_read_with_api_name(&path, Some("node:fs.statfs"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_read_with_api_name(&path, Some("node:fs.statfs"))?;
|
||||
state
|
||||
.borrow_mut::<P>()
|
||||
.check_sys("statfs", "node:fs.statfs")
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_sys("statfs", "node:fs.statfs")?;
|
||||
path
|
||||
};
|
||||
#[cfg(unix)]
|
||||
|
@ -279,8 +272,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(path, Some("node:fs.lutimes"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(path, Some("node:fs.lutimes"))?;
|
||||
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.lutime_sync(&path, atime_secs, atime_nanos, mtime_secs, mtime_nanos)?;
|
||||
|
@ -303,8 +295,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lutimesSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lutimesSync"))?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
|
||||
|
@ -326,8 +317,7 @@ where
|
|||
{
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchownSync"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchownSync"))?;
|
||||
let fs = state.borrow::<FileSystemRc>();
|
||||
fs.lchown_sync(&path, uid, gid)?;
|
||||
Ok(())
|
||||
|
@ -347,8 +337,7 @@ where
|
|||
let mut state = state.borrow_mut();
|
||||
let path = state
|
||||
.borrow_mut::<P>()
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchown"))
|
||||
.map_err(FsError::Permission)?;
|
||||
.check_write_with_api_name(&path, Some("node:fs.lchown"))?;
|
||||
(state.borrow::<FileSystemRc>().clone(), path)
|
||||
};
|
||||
fs.lchown_async(path, uid, gid).await?;
|
||||
|
|
|
@ -78,9 +78,7 @@ where
|
|||
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_net_url(&url, "ClientRequest")
|
||||
.map_err(FetchError::Permission)?;
|
||||
permissions.check_net_url(&url, "ClientRequest")?;
|
||||
}
|
||||
|
||||
let mut header_map = HeaderMap::new();
|
||||
|
|
|
@ -14,7 +14,7 @@ pub enum OsError {
|
|||
#[error(transparent)]
|
||||
Priority(priority::PriorityError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error("Failed to get cpu info")]
|
||||
FailedToGetCpuInfo,
|
||||
#[error("Failed to get user info")]
|
||||
|
@ -31,9 +31,7 @@ where
|
|||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_sys("getPriority", "node:os.getPriority()")
|
||||
.map_err(OsError::Permission)?;
|
||||
permissions.check_sys("getPriority", "node:os.getPriority()")?;
|
||||
}
|
||||
|
||||
priority::get_priority(pid).map_err(OsError::Priority)
|
||||
|
@ -50,9 +48,7 @@ where
|
|||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_sys("setPriority", "node:os.setPriority()")
|
||||
.map_err(OsError::Permission)?;
|
||||
permissions.check_sys("setPriority", "node:os.setPriority()")?;
|
||||
}
|
||||
|
||||
priority::set_priority(pid, priority).map_err(OsError::Priority)
|
||||
|
@ -266,9 +262,7 @@ where
|
|||
{
|
||||
{
|
||||
let permissions = state.borrow_mut::<P>();
|
||||
permissions
|
||||
.check_sys("cpus", "node:os.cpus()")
|
||||
.map_err(OsError::Permission)?;
|
||||
permissions.check_sys("cpus", "node:os.cpus()")?;
|
||||
}
|
||||
|
||||
cpus::cpu_info().ok_or(OsError::FailedToGetCpuInfo)
|
||||
|
|
|
@ -1312,6 +1312,8 @@ export function findSourceMap(_path) {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
Module.findSourceMap = findSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string | URL} _specifier
|
||||
* @param {string | URL} _parentUrl
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
notImplemented,
|
||||
TextEncodings,
|
||||
} from "ext:deno_node/_utils.ts";
|
||||
import { type Buffer } from "node:buffer";
|
||||
|
||||
export type CallbackWithError = (err: ErrnoException | null) => void;
|
||||
|
||||
|
|
|
@ -147,8 +147,8 @@ export function open(
|
|||
|
||||
export function openPromise(
|
||||
path: string | Buffer | URL,
|
||||
flags?: openFlags = "r",
|
||||
mode? = 0o666,
|
||||
flags: openFlags = "r",
|
||||
mode = 0o666,
|
||||
): Promise<FileHandle> {
|
||||
return new Promise((resolve, reject) => {
|
||||
open(path, flags, mode, (err, fd) => {
|
||||
|
|
|
@ -15,6 +15,7 @@ import { maybeCallback } from "ext:deno_node/_fs/_fs_common.ts";
|
|||
import { validateInteger } from "ext:deno_node/internal/validators.mjs";
|
||||
import * as io from "ext:deno_io/12_io.js";
|
||||
import { op_fs_seek_async, op_fs_seek_sync } from "ext:core/ops";
|
||||
import process from "node:process";
|
||||
|
||||
type Callback = (
|
||||
err: ErrnoException | null,
|
||||
|
|
|
@ -29,6 +29,7 @@ import {
|
|||
} from "ext:deno_node/internal/validators.mjs";
|
||||
import { Buffer } from "node:buffer";
|
||||
import { KeyFormat, KeyType } from "ext:deno_node/internal/crypto/types.ts";
|
||||
import process from "node:process";
|
||||
|
||||
import {
|
||||
op_node_generate_dh_group_key,
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
ERR_INVALID_ARG_TYPE,
|
||||
ERR_OUT_OF_RANGE,
|
||||
} from "ext:deno_node/internal/errors.ts";
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
export { default as randomBytes } from "ext:deno_node/internal/crypto/_randomBytes.ts";
|
||||
export {
|
||||
|
|
|
@ -126,6 +126,7 @@ ObjectSetPrototypeOf(HTTPParser.prototype, AsyncWrap.prototype);
|
|||
function defineProps(obj: object, props: Record<string, unknown>) {
|
||||
for (const entry of new SafeArrayIterator(ObjectEntries(props))) {
|
||||
ObjectDefineProperty(obj, entry[0], {
|
||||
__proto__: null,
|
||||
value: entry[1],
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
|
|
|
@ -182,6 +182,7 @@ function getContextOptions(options) {
|
|||
|
||||
let defaultContextNameIndex = 1;
|
||||
export function createContext(
|
||||
// deno-lint-ignore prefer-primordials
|
||||
contextObject = {},
|
||||
options = { __proto__: null },
|
||||
) {
|
||||
|
|
|
@ -50,6 +50,7 @@ use tokio::io::ReadHalf;
|
|||
use tokio::io::WriteHalf;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use fastwebsockets::CloseCode;
|
||||
use fastwebsockets::FragmentCollectorRead;
|
||||
use fastwebsockets::Frame;
|
||||
|
@ -75,7 +76,7 @@ pub enum WebsocketError {
|
|||
#[error(transparent)]
|
||||
Url(url::ParseError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
|
@ -112,7 +113,7 @@ pub trait WebSocketPermissions {
|
|||
&mut self,
|
||||
_url: &url::Url,
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError>;
|
||||
) -> Result<(), PermissionCheckError>;
|
||||
}
|
||||
|
||||
impl WebSocketPermissions for deno_permissions::PermissionsContainer {
|
||||
|
@ -121,7 +122,7 @@ impl WebSocketPermissions for deno_permissions::PermissionsContainer {
|
|||
&mut self,
|
||||
url: &url::Url,
|
||||
api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
deno_permissions::PermissionsContainer::check_net_url(self, url, api_name)
|
||||
}
|
||||
}
|
||||
|
@ -158,13 +159,10 @@ pub fn op_ws_check_permission_and_cancel_handle<WP>(
|
|||
where
|
||||
WP: WebSocketPermissions + 'static,
|
||||
{
|
||||
state
|
||||
.borrow_mut::<WP>()
|
||||
.check_net_url(
|
||||
&url::Url::parse(&url).map_err(WebsocketError::Url)?,
|
||||
&api_name,
|
||||
)
|
||||
.map_err(WebsocketError::Permission)?;
|
||||
state.borrow_mut::<WP>().check_net_url(
|
||||
&url::Url::parse(&url).map_err(WebsocketError::Url)?,
|
||||
&api_name,
|
||||
)?;
|
||||
|
||||
if cancel_handle {
|
||||
let rid = state
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
use crate::ops::fs_events::FsEventsError;
|
||||
use crate::ops::http::HttpStartError;
|
||||
use crate::ops::os::OsError;
|
||||
use crate::ops::permissions::PermissionError;
|
||||
use crate::ops::process::CheckRunPermissionError;
|
||||
use crate::ops::process::ProcessError;
|
||||
use crate::ops::signal::SignalError;
|
||||
use crate::ops::tty::TtyError;
|
||||
|
@ -48,6 +50,12 @@ use deno_kv::KvError;
|
|||
use deno_kv::KvMutationError;
|
||||
use deno_napi::NApiError;
|
||||
use deno_net::ops::NetError;
|
||||
use deno_permissions::ChildPermissionError;
|
||||
use deno_permissions::NetDescriptorFromUrlParseError;
|
||||
use deno_permissions::PathResolveError;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use deno_permissions::RunDescriptorParseError;
|
||||
use deno_permissions::SysDescriptorParseError;
|
||||
use deno_tls::TlsError;
|
||||
use deno_web::BlobError;
|
||||
use deno_web::CompressionError;
|
||||
|
@ -63,6 +71,54 @@ use std::error::Error;
|
|||
use std::io;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn get_run_descriptor_parse_error(e: &RunDescriptorParseError) -> &'static str {
|
||||
match e {
|
||||
RunDescriptorParseError::Which(_) => "Error",
|
||||
RunDescriptorParseError::PathResolve(e) => get_path_resolve_error(e),
|
||||
RunDescriptorParseError::EmptyRunQuery => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sys_descriptor_parse_error(e: &SysDescriptorParseError) -> &'static str {
|
||||
match e {
|
||||
SysDescriptorParseError::InvalidKind(_) => "TypeError",
|
||||
SysDescriptorParseError::Empty => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path_resolve_error(e: &PathResolveError) -> &'static str {
|
||||
match e {
|
||||
PathResolveError::CwdResolve(e) => get_io_error_class(e),
|
||||
PathResolveError::EmptyPath => "Error",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_permission_error_class(e: &PermissionError) -> &'static str {
|
||||
match e {
|
||||
PermissionError::InvalidPermissionName(_) => "ReferenceError",
|
||||
PermissionError::PathResolve(e) => get_path_resolve_error(e),
|
||||
PermissionError::NetDescriptorParse(_) => "URIError",
|
||||
PermissionError::SysDescriptorParse(e) => get_sys_descriptor_parse_error(e),
|
||||
PermissionError::RunDescriptorParse(e) => get_run_descriptor_parse_error(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_permission_check_error_class(e: &PermissionCheckError) -> &'static str {
|
||||
match e {
|
||||
PermissionCheckError::PermissionDenied(_) => "NotCapable",
|
||||
PermissionCheckError::InvalidFilePath(_) => "URIError",
|
||||
PermissionCheckError::NetDescriptorForUrlParse(e) => match e {
|
||||
NetDescriptorFromUrlParseError::MissingHost(_) => "TypeError",
|
||||
NetDescriptorFromUrlParseError::Host(_) => "URIError",
|
||||
},
|
||||
PermissionCheckError::SysDescriptorParse(e) => {
|
||||
get_sys_descriptor_parse_error(e)
|
||||
}
|
||||
PermissionCheckError::PathResolve(e) => get_path_resolve_error(e),
|
||||
PermissionCheckError::HostParse(_) => "URIError",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dlopen_error_class(error: &dlopen2::Error) -> &'static str {
|
||||
use dlopen2::Error::*;
|
||||
match error {
|
||||
|
@ -445,7 +501,7 @@ fn get_napi_error_class(e: &NApiError) -> &'static str {
|
|||
NApiError::InvalidPath
|
||||
| NApiError::LibLoading(_)
|
||||
| NApiError::ModuleNotFound(_) => "TypeError",
|
||||
NApiError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
NApiError::Permission(e) => get_permission_check_error_class(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,7 +579,7 @@ fn get_ffi_repr_error_class(e: &ReprError) -> &'static str {
|
|||
ReprError::InvalidF32 => "TypeError",
|
||||
ReprError::InvalidF64 => "TypeError",
|
||||
ReprError::InvalidPointer => "TypeError",
|
||||
ReprError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
ReprError::Permission(e) => get_permission_check_error_class(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,7 +587,7 @@ fn get_ffi_dlfcn_error_class(e: &DlfcnError) -> &'static str {
|
|||
match e {
|
||||
DlfcnError::RegisterSymbol { .. } => "Error",
|
||||
DlfcnError::Dlopen(_) => "Error",
|
||||
DlfcnError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
DlfcnError::Permission(e) => get_permission_check_error_class(e),
|
||||
DlfcnError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
}
|
||||
}
|
||||
|
@ -549,7 +605,7 @@ fn get_ffi_callback_error_class(e: &CallbackError) -> &'static str {
|
|||
match e {
|
||||
CallbackError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
CallbackError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
CallbackError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
CallbackError::Permission(e) => get_permission_check_error_class(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,8 +614,9 @@ fn get_ffi_call_error_class(e: &CallError) -> &'static str {
|
|||
CallError::IR(_) => "TypeError",
|
||||
CallError::NonblockingCallFailure(_) => "Error",
|
||||
CallError::InvalidSymbol(_) => "TypeError",
|
||||
CallError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
CallError::Permission(e) => get_permission_check_error_class(e),
|
||||
CallError::Callback(e) => get_ffi_callback_error_class(e),
|
||||
CallError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,9 +690,8 @@ fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str {
|
|||
|
||||
fn get_fetch_error(error: &FetchError) -> &'static str {
|
||||
match error {
|
||||
FetchError::Resource(e) | FetchError::Permission(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
FetchError::Permission(e) => get_permission_check_error_class(e),
|
||||
FetchError::NetworkError => "TypeError",
|
||||
FetchError::FsNotGet(_) => "TypeError",
|
||||
FetchError::InvalidUrl(_) => "TypeError",
|
||||
|
@ -669,9 +725,8 @@ fn get_http_client_create_error(error: &HttpClientCreateError) -> &'static str {
|
|||
|
||||
fn get_websocket_error(error: &WebsocketError) -> &'static str {
|
||||
match error {
|
||||
WebsocketError::Permission(e) | WebsocketError::Resource(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
WebsocketError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
WebsocketError::Permission(e) => get_permission_check_error_class(e),
|
||||
WebsocketError::Url(e) => get_url_parse_error_class(e),
|
||||
WebsocketError::Io(e) => get_io_error_class(e),
|
||||
WebsocketError::WebSocket(_) => "TypeError",
|
||||
|
@ -708,9 +763,10 @@ fn get_fs_ops_error(error: &FsOpsError) -> &'static str {
|
|||
match error {
|
||||
FsOpsError::Io(e) => get_io_error_class(e),
|
||||
FsOpsError::OperationError(e) => get_fs_error(&e.err),
|
||||
FsOpsError::Permission(e)
|
||||
| FsOpsError::Resource(e)
|
||||
| FsOpsError::Other(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
FsOpsError::Permission(e) => get_permission_check_error_class(e),
|
||||
FsOpsError::Resource(e) | FsOpsError::Other(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
FsOpsError::InvalidUtf8(_) => "InvalidData",
|
||||
FsOpsError::StripPrefix(_) => "Error",
|
||||
FsOpsError::Canceled(e) => {
|
||||
|
@ -777,9 +833,10 @@ fn get_net_error(error: &NetError) -> &'static str {
|
|||
NetError::SocketBusy => "Busy",
|
||||
NetError::Io(e) => get_io_error_class(e),
|
||||
NetError::AcceptTaskOngoing => "Busy",
|
||||
NetError::RootCertStore(e)
|
||||
| NetError::Permission(e)
|
||||
| NetError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
NetError::RootCertStore(e) | NetError::Resource(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
NetError::Permission(e) => get_permission_check_error_class(e),
|
||||
NetError::NoResolvedAddress => "Error",
|
||||
NetError::AddrParse(_) => "Error",
|
||||
NetError::Map(e) => get_net_map_error(e),
|
||||
|
@ -810,12 +867,25 @@ fn get_net_map_error(error: &deno_net::io::MapError) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_child_permission_error(e: &ChildPermissionError) -> &'static str {
|
||||
match e {
|
||||
ChildPermissionError::Escalation => "NotCapable",
|
||||
ChildPermissionError::PathResolve(e) => get_path_resolve_error(e),
|
||||
ChildPermissionError::NetDescriptorParse(_) => "URIError",
|
||||
ChildPermissionError::EnvDescriptorParse(_) => "Error",
|
||||
ChildPermissionError::SysDescriptorParse(e) => {
|
||||
get_sys_descriptor_parse_error(e)
|
||||
}
|
||||
ChildPermissionError::RunDescriptorParse(e) => {
|
||||
get_run_descriptor_parse_error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_create_worker_error(error: &CreateWorkerError) -> &'static str {
|
||||
match error {
|
||||
CreateWorkerError::ClassicWorkers => "DOMExceptionNotSupportedError",
|
||||
CreateWorkerError::Permission(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
CreateWorkerError::Permission(e) => get_child_permission_error(e),
|
||||
CreateWorkerError::ModuleResolution(e) => {
|
||||
get_module_resolution_error_class(e)
|
||||
}
|
||||
|
@ -862,9 +932,8 @@ fn get_signal_error(error: &SignalError) -> &'static str {
|
|||
|
||||
fn get_fs_events_error(error: &FsEventsError) -> &'static str {
|
||||
match error {
|
||||
FsEventsError::Resource(e) | FsEventsError::Permission(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
FsEventsError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
FsEventsError::Permission(e) => get_permission_check_error_class(e),
|
||||
FsEventsError::Notify(e) => get_notify_error_class(e),
|
||||
FsEventsError::Canceled(e) => {
|
||||
let io_err: io::Error = e.to_owned().into();
|
||||
|
@ -892,9 +961,8 @@ fn get_process_error(error: &ProcessError) -> &'static str {
|
|||
ProcessError::FailedResolvingCwd(e) | ProcessError::Io(e) => {
|
||||
get_io_error_class(e)
|
||||
}
|
||||
ProcessError::Permission(e) | ProcessError::Resource(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
ProcessError::Permission(e) => get_permission_check_error_class(e),
|
||||
ProcessError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
ProcessError::BorrowMut(_) => "Error",
|
||||
ProcessError::Which(_) => "Error",
|
||||
ProcessError::ChildProcessAlreadyTerminated => "TypeError",
|
||||
|
@ -903,6 +971,14 @@ fn get_process_error(error: &ProcessError) -> &'static str {
|
|||
ProcessError::InvalidPid => "TypeError",
|
||||
#[cfg(unix)]
|
||||
ProcessError::Nix(e) => get_nix_error_class(e),
|
||||
ProcessError::RunPermission(e) => match e {
|
||||
CheckRunPermissionError::Permission(e) => {
|
||||
get_permission_check_error_class(e)
|
||||
}
|
||||
CheckRunPermissionError::Other(e) => {
|
||||
get_error_class_name(e).unwrap_or("Error")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,6 +1047,7 @@ fn get_fs_error(e: &FsError) -> &'static str {
|
|||
mod node {
|
||||
use super::get_error_class_name;
|
||||
use super::get_io_error_class;
|
||||
use super::get_permission_check_error_class;
|
||||
use super::get_serde_json_error_class;
|
||||
use super::get_url_parse_error_class;
|
||||
pub use deno_node::ops::blocklist::BlocklistError;
|
||||
|
@ -998,7 +1075,7 @@ mod node {
|
|||
|
||||
pub fn get_fs_error(error: &FsError) -> &'static str {
|
||||
match error {
|
||||
FsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
FsError::Permission(e) => get_permission_check_error_class(e),
|
||||
FsError::Io(e) => get_io_error_class(e),
|
||||
#[cfg(windows)]
|
||||
FsError::PathHasNoRoot => "Error",
|
||||
|
@ -1084,7 +1161,7 @@ mod node {
|
|||
#[cfg(windows)]
|
||||
PriorityError::InvalidPriority => "TypeError",
|
||||
},
|
||||
OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
OsError::Permission(e) => get_permission_check_error_class(e),
|
||||
OsError::FailedToGetCpuInfo => "TypeError",
|
||||
OsError::FailedToGetUserInfo(e) => get_io_error_class(e),
|
||||
}
|
||||
|
@ -1116,7 +1193,7 @@ mod node {
|
|||
|
||||
fn get_os_error(error: &OsError) -> &'static str {
|
||||
match error {
|
||||
OsError::Permission(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||
OsError::Permission(e) => get_permission_check_error_class(e),
|
||||
OsError::InvalidUtf8(_) => "InvalidData",
|
||||
OsError::EnvEmptyKey => "TypeError",
|
||||
OsError::EnvInvalidKey(_) => "TypeError",
|
||||
|
@ -1144,6 +1221,18 @@ fn get_sync_fetch_error(error: &SyncFetchError) -> &'static str {
|
|||
|
||||
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
||||
deno_core::error::get_custom_error_class(e)
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ChildPermissionError>()
|
||||
.map(get_child_permission_error)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<PermissionCheckError>()
|
||||
.map(get_permission_check_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<PermissionError>()
|
||||
.map(get_permission_error_class)
|
||||
})
|
||||
.or_else(|| e.downcast_ref::<FsError>().map(get_fs_error))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<node::BlocklistError>()
|
||||
|
|
|
@ -696,6 +696,7 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
|
|||
// are lost.
|
||||
let jupyterNs = undefined;
|
||||
ObjectDefineProperty(finalDenoNs, "jupyter", {
|
||||
__proto__: null,
|
||||
get() {
|
||||
if (jupyterNs) {
|
||||
return jupyterNs;
|
||||
|
|
|
@ -114,7 +114,7 @@ pub enum FsEventsError {
|
|||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
Notify(#[from] NotifyError),
|
||||
#[error(transparent)]
|
||||
|
@ -181,8 +181,7 @@ fn op_fs_events_open(
|
|||
for path in &paths {
|
||||
let path = state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_read(path, "Deno.watchFs()")
|
||||
.map_err(FsEventsError::Permission)?;
|
||||
.check_read(path, "Deno.watchFs()")?;
|
||||
|
||||
let watcher = state.borrow_mut::<WatcherState>();
|
||||
watcher.watcher.watch(&path, recursive_mode)?;
|
||||
|
|
|
@ -73,7 +73,7 @@ deno_core::extension!(
|
|||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum OsError {
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
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.")]
|
||||
|
@ -94,8 +94,7 @@ fn op_exec_path(state: &mut OpState) -> Result<String, OsError> {
|
|||
let current_exe = env::current_exe().unwrap();
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")
|
||||
.map_err(OsError::Permission)?;
|
||||
.check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")?;
|
||||
// normalize path so it doesn't include '.' or '..' components
|
||||
let path = normalize_path(current_exe);
|
||||
|
||||
|
@ -111,10 +110,7 @@ fn op_set_env(
|
|||
#[string] key: &str,
|
||||
#[string] value: &str,
|
||||
) -> Result<(), OsError> {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_env(key)
|
||||
.map_err(OsError::Permission)?;
|
||||
state.borrow_mut::<PermissionsContainer>().check_env(key)?;
|
||||
if key.is_empty() {
|
||||
return Err(OsError::EnvEmptyKey);
|
||||
}
|
||||
|
@ -146,10 +142,7 @@ fn op_get_env(
|
|||
let skip_permission_check = NODE_ENV_VAR_ALLOWLIST.contains(&key);
|
||||
|
||||
if !skip_permission_check {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_env(&key)
|
||||
.map_err(OsError::Permission)?;
|
||||
state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
|
||||
}
|
||||
|
||||
if key.is_empty() {
|
||||
|
@ -172,10 +165,7 @@ fn op_delete_env(
|
|||
state: &mut OpState,
|
||||
#[string] key: String,
|
||||
) -> Result<(), OsError> {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_env(&key)
|
||||
.map_err(OsError::Permission)?;
|
||||
state.borrow_mut::<PermissionsContainer>().check_env(&key)?;
|
||||
if key.is_empty() || key.contains(&['=', '\0'] as &[char]) {
|
||||
return Err(OsError::EnvInvalidKey(key.to_string()));
|
||||
}
|
||||
|
@ -240,8 +230,7 @@ fn op_network_interfaces(
|
|||
) -> Result<Vec<NetworkInterface>, OsError> {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_sys("networkInterfaces", "Deno.networkInterfaces()")
|
||||
.map_err(OsError::Permission)?;
|
||||
.check_sys("networkInterfaces", "Deno.networkInterfaces()")?;
|
||||
Ok(netif::up()?.map(NetworkInterface::from).collect())
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
use ::deno_permissions::PermissionState;
|
||||
use ::deno_permissions::PermissionsContainer;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use serde::Deserialize;
|
||||
|
@ -47,12 +45,26 @@ impl From<PermissionState> for PermissionStatus {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum PermissionError {
|
||||
#[error("No such permission name: {0}")]
|
||||
InvalidPermissionName(String),
|
||||
#[error("{0}")]
|
||||
PathResolve(#[from] ::deno_permissions::PathResolveError),
|
||||
#[error("{0}")]
|
||||
NetDescriptorParse(#[from] ::deno_permissions::NetDescriptorParseError),
|
||||
#[error("{0}")]
|
||||
SysDescriptorParse(#[from] ::deno_permissions::SysDescriptorParseError),
|
||||
#[error("{0}")]
|
||||
RunDescriptorParse(#[from] ::deno_permissions::RunDescriptorParseError),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_query_permission(
|
||||
state: &mut OpState,
|
||||
#[serde] args: PermissionArgs,
|
||||
) -> Result<PermissionStatus, AnyError> {
|
||||
) -> Result<PermissionStatus, PermissionError> {
|
||||
let permissions = state.borrow::<PermissionsContainer>();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.query_read(args.path.as_deref())?,
|
||||
|
@ -62,12 +74,7 @@ pub fn op_query_permission(
|
|||
"sys" => permissions.query_sys(args.kind.as_deref())?,
|
||||
"run" => permissions.query_run(args.command.as_deref())?,
|
||||
"ffi" => permissions.query_ffi(args.path.as_deref())?,
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
format!("No such permission name: {n}"),
|
||||
))
|
||||
}
|
||||
_ => return Err(PermissionError::InvalidPermissionName(args.name)),
|
||||
};
|
||||
Ok(PermissionStatus::from(perm))
|
||||
}
|
||||
|
@ -77,7 +84,7 @@ pub fn op_query_permission(
|
|||
pub fn op_revoke_permission(
|
||||
state: &mut OpState,
|
||||
#[serde] args: PermissionArgs,
|
||||
) -> Result<PermissionStatus, AnyError> {
|
||||
) -> Result<PermissionStatus, PermissionError> {
|
||||
let permissions = state.borrow::<PermissionsContainer>();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.revoke_read(args.path.as_deref())?,
|
||||
|
@ -87,12 +94,7 @@ pub fn op_revoke_permission(
|
|||
"sys" => permissions.revoke_sys(args.kind.as_deref())?,
|
||||
"run" => permissions.revoke_run(args.command.as_deref())?,
|
||||
"ffi" => permissions.revoke_ffi(args.path.as_deref())?,
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
format!("No such permission name: {n}"),
|
||||
))
|
||||
}
|
||||
_ => return Err(PermissionError::InvalidPermissionName(args.name)),
|
||||
};
|
||||
Ok(PermissionStatus::from(perm))
|
||||
}
|
||||
|
@ -102,7 +104,7 @@ pub fn op_revoke_permission(
|
|||
pub fn op_request_permission(
|
||||
state: &mut OpState,
|
||||
#[serde] args: PermissionArgs,
|
||||
) -> Result<PermissionStatus, AnyError> {
|
||||
) -> Result<PermissionStatus, PermissionError> {
|
||||
let permissions = state.borrow::<PermissionsContainer>();
|
||||
let perm = match args.name.as_ref() {
|
||||
"read" => permissions.request_read(args.path.as_deref())?,
|
||||
|
@ -112,12 +114,7 @@ pub fn op_request_permission(
|
|||
"sys" => permissions.request_sys(args.kind.as_deref())?,
|
||||
"run" => permissions.request_run(args.command.as_deref())?,
|
||||
"ffi" => permissions.request_ffi(args.path.as_deref())?,
|
||||
n => {
|
||||
return Err(custom_error(
|
||||
"ReferenceError",
|
||||
format!("No such permission name: {n}"),
|
||||
))
|
||||
}
|
||||
_ => return Err(PermissionError::InvalidPermissionName(args.name)),
|
||||
};
|
||||
Ok(PermissionStatus::from(perm))
|
||||
}
|
||||
|
|
|
@ -206,7 +206,9 @@ pub enum ProcessError {
|
|||
#[error("failed resolving cwd: {0}")]
|
||||
FailedResolvingCwd(#[source] std::io::Error),
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error(transparent)]
|
||||
RunPermission(#[from] CheckRunPermissionError),
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
#[error(transparent)]
|
||||
|
@ -653,8 +655,7 @@ fn compute_run_cmd_and_check_permissions(
|
|||
},
|
||||
&run_env,
|
||||
api_name,
|
||||
)
|
||||
.map_err(ProcessError::Permission)?;
|
||||
)?;
|
||||
Ok((cmd, run_env))
|
||||
}
|
||||
|
||||
|
@ -734,12 +735,20 @@ fn resolve_path(path: &str, cwd: &Path) -> PathBuf {
|
|||
deno_path_util::normalize_path(cwd.join(path))
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CheckRunPermissionError {
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[error("{0}")]
|
||||
Other(deno_core::error::AnyError),
|
||||
}
|
||||
|
||||
fn check_run_permission(
|
||||
state: &mut OpState,
|
||||
cmd: &RunQueryDescriptor,
|
||||
run_env: &RunEnv,
|
||||
api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), CheckRunPermissionError> {
|
||||
let permissions = state.borrow_mut::<PermissionsContainer>();
|
||||
if !permissions.query_run_all(api_name) {
|
||||
// error the same on all platforms
|
||||
|
@ -747,14 +756,14 @@ fn check_run_permission(
|
|||
if !env_var_names.is_empty() {
|
||||
// we don't allow users to launch subprocesses with any LD_ or DYLD_*
|
||||
// env vars set because this allows executing code (ex. LD_PRELOAD)
|
||||
return Err(deno_core::error::custom_error(
|
||||
return Err(CheckRunPermissionError::Other(deno_core::error::custom_error(
|
||||
"NotCapable",
|
||||
format!(
|
||||
"Requires --allow-all permissions to spawn subprocess with {} environment variable{}.",
|
||||
env_var_names.join(", "),
|
||||
if env_var_names.len() != 1 { "s" } else { "" }
|
||||
)
|
||||
));
|
||||
)));
|
||||
}
|
||||
permissions.check_run(cmd, api_name)?;
|
||||
}
|
||||
|
@ -1126,8 +1135,7 @@ mod deprecated {
|
|||
) -> Result<(), ProcessError> {
|
||||
state
|
||||
.borrow_mut::<PermissionsContainer>()
|
||||
.check_run_all(&api_name)
|
||||
.map_err(ProcessError::Permission)?;
|
||||
.check_run_all(&api_name)?;
|
||||
kill(pid, &signal)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ pub enum CreateWorkerError {
|
|||
#[error("Classic workers are not supported.")]
|
||||
ClassicWorkers,
|
||||
#[error(transparent)]
|
||||
Permission(deno_core::error::AnyError),
|
||||
Permission(deno_permissions::ChildPermissionError),
|
||||
#[error(transparent)]
|
||||
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||
#[error(transparent)]
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_path_util::normalize_path;
|
||||
use deno_permissions::AllowRunDescriptor;
|
||||
use deno_permissions::AllowRunDescriptorParseResult;
|
||||
|
@ -15,9 +12,12 @@ use deno_permissions::FfiDescriptor;
|
|||
use deno_permissions::ImportDescriptor;
|
||||
use deno_permissions::NetDescriptor;
|
||||
use deno_permissions::PathQueryDescriptor;
|
||||
use deno_permissions::PathResolveError;
|
||||
use deno_permissions::ReadDescriptor;
|
||||
use deno_permissions::RunDescriptorParseError;
|
||||
use deno_permissions::RunQueryDescriptor;
|
||||
use deno_permissions::SysDescriptor;
|
||||
use deno_permissions::SysDescriptorParseError;
|
||||
use deno_permissions::WriteDescriptor;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -30,9 +30,9 @@ impl RuntimePermissionDescriptorParser {
|
|||
Self { fs }
|
||||
}
|
||||
|
||||
fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, AnyError> {
|
||||
fn resolve_from_cwd(&self, path: &str) -> Result<PathBuf, PathResolveError> {
|
||||
if path.is_empty() {
|
||||
bail!("Empty path is not allowed");
|
||||
return Err(PathResolveError::EmptyPath);
|
||||
}
|
||||
let path = Path::new(path);
|
||||
if path.is_absolute() {
|
||||
|
@ -43,12 +43,11 @@ impl RuntimePermissionDescriptorParser {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_cwd(&self) -> Result<PathBuf, AnyError> {
|
||||
fn resolve_cwd(&self) -> Result<PathBuf, PathResolveError> {
|
||||
self
|
||||
.fs
|
||||
.cwd()
|
||||
.map_err(|e| e.into_io_error())
|
||||
.context("failed resolving cwd")
|
||||
.map_err(|e| PathResolveError::CwdResolve(e.into_io_error()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,37 +57,37 @@ impl deno_permissions::PermissionDescriptorParser
|
|||
fn parse_read_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<ReadDescriptor, AnyError> {
|
||||
) -> Result<ReadDescriptor, PathResolveError> {
|
||||
Ok(ReadDescriptor(self.resolve_from_cwd(text)?))
|
||||
}
|
||||
|
||||
fn parse_write_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<WriteDescriptor, AnyError> {
|
||||
) -> Result<WriteDescriptor, PathResolveError> {
|
||||
Ok(WriteDescriptor(self.resolve_from_cwd(text)?))
|
||||
}
|
||||
|
||||
fn parse_net_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<NetDescriptor, AnyError> {
|
||||
) -> Result<NetDescriptor, deno_permissions::NetDescriptorParseError> {
|
||||
NetDescriptor::parse(text)
|
||||
}
|
||||
|
||||
fn parse_import_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<ImportDescriptor, AnyError> {
|
||||
) -> Result<ImportDescriptor, deno_permissions::NetDescriptorParseError> {
|
||||
ImportDescriptor::parse(text)
|
||||
}
|
||||
|
||||
fn parse_env_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<EnvDescriptor, AnyError> {
|
||||
) -> Result<EnvDescriptor, deno_permissions::EnvDescriptorParseError> {
|
||||
if text.is_empty() {
|
||||
Err(AnyError::msg("Empty env not allowed"))
|
||||
Err(deno_permissions::EnvDescriptorParseError)
|
||||
} else {
|
||||
Ok(EnvDescriptor::new(text))
|
||||
}
|
||||
|
@ -97,9 +96,9 @@ impl deno_permissions::PermissionDescriptorParser
|
|||
fn parse_sys_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<deno_permissions::SysDescriptor, AnyError> {
|
||||
) -> Result<SysDescriptor, SysDescriptorParseError> {
|
||||
if text.is_empty() {
|
||||
Err(AnyError::msg("Empty sys not allowed"))
|
||||
Err(SysDescriptorParseError::Empty)
|
||||
} else {
|
||||
Ok(SysDescriptor::parse(text.to_string())?)
|
||||
}
|
||||
|
@ -108,21 +107,21 @@ impl deno_permissions::PermissionDescriptorParser
|
|||
fn parse_allow_run_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<AllowRunDescriptorParseResult, AnyError> {
|
||||
) -> Result<AllowRunDescriptorParseResult, RunDescriptorParseError> {
|
||||
Ok(AllowRunDescriptor::parse(text, &self.resolve_cwd()?)?)
|
||||
}
|
||||
|
||||
fn parse_deny_run_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<DenyRunDescriptor, AnyError> {
|
||||
) -> Result<DenyRunDescriptor, PathResolveError> {
|
||||
Ok(DenyRunDescriptor::parse(text, &self.resolve_cwd()?))
|
||||
}
|
||||
|
||||
fn parse_ffi_descriptor(
|
||||
&self,
|
||||
text: &str,
|
||||
) -> Result<deno_permissions::FfiDescriptor, AnyError> {
|
||||
) -> Result<FfiDescriptor, PathResolveError> {
|
||||
Ok(FfiDescriptor(self.resolve_from_cwd(text)?))
|
||||
}
|
||||
|
||||
|
@ -131,7 +130,7 @@ impl deno_permissions::PermissionDescriptorParser
|
|||
fn parse_path_query(
|
||||
&self,
|
||||
path: &str,
|
||||
) -> Result<PathQueryDescriptor, AnyError> {
|
||||
) -> Result<PathQueryDescriptor, PathResolveError> {
|
||||
Ok(PathQueryDescriptor {
|
||||
resolved: self.resolve_from_cwd(path)?,
|
||||
requested: path.to_string(),
|
||||
|
@ -141,11 +140,12 @@ impl deno_permissions::PermissionDescriptorParser
|
|||
fn parse_run_query(
|
||||
&self,
|
||||
requested: &str,
|
||||
) -> Result<RunQueryDescriptor, AnyError> {
|
||||
) -> Result<RunQueryDescriptor, RunDescriptorParseError> {
|
||||
if requested.is_empty() {
|
||||
bail!("Empty run query is not allowed");
|
||||
return Err(RunDescriptorParseError::EmptyRunQuery);
|
||||
}
|
||||
RunQueryDescriptor::parse(requested)
|
||||
.map_err(RunDescriptorParseError::PathResolve)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ log.workspace = true
|
|||
once_cell.workspace = true
|
||||
percent-encoding = { version = "2.3.1", features = [] }
|
||||
serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
which.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_terminal::colors;
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -101,8 +100,7 @@ pub struct TtyPrompter;
|
|||
fn clear_stdin(
|
||||
_stdin_lock: &mut StdinLock,
|
||||
_stderr_lock: &mut StderrLock,
|
||||
) -> Result<(), AnyError> {
|
||||
use deno_core::anyhow::bail;
|
||||
) -> Result<(), std::io::Error> {
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
const STDIN_FD: i32 = 0;
|
||||
|
@ -117,7 +115,10 @@ fn clear_stdin(
|
|||
loop {
|
||||
let r = libc::tcflush(STDIN_FD, libc::TCIFLUSH);
|
||||
if r != 0 {
|
||||
bail!("clear_stdin failed (tcflush)");
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"clear_stdin failed (tcflush)",
|
||||
));
|
||||
}
|
||||
|
||||
// Initialize timeout for select to be 100ms
|
||||
|
@ -137,7 +138,10 @@ fn clear_stdin(
|
|||
|
||||
// Check if select returned an error
|
||||
if r < 0 {
|
||||
bail!("clear_stdin failed (select)");
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"clear_stdin failed (select)",
|
||||
));
|
||||
}
|
||||
|
||||
// Check if select returned due to timeout (stdin is quiescent)
|
||||
|
@ -156,8 +160,7 @@ fn clear_stdin(
|
|||
fn clear_stdin(
|
||||
stdin_lock: &mut StdinLock,
|
||||
stderr_lock: &mut StderrLock,
|
||||
) -> Result<(), AnyError> {
|
||||
use deno_core::anyhow::bail;
|
||||
) -> Result<(), std::io::Error> {
|
||||
use winapi::shared::minwindef::TRUE;
|
||||
use winapi::shared::minwindef::UINT;
|
||||
use winapi::shared::minwindef::WORD;
|
||||
|
@ -194,18 +197,23 @@ fn clear_stdin(
|
|||
|
||||
return Ok(());
|
||||
|
||||
unsafe fn flush_input_buffer(stdin: HANDLE) -> Result<(), AnyError> {
|
||||
unsafe fn flush_input_buffer(stdin: HANDLE) -> Result<(), std::io::Error> {
|
||||
let success = FlushConsoleInputBuffer(stdin);
|
||||
if success != TRUE {
|
||||
bail!(
|
||||
"Could not flush the console input buffer: {}",
|
||||
std::io::Error::last_os_error()
|
||||
)
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!(
|
||||
"Could not flush the console input buffer: {}",
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn emulate_enter_key_press(stdin: HANDLE) -> Result<(), AnyError> {
|
||||
unsafe fn emulate_enter_key_press(
|
||||
stdin: HANDLE,
|
||||
) -> Result<(), std::io::Error> {
|
||||
// https://github.com/libuv/libuv/blob/a39009a5a9252a566ca0704d02df8dabc4ce328f/src/win/tty.c#L1121-L1131
|
||||
let mut input_record: INPUT_RECORD = std::mem::zeroed();
|
||||
input_record.EventType = KEY_EVENT;
|
||||
|
@ -220,34 +228,43 @@ fn clear_stdin(
|
|||
let success =
|
||||
WriteConsoleInputW(stdin, &input_record, 1, &mut record_written);
|
||||
if success != TRUE {
|
||||
bail!(
|
||||
"Could not emulate enter key press: {}",
|
||||
std::io::Error::last_os_error()
|
||||
);
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!(
|
||||
"Could not emulate enter key press: {}",
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn is_input_buffer_empty(stdin: HANDLE) -> Result<bool, AnyError> {
|
||||
unsafe fn is_input_buffer_empty(
|
||||
stdin: HANDLE,
|
||||
) -> Result<bool, std::io::Error> {
|
||||
let mut buffer = Vec::with_capacity(1);
|
||||
let mut events_read = 0;
|
||||
let success =
|
||||
PeekConsoleInputW(stdin, buffer.as_mut_ptr(), 1, &mut events_read);
|
||||
if success != TRUE {
|
||||
bail!(
|
||||
"Could not peek the console input buffer: {}",
|
||||
std::io::Error::last_os_error()
|
||||
)
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!(
|
||||
"Could not peek the console input buffer: {}",
|
||||
std::io::Error::last_os_error()
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(events_read == 0)
|
||||
}
|
||||
|
||||
fn move_cursor_up(stderr_lock: &mut StderrLock) -> Result<(), AnyError> {
|
||||
write!(stderr_lock, "\x1B[1A")?;
|
||||
Ok(())
|
||||
fn move_cursor_up(
|
||||
stderr_lock: &mut StderrLock,
|
||||
) -> Result<(), std::io::Error> {
|
||||
write!(stderr_lock, "\x1B[1A")
|
||||
}
|
||||
|
||||
fn read_stdin_line(stdin_lock: &mut StdinLock) -> Result<(), AnyError> {
|
||||
fn read_stdin_line(stdin_lock: &mut StdinLock) -> Result<(), std::io::Error> {
|
||||
let mut input = String::new();
|
||||
stdin_lock.read_line(&mut input)?;
|
||||
Ok(())
|
||||
|
|
|
@ -5,12 +5,12 @@ use crate::ops::bootstrap::SnapshotOptions;
|
|||
use crate::shared::maybe_transpile_source;
|
||||
use crate::shared::runtime;
|
||||
use deno_cache::SqliteBackedCache;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::snapshot::*;
|
||||
use deno_core::v8;
|
||||
use deno_core::Extension;
|
||||
use deno_http::DefaultHttpPropertyExtractor;
|
||||
use deno_io::fs::FsError;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
use std::borrow::Cow;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
@ -26,7 +26,7 @@ impl deno_websocket::WebSocketPermissions for Permissions {
|
|||
&mut self,
|
||||
_url: &deno_core::url::Url,
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ impl deno_fetch::FetchPermissions for Permissions {
|
|||
&mut self,
|
||||
_url: &deno_core::url::Url,
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -50,28 +50,26 @@ impl deno_fetch::FetchPermissions for Permissions {
|
|||
&mut self,
|
||||
_p: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
||||
impl deno_ffi::FfiPermissions for Permissions {
|
||||
fn check_partial_no_path(
|
||||
&mut self,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
fn check_partial_no_path(&mut self) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
fn check_partial_with_path(
|
||||
&mut self,
|
||||
_path: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
||||
impl deno_napi::NapiPermissions for Permissions {
|
||||
fn check(&mut self, _path: &str) -> std::result::Result<PathBuf, AnyError> {
|
||||
fn check(&mut self, _path: &str) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
@ -81,20 +79,20 @@ impl deno_node::NodePermissions for Permissions {
|
|||
&mut self,
|
||||
_url: &deno_core::url::Url,
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
fn check_read_path<'a>(
|
||||
&mut self,
|
||||
_path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
fn check_read_with_api_name(
|
||||
&mut self,
|
||||
_p: &str,
|
||||
_api_name: Option<&str>,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
fn query_read_all(&mut self) -> bool {
|
||||
|
@ -104,14 +102,14 @@ impl deno_node::NodePermissions for Permissions {
|
|||
&mut self,
|
||||
_p: &str,
|
||||
_api_name: Option<&str>,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
fn check_sys(
|
||||
&mut self,
|
||||
_kind: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +119,7 @@ impl deno_net::NetPermissions for Permissions {
|
|||
&mut self,
|
||||
_host: &(T, Option<u16>),
|
||||
_api_name: &str,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -129,7 +127,7 @@ impl deno_net::NetPermissions for Permissions {
|
|||
&mut self,
|
||||
_p: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -137,7 +135,7 @@ impl deno_net::NetPermissions for Permissions {
|
|||
&mut self,
|
||||
_p: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -145,7 +143,7 @@ impl deno_net::NetPermissions for Permissions {
|
|||
&mut self,
|
||||
_p: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +156,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
_write: bool,
|
||||
_path: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<std::borrow::Cow<'a, Path>, FsError> {
|
||||
) -> Result<Cow<'a, Path>, FsError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -166,11 +164,14 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
fn check_read_all(&mut self, _api_name: &str) -> Result<(), AnyError> {
|
||||
fn check_read_all(
|
||||
&mut self,
|
||||
_api_name: &str,
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -179,7 +180,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
_path: &Path,
|
||||
_display: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -187,7 +188,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -195,11 +196,14 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
fn check_write_all(&mut self, _api_name: &str) -> Result<(), AnyError> {
|
||||
fn check_write_all(
|
||||
&mut self,
|
||||
_api_name: &str,
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -208,7 +212,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
_path: &Path,
|
||||
_display: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -216,7 +220,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -224,7 +228,7 @@ impl deno_fs::FsPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +238,7 @@ impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &str,
|
||||
_api_name: &str,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
|
||||
|
@ -242,7 +246,7 @@ impl deno_kv::sqlite::SqliteDbHandlerPermissions for Permissions {
|
|||
&mut self,
|
||||
_path: &'a Path,
|
||||
_api_name: &str,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, PermissionCheckError> {
|
||||
unreachable!("snapshotting!")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6396,6 +6396,45 @@ fn lsp_cache_on_save() {
|
|||
client.shutdown();
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/denoland/deno/issues/25999.
|
||||
#[test]
|
||||
fn lsp_asset_document_dom_code_action() {
|
||||
let context = TestContextBuilder::new().use_temp_cwd().build();
|
||||
let temp_dir = context.temp_dir();
|
||||
temp_dir.write(
|
||||
"deno.json",
|
||||
json!({
|
||||
"compilerOptions": {
|
||||
"lib": ["deno.window", "dom"],
|
||||
},
|
||||
})
|
||||
.to_string(),
|
||||
);
|
||||
let mut client = context.new_lsp_command().build();
|
||||
client.initialize_default();
|
||||
client.did_open(json!({
|
||||
"textDocument": {
|
||||
"uri": temp_dir.url().join("file.ts").unwrap(),
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": r#""#,
|
||||
},
|
||||
}));
|
||||
let res = client.write_request(
|
||||
"textDocument/codeAction",
|
||||
json!({
|
||||
"textDocument": { "uri": "asset:///lib.dom.d.ts" },
|
||||
"range": {
|
||||
"start": { "line": 0, "character": 0 },
|
||||
"end": { "line": 0, "character": 0 },
|
||||
},
|
||||
"context": { "diagnostics": [], "only": ["quickfix"] },
|
||||
}),
|
||||
);
|
||||
assert_eq!(res, json!(null));
|
||||
client.shutdown();
|
||||
}
|
||||
|
||||
// Regression test for https://github.com/denoland/deno/issues/22122.
|
||||
#[test]
|
||||
fn lsp_cache_then_definition() {
|
||||
|
|
|
@ -572,16 +572,19 @@ async fn serve_watch_all() {
|
|||
let main_file_to_watch = t.path().join("main_file_to_watch.js");
|
||||
main_file_to_watch.write(
|
||||
"export default {
|
||||
fetch(_request: Request) {
|
||||
fetch(_request) {
|
||||
return new Response(\"aaaaaaqqq!\");
|
||||
},
|
||||
};",
|
||||
);
|
||||
|
||||
let another_file = t.path().join("another_file.js");
|
||||
another_file.write("");
|
||||
|
||||
let mut child = util::deno_cmd()
|
||||
.current_dir(t.path())
|
||||
.arg("serve")
|
||||
.arg("--watch=another_file.js")
|
||||
.arg(format!("--watch={another_file}"))
|
||||
.arg("-L")
|
||||
.arg("debug")
|
||||
.arg(&main_file_to_watch)
|
||||
|
@ -596,7 +599,7 @@ async fn serve_watch_all() {
|
|||
// Change content of the file
|
||||
main_file_to_watch.write(
|
||||
"export default {
|
||||
fetch(_request: Request) {
|
||||
fetch(_request) {
|
||||
return new Response(\"aaaaaaqqq123!\");
|
||||
},
|
||||
};",
|
||||
|
@ -604,18 +607,20 @@ async fn serve_watch_all() {
|
|||
wait_contains("Restarting", &mut stderr_lines).await;
|
||||
wait_for_watcher("main_file_to_watch.js", &mut stderr_lines).await;
|
||||
|
||||
let another_file = t.path().join("another_file.js");
|
||||
another_file.write("export const foo = 0;");
|
||||
// Confirm that the added file is watched as well
|
||||
wait_contains("Restarting", &mut stderr_lines).await;
|
||||
wait_for_watcher("main_file_to_watch.js", &mut stderr_lines).await;
|
||||
|
||||
main_file_to_watch
|
||||
.write("import { foo } from './another_file.js'; console.log(foo);");
|
||||
wait_contains("Restarting", &mut stderr_lines).await;
|
||||
wait_for_watcher("main_file_to_watch.js", &mut stderr_lines).await;
|
||||
wait_contains("0", &mut stdout_lines).await;
|
||||
|
||||
another_file.write("export const foo = 42;");
|
||||
wait_contains("Restarting", &mut stderr_lines).await;
|
||||
wait_for_watcher("main_file_to_watch.js", &mut stderr_lines).await;
|
||||
wait_contains("42", &mut stdout_lines).await;
|
||||
|
||||
// Confirm that watch continues even with wrong syntax error
|
||||
|
@ -623,10 +628,11 @@ async fn serve_watch_all() {
|
|||
|
||||
wait_contains("Restarting", &mut stderr_lines).await;
|
||||
wait_contains("error:", &mut stderr_lines).await;
|
||||
wait_for_watcher("main_file_to_watch.js", &mut stderr_lines).await;
|
||||
|
||||
main_file_to_watch.write(
|
||||
"export default {
|
||||
fetch(_request: Request) {
|
||||
fetch(_request) {
|
||||
return new Response(\"aaaaaaqqq!\");
|
||||
},
|
||||
};",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const assert = require("assert");
|
||||
const debug = require('util').debuglog('test');
|
||||
const process = require("process");
|
||||
|
||||
function onmessage(m) {
|
||||
debug("CHILD got message:", m);
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export function doThing() {
|
||||
return "thing";
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export function doThing() {
|
||||
return "thing2";
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
}
|
||||
}
|
6
tests/registry/jsr/@denotest/unstable/meta.json
Normal file
6
tests/registry/jsr/@denotest/unstable/meta.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"versions": {
|
||||
"1.0.0-beta.1": {},
|
||||
"1.0.0-beta.2": {}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,22 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [
|
||||
{
|
||||
"args": "add npm:@denotest/unstable",
|
||||
"output": "add.out"
|
||||
"tests": {
|
||||
"npm_package": {
|
||||
"steps": [
|
||||
{
|
||||
"args": "add npm:@denotest/unstable",
|
||||
"output": "add.out"
|
||||
}
|
||||
]
|
||||
},
|
||||
"jsr_package": {
|
||||
"steps": [
|
||||
{
|
||||
"args": "add jsr:@denotest/unstable",
|
||||
"output": "add_jsr.out",
|
||||
"exitCode": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
1
tests/specs/add/only_unstable_versions/add_jsr.out
Normal file
1
tests/specs/add/only_unstable_versions/add_jsr.out
Normal file
|
@ -0,0 +1 @@
|
|||
error: jsr:@denotest/unstable has only pre-release versions available. Try specifying a version: `deno add jsr:@denotest/unstable@^1.0.0-beta.2`
|
|
@ -8,6 +8,30 @@
|
|||
"well_formatted": {
|
||||
"args": "fmt --check well_formatted.yml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"ignore_line": {
|
||||
"args": "fmt --check ignore_line.yml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"ignore_file": {
|
||||
"args": "fmt ignore_file.yaml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"ignore_file2": {
|
||||
"args": "fmt ignore_file2.yaml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"ignore_file3": {
|
||||
"args": "fmt ignore_file3.yaml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"ignore_file4": {
|
||||
"args": "fmt ignore_file4.yaml",
|
||||
"output": "Checked 1 file\n"
|
||||
},
|
||||
"wrong_file_ignore": {
|
||||
"args": "fmt wrong_file_ignore.yaml",
|
||||
"output": "wrong_file_ignore.out"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
tests/specs/fmt/yaml/ignore_file.yaml
Normal file
2
tests/specs/fmt/yaml/ignore_file.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
# deno-fmt-ignore-file
|
||||
{{something crazy
|
2
tests/specs/fmt/yaml/ignore_file2.yaml
Normal file
2
tests/specs/fmt/yaml/ignore_file2.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
#deno-fmt-ignore-file
|
||||
{{something crazy
|
5
tests/specs/fmt/yaml/ignore_file3.yaml
Normal file
5
tests/specs/fmt/yaml/ignore_file3.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
||||
# incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
# quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
# deno-fmt-ignore-file
|
||||
{{something crazy
|
2
tests/specs/fmt/yaml/ignore_file4.yaml
Normal file
2
tests/specs/fmt/yaml/ignore_file4.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
# deno-fmt-ignore-file Because this is templated yaml file
|
||||
{{something crazy
|
2
tests/specs/fmt/yaml/ignore_line.yml
Normal file
2
tests/specs/fmt/yaml/ignore_line.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
# deno-fmt-ignore
|
||||
- Test
|
7
tests/specs/fmt/yaml/wrong_file_ignore.out
Normal file
7
tests/specs/fmt/yaml/wrong_file_ignore.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
Error formatting: [WILDCARD]wrong_file_ignore.yaml
|
||||
parse error at line 5, column 1
|
||||
|
|
||||
5 | {{something crazy
|
||||
| ^
|
||||
|
||||
Checked 1 file
|
5
tests/specs/fmt/yaml/wrong_file_ignore.yaml
Normal file
5
tests/specs/fmt/yaml/wrong_file_ignore.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
# File ignore directive only works if it's in the first cluster
|
||||
# of comment, ie. there are no empty lines after the first n-leading lines.
|
||||
|
||||
# deno-fmt-ignore-file
|
||||
{{something crazy
|
5
tests/specs/run/workspaces/wildcard/__test__.jsonc
Normal file
5
tests/specs/run/workspaces/wildcard/__test__.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"args": "run -L debug -A main.ts",
|
||||
"output": "main.out",
|
||||
"tempDir": true
|
||||
}
|
8
tests/specs/run/workspaces/wildcard/deno.json
Normal file
8
tests/specs/run/workspaces/wildcard/deno.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"workspace": [
|
||||
"./packages/*"
|
||||
],
|
||||
"imports": {
|
||||
"chalk": "npm:chalk"
|
||||
}
|
||||
}
|
22
tests/specs/run/workspaces/wildcard/main.out
Normal file
22
tests/specs/run/workspaces/wildcard/main.out
Normal file
|
@ -0,0 +1,22 @@
|
|||
[WILDCARD]Workspace config generated this import map {
|
||||
"imports": {
|
||||
"chalk": "npm:chalk",
|
||||
"chalk/": "npm:/chalk/"
|
||||
},
|
||||
"scopes": {
|
||||
"./packages/bar/": {
|
||||
"@/": "./packages/bar/",
|
||||
"secret_mod/": "./packages/bar/some_mod/"
|
||||
},
|
||||
"./packages/foo/": {
|
||||
"~/": "./packages/foo/",
|
||||
"foo/": "./packages/foo/bar/"
|
||||
}
|
||||
}
|
||||
}
|
||||
[WILDCARD]
|
||||
hello from foo
|
||||
buzz from foo
|
||||
hello from bar
|
||||
buzz from bar
|
||||
[Function: chalk][WILDCARD]
|
5
tests/specs/run/workspaces/wildcard/main.ts
Normal file
5
tests/specs/run/workspaces/wildcard/main.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import chalk from "chalk";
|
||||
import "./packages/foo/mod.ts";
|
||||
import "./packages/bar/mod.ts";
|
||||
|
||||
console.log(chalk);
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "asdfasdfasdf",
|
||||
"version": "0.0.0",
|
||||
"imports": {
|
||||
"@/": "./",
|
||||
"secret_mod/": "./some_mod/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export const buzz = "buzz from bar";
|
5
tests/specs/run/workspaces/wildcard/packages/bar/mod.ts
Normal file
5
tests/specs/run/workspaces/wildcard/packages/bar/mod.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { hello } from "secret_mod/hello.ts";
|
||||
import { buzz } from "@/fizz/buzz.ts";
|
||||
|
||||
console.log(hello);
|
||||
console.log(buzz);
|
|
@ -0,0 +1 @@
|
|||
export const hello = "hello from bar";
|
|
@ -0,0 +1 @@
|
|||
export const hello = "hello from foo";
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "qwerqwer",
|
||||
"version": "0.0.0",
|
||||
"imports": {
|
||||
"~/": "./",
|
||||
"foo/": "./bar/"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export const buzz = "buzz from foo";
|
5
tests/specs/run/workspaces/wildcard/packages/foo/mod.ts
Normal file
5
tests/specs/run/workspaces/wildcard/packages/foo/mod.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { hello } from "foo/hello.ts";
|
||||
import { buzz } from "~/fizz/buzz.ts";
|
||||
|
||||
console.log(hello);
|
||||
console.log(buzz);
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// deno-lint-ignore-file no-node-globals
|
||||
|
||||
import {
|
||||
assert,
|
||||
|
|
|
@ -56,12 +56,13 @@ async function dlint() {
|
|||
":!:cli/tsc/compiler.d.ts",
|
||||
":!:runtime/examples/",
|
||||
":!:target/",
|
||||
":!:tests/ffi/tests/test.js",
|
||||
":!:tests/registry/**",
|
||||
":!:tests/specs/**",
|
||||
":!:tests/testdata/**",
|
||||
":!:tests/unit_node/testdata/**",
|
||||
":!:tests/wpt/suite/**",
|
||||
":!:tests/wpt/runner/**",
|
||||
":!:tests/wpt/suite/**",
|
||||
]);
|
||||
|
||||
if (!sourceFiles.length) {
|
||||
|
|
|
@ -11,7 +11,7 @@ export { delay } from "@std/async/delay";
|
|||
|
||||
// [toolName] --version output
|
||||
const versions = {
|
||||
"dlint": "dlint 0.60.0",
|
||||
"dlint": "dlint 0.68.0",
|
||||
};
|
||||
|
||||
const compressed = new Set(["ld64.lld", "rcodesign"]);
|
||||
|
@ -178,7 +178,7 @@ export function getPrebuiltToolPath(toolName) {
|
|||
return join(PREBUILT_TOOL_DIR, toolName + executableSuffix);
|
||||
}
|
||||
|
||||
const commitId = "b8aac22e0cd7c1c6557a56a813fe0c25486fafee";
|
||||
const commitId = "7a3a6fee951b3381c59aa4c907274957f324ce8c";
|
||||
const downloadUrl =
|
||||
`https://raw.githubusercontent.com/denoland/deno_third_party/${commitId}/prebuilt/${platformDirName}`;
|
||||
|
||||
|
|
Loading…
Reference in a new issue