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/module_loader.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/module_loader.rs')
-rw-r--r-- | cli/module_loader.rs | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/cli/module_loader.rs b/cli/module_loader.rs index d452c30cf..d507a5b15 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -20,6 +20,7 @@ use deno_core::ModuleSource; use deno_core::ModuleSpecifier; use deno_core::ModuleType; use deno_core::OpState; +use deno_core::ResolutionKind; use deno_core::SourceMapGetter; use deno_runtime::permissions::PermissionsContainer; use std::cell::RefCell; @@ -36,28 +37,38 @@ struct ModuleCodeSource { pub struct CliModuleLoader { pub lib: TsTypeLib, /// The initial set of permissions used to resolve the static imports in the - /// worker. They are decoupled from the worker (dynamic) permissions since - /// read access errors must be raised based on the parent thread permissions. + /// worker. These are "allow all" for main worker, and parent thread + /// permissions for Web Worker. pub root_permissions: PermissionsContainer, + /// Permissions used to resolve dynamic imports, these get passed as + /// "root permissions" for Web Worker. + dynamic_permissions: PermissionsContainer, pub ps: ProcState, } impl CliModuleLoader { - pub fn new(ps: ProcState) -> Rc<Self> { + pub fn new( + ps: ProcState, + root_permissions: PermissionsContainer, + dynamic_permissions: PermissionsContainer, + ) -> Rc<Self> { Rc::new(CliModuleLoader { lib: ps.options.ts_type_lib_window(), - root_permissions: PermissionsContainer::allow_all(), + root_permissions, + dynamic_permissions, ps, }) } pub fn new_for_worker( ps: ProcState, - permissions: PermissionsContainer, + root_permissions: PermissionsContainer, + dynamic_permissions: PermissionsContainer, ) -> Rc<Self> { Rc::new(CliModuleLoader { lib: ps.options.ts_type_lib_worker(), - root_permissions: permissions, + root_permissions, + dynamic_permissions, ps, }) } @@ -138,6 +149,7 @@ impl CliModuleLoader { &self, specifier: &ModuleSpecifier, maybe_referrer: Option<ModuleSpecifier>, + is_dynamic: bool, ) -> Result<ModuleSource, AnyError> { let code_source = if self.ps.npm_resolver.in_npm_package(specifier) { let file_path = specifier.to_file_path().unwrap(); @@ -152,6 +164,11 @@ impl CliModuleLoader { })?; let code = if self.ps.cjs_resolutions.lock().contains(specifier) { + let mut permissions = if is_dynamic { + self.dynamic_permissions.clone() + } else { + self.root_permissions.clone() + }; // translate cjs to esm if it's cjs and inject node globals node::translate_cjs_to_esm( &self.ps.file_fetcher, @@ -160,6 +177,7 @@ impl CliModuleLoader { MediaType::Cjs, &self.ps.npm_resolver, &self.ps.node_analysis_cache, + &mut permissions, )? } else { // only inject node globals for esm @@ -203,28 +221,35 @@ impl ModuleLoader for CliModuleLoader { &self, specifier: &str, referrer: &str, - _is_main: bool, + kind: ResolutionKind, ) -> Result<ModuleSpecifier, AnyError> { - self.ps.resolve(specifier, referrer) + let mut permissions = if matches!(kind, ResolutionKind::DynamicImport) { + self.dynamic_permissions.clone() + } else { + self.root_permissions.clone() + }; + self.ps.resolve(specifier, referrer, &mut permissions) } fn load( &self, specifier: &ModuleSpecifier, maybe_referrer: Option<ModuleSpecifier>, - _is_dynamic: bool, + is_dynamic: bool, ) -> Pin<Box<deno_core::ModuleSourceFuture>> { // NOTE: this block is async only because of `deno_core` interface // requirements; module was already loaded when constructing module graph // during call to `prepare_load` so we can load it synchronously. - Box::pin(deno_core::futures::future::ready( - self.load_sync(specifier, maybe_referrer), - )) + Box::pin(deno_core::futures::future::ready(self.load_sync( + specifier, + maybe_referrer, + is_dynamic, + ))) } fn prepare_load( &self, - op_state: Rc<RefCell<OpState>>, + _op_state: Rc<RefCell<OpState>>, specifier: &ModuleSpecifier, _maybe_referrer: Option<String>, is_dynamic: bool, @@ -236,18 +261,15 @@ impl ModuleLoader for CliModuleLoader { let specifier = specifier.clone(); let ps = self.ps.clone(); - let state = op_state.borrow(); - let dynamic_permissions = state.borrow::<PermissionsContainer>().clone(); + let dynamic_permissions = self.dynamic_permissions.clone(); let root_permissions = if is_dynamic { - dynamic_permissions.clone() + self.dynamic_permissions.clone() } else { self.root_permissions.clone() }; let lib = self.lib; - drop(state); - async move { ps.prepare_module_load( vec![specifier], |