Remove vars after leaving dir

This commit is contained in:
Sam Hedin 2020-06-06 12:53:45 +02:00
parent 03febb8cab
commit d6e1a0e616
4 changed files with 48 additions and 13 deletions

View File

@ -889,7 +889,6 @@ async fn process_line(
trace!("{:#?}", classified_block);
let env = ctx.get_env();
match run_block(
&classified_block.block,
ctx,

View File

@ -120,4 +120,31 @@ impl DirectorySpecificEnvironment {
Ok(vars_to_add)
}
//If the user has left directories which added env vars through .nu, we clear those vars
pub fn env_vars_to_delete(&mut self) -> std::io::Result<Vec<String>> {
let current_dir = std::env::current_dir()?;
//Gather up all environment variables that should be deleted.
//If we are not in a directory or one of its subdirectories, mark the env_vals it maps to for removal.
let vars_to_delete = self.added_env_vars.iter().fold(
Vec::new(),
|mut vars_to_delete, (directory, env_vars)| {
let mut working_dir = Some(current_dir.as_path());
while let Some(wdir) = working_dir {
if &wdir == directory {
return vars_to_delete;
} else {
working_dir = working_dir.unwrap().parent();
}
}
//only delete vars from directories we are not in
vars_to_delete.extend(env_vars.clone());
vars_to_delete
},
);
Ok(vars_to_delete)
}
}

View File

@ -59,18 +59,33 @@ impl Environment {
}
pub fn maintain_directory_environment(&mut self) -> std::io::Result<()> {
self.direnv.env_vars_to_delete()?.iter().for_each(|k| {
self.remove_env(&k);
});
self.direnv.env_vars_to_add()?.iter().for_each(|(k, v)| {
self.add_env(&k, &v, true);
});
self.direnv.overwritten_values_to_restore()?.iter().for_each(|(k, v)| {
self.add_env(&k, &v, true);
});
self.direnv
.overwritten_values_to_restore()?
.iter()
.for_each(|(k, v)| {
self.add_env(&k, &v, true);
});
Ok(())
}
fn remove_env(&mut self, key: &str) {
if let Some(Value {
value: UntaggedValue::Row(ref mut envs),
tag: _,
}) = self.environment_vars
{
envs.entries.remove(key);
};
}
pub fn morph<T: Conf>(&mut self, configuration: &T) {
self.environment_vars = configuration.env();
self.path_vars = configuration.path();

View File

@ -13,22 +13,16 @@ In order for a .nu-file to be read, the directory it is in must be listed in the
nu_env_dirs = ["/home/sam", "/home/sam/github", "/home/sam/github/test"]
```
This was implemented for the sake of security. I do not believe that it is appropiate for nushell to pick up random .nu-files unless
the user has explicitly said that it's alright. An adversary could hide a .nu-file in an otherwise unsuspicous folder that you download,
the user has explicitly said that it's alright. An adversary could hide a .nu-file in an otherwise unsuspicious folder that you download,
and now you suddenly have nushell picking up whatever environment variables they set.
This meant that the code necessarily become more involved than just looking for a .nu-file in the current directory and applying its variables,
but this extra code also allowed for some other nice features and behavior which is listed below.
Behavior:
- If you are in a subdirectory to a directory with a .nu-file, the vars in that .nu-file are applied.
- If you are in a directory, or a subdirectory to a directory with a .nu-file, the vars in that .nu-file are applied.
- If you leave a directory which set some variables, the variables are unset.
- If a directory contains a .nu with an environment variable already set, the old value will be overwritten with the value from the .nu. This holds even if the old value was set by a .nu in a parent directory.
- The overwritten value is restored when you leave the directory.
- TODO: What happens if you overwrite twice?
Questions:
`remove_env()` accesses the environment directly to remove variables.
Just using what I think was expected, envs.entries.remove(key), does not work.
If this is a problem, how can I make it work better with existing code?
----