Repository: nushell/nushell
File: crates/nu-cmd-plugin/src/util.rs (Rust)

Code before:
    // Try to read the plugin file if it exists
    let mut contents = if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
        PluginRegistryFile::read_from(
            File::open(&plugin_registry_file_path)
                .map_err(|err| IoError::new(err, file_span, plugin_registry_file_path.clone()))?,
            Some(file_span),
        )?
    } else {
        PluginRegistryFile::default()
    };

    // Do the operation
    operate(&mut contents)?;

    // Save the modified file on success
    // First, ensure the parent directory exists
    if let Some(parent_dir) = plugin_registry_file_path.parent()
        && !parent_dir.exists()
    {
        fs::create_dir_all(parent_dir).map_err(|err| {
            IoError::new_with_additional_context(
                err.not_found_as(NotFound::Directory),
                file_span,
                parent_dir.to_path_buf(),
                "Cannot create plugin config directory. \
                Ensure the parent path is accessible and you have write permissions"
                    .to_string(),
            )
        })?;
    }

    // Now create the file
    contents.write_to(
        File::create(&plugin_registry_file_path)
            .map_err(|err| IoError::new(err, file_span, plugin_registry_file_path))?,
        Some(span),
    )?;

    Ok(())
}

pub(crate) fn canonicalize_possible_filename_arg(
    engine_state: &EngineState,
    stack: &Stack,
    arg: &str,
) -> PathBuf {
    // This results in the best possible chance of a match with the plugin item
    #[allow(deprecated)]
    if let Ok(cwd) = nu_engine::current_dir(engine_state, stack) {
        let path = nu_path::expand_path_with(arg, &cwd, true);
        // Try to canonicalize

Review comment (security):
I don't think you have to write this long context. If you don't have the permissions to create such a dir, you already get a permissions denied error, making this very obvious. Very long messages in our messages get somewhat messy. You don't have to remove that, just wanna say. You can take a look how it looks in your terminal.

Code after:
    // Try to read the plugin file if it exists
    let mut contents = if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
        PluginRegistryFile::read_from(
            File::open(&plugin_registry_file_path)
                .map_err(|err| IoError::new(err, file_span, plugin_registry_file_path.clone()))?,
            Some(file_span),
        )?
    } else {
        PluginRegistryFile::default()
    };

    // Do the operation
    operate(&mut contents)?;

    // Save the modified file on success
    // First, ensure the parent directory exists
    if let Some(parent_dir) = plugin_registry_file_path.parent() {
        fs::create_dir_all(parent_dir).map_err(|err| {
            IoError::new(
                err.not_found_as(NotFound::Directory),
                file_span,
                parent_dir.to_path_buf(),
            )
        })?;
    }

    // Now create the file
    contents.write_to(
        File::create(&plugin_registry_file_path)
            .map_err(|err| IoError::new(err, file_span, plugin_registry_file_path))?,
        Some(span),
    )?;

    Ok(())
}

pub(crate) fn canonicalize_possible_filename_arg(
    engine_state: &EngineState,
    stack: &Stack,
    arg: &str,
) -> PathBuf {
    // This results in the best possible chance of a match with the plugin item
    #[allow(deprecated)]
    if let Ok(cwd) = nu_engine::current_dir(engine_state, stack) {
        let path = nu_path::expand_path_with(arg, &cwd, true);
        // Try to canonicalize
        nu_path::locate_in_dirs(&path, &cwd, || get_plugin_dirs(engine_state, stack))
            // If we couldn't locate it, return the expanded path alone
            .unwrap_or(path)
    } else {
        arg.into()