From d12026d12b07dcbfd8bd1914cdcd292888cec37f Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sun, 4 Apr 2021 17:10:23 -0600 Subject: prevent circular inference chains --- src/makefile/mod.rs | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs index 1f0b8a2..b887ad4 100644 --- a/src/makefile/mod.rs +++ b/src/makefile/mod.rs @@ -37,7 +37,6 @@ pub struct Makefile<'a> { pub first_non_special_target: Option, args: &'a Args, // TODO borrow warnings from Python version - fucking_bullshit_recursion_stack: RefCell>, } impl<'a> Makefile<'a> { @@ -76,7 +75,6 @@ impl<'a> Makefile<'a> { targets: RefCell::new(targets), first_non_special_target, args, - fucking_bullshit_recursion_stack: RefCell::new(Vec::new()), } } @@ -104,7 +102,16 @@ impl<'a> Makefile<'a> { } } - fn infer_target(&self, name: &str, banned_rules: Vec<&InferenceRule>) -> Result<()> { + fn infer_target( + &self, + name: &str, + banned_rules: Vec<&InferenceRule>, + banned_names: Vec<&str>, + ) -> Result<()> { + if banned_names.contains(&name) { + bail!("no infinite recursion allowed"); + } + log::trace!("inferring {}, stack = {:?}", name, banned_names); let mut new_target = None; let follow_gnu = cfg!(feature = "full"); @@ -141,7 +148,7 @@ impl<'a> Makefile<'a> { .prereqs(name)? .inspect(|x| log::trace!("{:>58} prereq {}", name, x)) .map(|prereq_path_name| { - if name == prereq_path_name { + if name == prereq_path_name || banned_names.contains(&&*prereq_path_name) { // we can't build this based on itself! fuck outta here return None; } @@ -163,7 +170,9 @@ impl<'a> Makefile<'a> { .or_else(|| { let mut banned_rules = banned_rules.clone(); banned_rules.push(rule); - self.infer_target(&prereq_path_name, banned_rules) + let mut banned_names = banned_names.clone(); + banned_names.push(name); + self.infer_target(&prereq_path_name, banned_rules, banned_names) .ok() .and_then(|_| { if self.targets.borrow().contains_key(&prereq_path_name) { @@ -199,16 +208,6 @@ impl<'a> Makefile<'a> { } pub fn get_target(&self, name: &str) -> Result>> { - if self - .fucking_bullshit_recursion_stack - .borrow() - .contains(&name.to_owned()) - { - bail!("no infinite recursion allowed"); - } - self.fucking_bullshit_recursion_stack - .borrow_mut() - .push(name.to_owned()); // TODO implement .POSIX let follow_gnu = cfg!(feature = "full"); @@ -221,7 +220,7 @@ impl<'a> Makefile<'a> { false }; if !self.targets.borrow().contains_key(name) || exists_but_infer_anyway { - self.infer_target(name, vec![])?; + self.infer_target(name, vec![], vec![])?; } let mut new_target = None; @@ -258,8 +257,6 @@ impl<'a> Makefile<'a> { .insert(new_target.name.clone(), Rc::new(RefCell::new(new_target))); } - self.fucking_bullshit_recursion_stack.borrow_mut().pop(); - let targets = self.targets.borrow(); Ok(Rc::clone( targets @@ -469,7 +466,6 @@ mod test { targets: Default::default(), first_non_special_target: None, args: &args, - fucking_bullshit_recursion_stack: Default::default(), }; let target = file.get_target("this-is-a-test-case")?; -- cgit v1.2.3