mirror of
https://github.com/nushell/nushell
synced 2024-12-28 14:03:09 +00:00
Disallow setting the PWD
via load-env
input (#12522)
# Description Fixes #12520 # User-Facing Changes Breaking change: Any operation parsing input with `PWD` to set the environment will now fail with `ShellError::AutomaticEnvVarSetManually` Furthermore transactions containing the special env-vars will be rejected before executing any modifications. Prevoiusly this was changing valid variables before while leaving valid variables after the violation untouched. ## `PWD` handling. Now failing ``` {PWD: "/trolling"} | load-env ``` already failing ``` load-env {PWD: "/trolling"} ``` ## Error management ``` > load-env {MY_VAR1: foo, PWD: "/trolling", MY_VAR2: bar} Error: nu:🐚:automatic_env_var_set_manually × PWD cannot be set manually. ╭─[entry #1:1:2] 1 │ load-env {MY_VAR1: foo, PWD: "/trolling", MY_VAR2: bar} · ────┬─── · ╰── cannot set 'PWD' manually ╰──── help: The environment variable 'PWD' is set automatically by Nushell and cannot be set manually. ``` ### Before: ``` > $env.MY_VAR1 foo > $env.MY_VAR2 Error: nu:🐚:name_not_found .... ``` ### After: ``` > $env.MY_VAR1 Error: nu:🐚:name_not_found .... > $env.MY_VAR2 Error: nu:🐚:name_not_found .... ``` # After Submitting We need to check if any integrations rely on this hack.
This commit is contained in:
parent
c06ef201b7
commit
078ba5aabe
1 changed files with 25 additions and 44 deletions
69
crates/nu-command/src/env/load_env.rs
vendored
69
crates/nu-command/src/env/load_env.rs
vendored
|
@ -1,4 +1,4 @@
|
|||
use nu_engine::{command_prelude::*, current_dir};
|
||||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LoadEnv;
|
||||
|
@ -37,53 +37,34 @@ impl Command for LoadEnv {
|
|||
let arg: Option<Record> = call.opt(engine_state, stack, 0)?;
|
||||
let span = call.head;
|
||||
|
||||
match arg {
|
||||
Some(record) => {
|
||||
for (env_var, rhs) in record {
|
||||
let env_var_ = env_var.as_str();
|
||||
if ["FILE_PWD", "CURRENT_FILE", "PWD"].contains(&env_var_) {
|
||||
return Err(ShellError::AutomaticEnvVarSetManually {
|
||||
envvar_name: env_var,
|
||||
span: call.head,
|
||||
});
|
||||
}
|
||||
stack.add_env_var(env_var, rhs);
|
||||
}
|
||||
Ok(PipelineData::empty())
|
||||
}
|
||||
let record = match arg {
|
||||
Some(record) => record,
|
||||
None => match input {
|
||||
PipelineData::Value(Value::Record { val, .. }, ..) => {
|
||||
for (env_var, rhs) in val.into_owned() {
|
||||
let env_var_ = env_var.as_str();
|
||||
if ["FILE_PWD", "CURRENT_FILE"].contains(&env_var_) {
|
||||
return Err(ShellError::AutomaticEnvVarSetManually {
|
||||
envvar_name: env_var,
|
||||
span: call.head,
|
||||
});
|
||||
}
|
||||
|
||||
if env_var == "PWD" {
|
||||
let cwd = current_dir(engine_state, stack)?;
|
||||
let rhs = rhs.coerce_into_string()?;
|
||||
let rhs = nu_path::expand_path_with(rhs, cwd, true);
|
||||
stack.add_env_var(
|
||||
env_var,
|
||||
Value::string(rhs.to_string_lossy(), call.head),
|
||||
);
|
||||
} else {
|
||||
stack.add_env_var(env_var, rhs);
|
||||
}
|
||||
}
|
||||
Ok(PipelineData::empty())
|
||||
PipelineData::Value(Value::Record { val, .. }, ..) => val.into_owned(),
|
||||
_ => {
|
||||
return Err(ShellError::UnsupportedInput {
|
||||
msg: "'load-env' expects a single record".into(),
|
||||
input: "value originated from here".into(),
|
||||
msg_span: span,
|
||||
input_span: input.span().unwrap_or(span),
|
||||
})
|
||||
}
|
||||
_ => Err(ShellError::UnsupportedInput {
|
||||
msg: "'load-env' expects a single record".into(),
|
||||
input: "value originated from here".into(),
|
||||
msg_span: span,
|
||||
input_span: input.span().unwrap_or(span),
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
for prohibited in ["FILE_PWD", "CURRENT_FILE", "PWD"] {
|
||||
if record.contains(prohibited) {
|
||||
return Err(ShellError::AutomaticEnvVarSetManually {
|
||||
envvar_name: prohibited.to_string(),
|
||||
span: call.head,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (env_var, rhs) in record {
|
||||
stack.add_env_var(env_var, rhs);
|
||||
}
|
||||
Ok(PipelineData::empty())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
|
Loading…
Reference in a new issue