mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Enforce that nobody can push/pop from the global environment stack
This is just a precaution.
This commit is contained in:
parent
7fcbe5b8ab
commit
9ad875cdb7
2 changed files with 22 additions and 2 deletions
9
src/env/environment.rs
vendored
9
src/env/environment.rs
vendored
|
@ -173,12 +173,14 @@ impl EnvScoped {
|
|||
/// This backs the parser's "vars".
|
||||
pub struct EnvStack {
|
||||
inner: EnvMutex<EnvStackImpl>,
|
||||
can_push_pop: bool, // If false, panic on push/pop. Used for the global stack.
|
||||
}
|
||||
|
||||
impl EnvStack {
|
||||
pub fn new() -> EnvStack {
|
||||
EnvStack {
|
||||
inner: EnvStackImpl::new(),
|
||||
can_push_pop: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,6 +293,7 @@ impl EnvStack {
|
|||
|
||||
/// Push the variable stack. Used for implementing local variables for functions and for-loops.
|
||||
pub fn push(&self, new_scope: bool) {
|
||||
assert!(self.can_push_pop, "push/pop not allowed on global stack");
|
||||
let mut imp = self.lock();
|
||||
if new_scope {
|
||||
imp.push_shadowing();
|
||||
|
@ -301,6 +304,7 @@ impl EnvStack {
|
|||
|
||||
/// Pop the variable stack. Used for implementing local variables for functions and for-loops.
|
||||
pub fn pop(&self) {
|
||||
assert!(self.can_push_pop, "push/pop not allowed on global stack");
|
||||
let popped = self.lock().pop();
|
||||
// Only dispatch variable changes if we are the principal environment.
|
||||
if self.is_principal() {
|
||||
|
@ -363,7 +367,10 @@ impl EnvStack {
|
|||
pub fn globals() -> &'static EnvStack {
|
||||
use std::sync::OnceLock;
|
||||
static GLOBALS: OnceLock<EnvStack> = OnceLock::new();
|
||||
GLOBALS.get_or_init(EnvStack::new)
|
||||
GLOBALS.get_or_init(|| EnvStack {
|
||||
inner: EnvStackImpl::new(),
|
||||
can_push_pop: false,
|
||||
})
|
||||
}
|
||||
|
||||
/// Access the principal variable stack, associated with the principal parser.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::env::{EnvMode, EnvVar, EnvVarFlags, Environment};
|
||||
use crate::env::{EnvMode, EnvStack, EnvVar, EnvVarFlags, Environment};
|
||||
use crate::parser::Parser;
|
||||
use crate::tests::prelude::*;
|
||||
use crate::wchar::prelude::*;
|
||||
|
@ -177,3 +177,16 @@ fn test_env_snapshot() {
|
|||
vars.pop();
|
||||
popd();
|
||||
}
|
||||
|
||||
// Can't push/pop from globals.
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_no_global_push() {
|
||||
EnvStack::globals().push(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_no_global_pop() {
|
||||
EnvStack::globals().pop();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue