aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-04-04 17:10:23 -0600
committerMelody Horn <melody@boringcactus.com>2021-04-04 17:10:23 -0600
commitd12026d12b07dcbfd8bd1914cdcd292888cec37f (patch)
tree7e9d4f4fb9ae72cba390d600b327c9d78c035889
parentfb11514c230a1ab6428b2d754c5d0723713a0349 (diff)
downloadmakers-d12026d12b07dcbfd8bd1914cdcd292888cec37f.tar.gz
makers-d12026d12b07dcbfd8bd1914cdcd292888cec37f.zip
prevent circular inference chains
-rw-r--r--src/makefile/mod.rs34
1 files 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<String>,
args: &'a Args,
// TODO borrow warnings from Python version
- fucking_bullshit_recursion_stack: RefCell<Vec<String>>,
}
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<Rc<RefCell<Target>>> {
- 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")?;