diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-01-10 14:35:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-10 14:35:44 +0100 |
commit | 636352e0ca1e611c7673f2ab68538e1ddb2dc5b7 (patch) | |
tree | c250c7a74917cef683999e06283ea9f7182f372c /cli/node/mod.rs | |
parent | 45768f0e832e54d61ddb5a62d62239aef0e597b5 (diff) |
fix(npm): allow to read package.json if permissions are granted (#17209)
This commit changes signature of "deno_core::ModuleLoader::resolve" to pass
an enum indicating whether or not we're resolving a specifier for dynamic import.
Additionally "CliModuleLoader" was changes to store both "parent permissions" (or
"root permissions") as well as "dynamic permissions" that allow to check for permissions
in top-level module load an dynamic imports.
Then all code paths that have anything to do with Node/npm compat are now checking
for permissions which are passed from module loader instance associated with given
worker.
Diffstat (limited to 'cli/node/mod.rs')
-rw-r--r-- | cli/node/mod.rs | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/cli/node/mod.rs b/cli/node/mod.rs index e6cc22255..aed639bc4 100644 --- a/cli/node/mod.rs +++ b/cli/node/mod.rs @@ -25,12 +25,14 @@ use deno_runtime::deno_node::package_imports_resolve; use deno_runtime::deno_node::package_resolve; use deno_runtime::deno_node::path_to_declaration_path; use deno_runtime::deno_node::NodeModuleKind; +use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; use deno_runtime::deno_node::PackageJson; use deno_runtime::deno_node::PathClean; use deno_runtime::deno_node::RequireNpmResolver; use deno_runtime::deno_node::DEFAULT_CONDITIONS; use deno_runtime::deno_node::NODE_GLOBAL_THIS_NAME; +use deno_runtime::permissions::PermissionsContainer; use once_cell::sync::Lazy; use regex::Regex; @@ -440,6 +442,7 @@ pub fn node_resolve( referrer: &ModuleSpecifier, mode: NodeResolutionMode, npm_resolver: &dyn RequireNpmResolver, + permissions: &mut dyn NodePermissions, ) -> Result<Option<NodeResolution>, AnyError> { // Note: if we are here, then the referrer is an esm module // TODO(bartlomieju): skipped "policy" part as we don't plan to support it @@ -481,6 +484,7 @@ pub fn node_resolve( DEFAULT_CONDITIONS, mode, npm_resolver, + permissions, )?; let url = match url { Some(url) => url, @@ -510,6 +514,7 @@ pub fn node_resolve_npm_reference( reference: &NpmPackageReference, mode: NodeResolutionMode, npm_resolver: &NpmPackageResolver, + permissions: &mut dyn NodePermissions, ) -> Result<Option<NodeResolution>, AnyError> { let package_folder = npm_resolver.resolve_package_folder_from_deno_module(&reference.req)?; @@ -525,6 +530,7 @@ pub fn node_resolve_npm_reference( DEFAULT_CONDITIONS, mode, npm_resolver, + permissions, ) .with_context(|| { format!("Error resolving package config for '{}'", reference) @@ -553,11 +559,13 @@ pub fn node_resolve_binary_export( pkg_req: &NpmPackageReq, bin_name: Option<&str>, npm_resolver: &NpmPackageResolver, + permissions: &mut dyn NodePermissions, ) -> Result<NodeResolution, AnyError> { let package_folder = npm_resolver.resolve_package_folder_from_deno_module(pkg_req)?; let package_json_path = package_folder.join("package.json"); - let package_json = PackageJson::load(npm_resolver, package_json_path)?; + let package_json = + PackageJson::load(npm_resolver, permissions, package_json_path)?; let bin = match &package_json.bin { Some(bin) => bin, None => bail!( @@ -665,11 +673,12 @@ fn package_config_resolve( conditions: &[&str], mode: NodeResolutionMode, npm_resolver: &dyn RequireNpmResolver, + permissions: &mut dyn NodePermissions, ) -> Result<Option<PathBuf>, AnyError> { let package_json_path = package_dir.join("package.json"); let referrer = ModuleSpecifier::from_directory_path(package_dir).unwrap(); let package_config = - PackageJson::load(npm_resolver, package_json_path.clone())?; + PackageJson::load(npm_resolver, permissions, package_json_path.clone())?; if let Some(exports) = &package_config.exports { let result = package_exports_resolve( &package_json_path, @@ -680,6 +689,7 @@ fn package_config_resolve( conditions, mode, npm_resolver, + permissions, ); match result { Ok(found) => return Ok(Some(found)), @@ -712,7 +722,11 @@ pub fn url_to_node_resolution( if url_str.starts_with("http") { Ok(NodeResolution::Esm(url)) } else if url_str.ends_with(".js") || url_str.ends_with(".d.ts") { - let package_config = get_closest_package_json(&url, npm_resolver)?; + let package_config = get_closest_package_json( + &url, + npm_resolver, + &mut PermissionsContainer::allow_all(), + )?; if package_config.typ == "module" { Ok(NodeResolution::Esm(url)) } else { @@ -786,6 +800,7 @@ fn module_resolve( conditions: &[&str], mode: NodeResolutionMode, npm_resolver: &dyn RequireNpmResolver, + permissions: &mut dyn NodePermissions, ) -> Result<Option<ModuleSpecifier>, AnyError> { // note: if we're here, the referrer is an esm module let url = if should_be_treated_as_relative_or_absolute_path(specifier) { @@ -811,6 +826,7 @@ fn module_resolve( conditions, mode, npm_resolver, + permissions, ) .map(|p| ModuleSpecifier::from_file_path(p).unwrap())?, ) @@ -824,6 +840,7 @@ fn module_resolve( conditions, mode, npm_resolver, + permissions, )? .map(|p| ModuleSpecifier::from_file_path(p).unwrap()) }; @@ -879,6 +896,7 @@ pub fn translate_cjs_to_esm( media_type: MediaType, npm_resolver: &NpmPackageResolver, node_analysis_cache: &NodeAnalysisCache, + permissions: &mut dyn NodePermissions, ) -> Result<String, AnyError> { fn perform_cjs_analysis( analysis_cache: &NodeAnalysisCache, @@ -956,6 +974,7 @@ pub fn translate_cjs_to_esm( &["deno", "require", "default"], NodeResolutionMode::Execution, npm_resolver, + permissions, )?; let reexport_specifier = ModuleSpecifier::from_file_path(resolved_reexport).unwrap(); @@ -1027,6 +1046,7 @@ fn resolve( conditions: &[&str], mode: NodeResolutionMode, npm_resolver: &dyn RequireNpmResolver, + permissions: &mut dyn NodePermissions, ) -> Result<PathBuf, AnyError> { if specifier.starts_with('/') { todo!(); @@ -1056,7 +1076,7 @@ fn resolve( let package_json_path = module_dir.join("package.json"); if package_json_path.exists() { let package_json = - PackageJson::load(npm_resolver, package_json_path.clone())?; + PackageJson::load(npm_resolver, permissions, package_json_path.clone())?; if let Some(exports) = &package_json.exports { return package_exports_resolve( @@ -1068,6 +1088,7 @@ fn resolve( conditions, mode, npm_resolver, + permissions, ); } @@ -1080,7 +1101,7 @@ fn resolve( let package_json_path = d.join("package.json"); if package_json_path.exists() { let package_json = - PackageJson::load(npm_resolver, package_json_path)?; + PackageJson::load(npm_resolver, permissions, package_json_path)?; if let Some(main) = package_json.main(NodeModuleKind::Cjs) { return Ok(d.join(main).clean()); } |