Repository: denoland/deno
File: runtime/permissions/lib.rs (Rust)

Code before:
        ChildUnaryPermissionArg::Inherit | ChildUnaryPermissionArg::Granted => {
          true
        }
        ChildUnaryPermissionArg::NotGranted
        | ChildUnaryPermissionArg::GrantedList(_) => false,
      }
    }

    let mut worker_perms = Permissions::none_without_prompt();

    let mut inner = self.inner.lock();
    worker_perms.all = inner
      .all
      .create_child_permissions(ChildUnitPermissionArg::Inherit)?;

    // downgrade the `worker_perms.all` based on the other values
    if worker_perms.all.query() == PermissionState::Granted {
      let unary_perms = [
        &child_permissions_arg.read,
        &child_permissions_arg.write,
        &child_permissions_arg.net,
        &child_permissions_arg.import,
        &child_permissions_arg.env,
        &child_permissions_arg.sys,
        &child_permissions_arg.run,
        &child_permissions_arg.ffi,
      ];
      let allow_all = unary_perms.into_iter().all(is_granted_unary);
      if !allow_all {
        worker_perms.all.revoke();
      }
    }

    // WARNING: When adding a permission here, ensure it is handled
    // in the worker_perms.all block above
    worker_perms.read = inner.read.create_child_permissions(
      child_permissions_arg.read,
      |text| {
        Ok::<_, PathResolveError>(Some(
          self.descriptor_parser.parse_read_descriptor(text)?,
        ))
      },
    )?;
    worker_perms.write = inner.write.create_child_permissions(
      child_permissions_arg.write,
      |text| {
        Ok::<_, PathResolveError>(Some(
          self.descriptor_parser.parse_write_descriptor(text)?,
        ))
      },
    )?;

Review comment (security):
@bartlomieju checking 8 different fields was already necessary for updating this state as can be seen here (and I'd need to add similar code in the permissions in the config file pr). It's much better/less error prone for it to be derived.

Code after:
    descriptor_parser: Arc<dyn PermissionDescriptorParser>,
  ) -> Self {
    Self::new(descriptor_parser, Permissions::allow_all())
  }

  pub fn create_child_permissions(
    &self,
    child_permissions_arg: ChildPermissionsArg,
  ) -> Result<PermissionsContainer, ChildPermissionError> {
    let mut worker_perms = Permissions::none_without_prompt();

    let mut inner = self.inner.lock();

    // WARNING: When adding a permission here, ensure it is handled
    // in the worker_perms.all block above
    worker_perms.read = inner.read.create_child_permissions(
      child_permissions_arg.read,
      |text| {
        Ok::<_, PathResolveError>(Some(
          self.descriptor_parser.parse_read_descriptor(text)?,
        ))
      },
    )?;
    worker_perms.write = inner.write.create_child_permissions(
      child_permissions_arg.write,
      |text| {
        Ok::<_, PathResolveError>(Some(
          self.descriptor_parser.parse_write_descriptor(text)?,
        ))
      },
    )?;
    worker_perms.import = inner.import.create_child_permissions(
      child_permissions_arg.import,
      |text| {
        Ok::<_, NetDescriptorParseError>(Some(
          self.descriptor_parser.parse_import_descriptor(text)?,
        ))
      },
    )?;
    worker_perms.net = inner.net.create_child_permissions(
      child_permissions_arg.net,
      |text| {
        Ok::<_, NetDescriptorParseError>(Some(
          self.descriptor_parser.parse_net_descriptor(text)?,
        ))
      },
    )?;
    worker_perms.env = inner.env.create_child_permissions(
      child_permissions_arg.env,
      |text| {
        Ok::<_, EnvDescriptorParseError>(Some(