diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-09-30 10:05:35 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-10-02 09:38:17 +0300 |
| commit | a250fcf252d54c83b808322c8f46de0732fcec13 (patch) | |
| tree | a96cd6d40f5317e5116261ca88c56c347497f003 | |
| parent | 24b3cbfe55d4acae931e444f327064d5eaac812c (diff) | |
| download | niri-a250fcf252d54c83b808322c8f46de0732fcec13.tar.gz niri-a250fcf252d54c83b808322c8f46de0732fcec13.tar.bz2 niri-a250fcf252d54c83b808322c8f46de0732fcec13.zip | |
config: Add a nicer error for recursive includes
We can't check recursive includes across "dir/" followed by "../"
because dir may be a symlink, so "dir/../" may resolve to a different
folder. But this is already good within the same folder.
| -rw-r--r-- | niri-config/src/lib.rs | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 038d7e5a..ac133c62 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -114,6 +114,10 @@ struct Recursion(u8); struct Includes(Vec<PathBuf>); #[derive(Default)] struct IncludeErrors(Vec<knuffel::Error>); +// Used for recursive include detection. +// +// We don't *need* it because we have a recursion limit, but it makes for nicer error messages. +struct IncludeStack(HashSet<PathBuf>); // Rather than listing all fields and deriving knuffel::Decode, we implement // knuffel::DecodeChildren by hand, since we need custom logic for every field anyway: we want to @@ -294,6 +298,16 @@ where }; let base = path.parent().map(Path::to_path_buf).unwrap_or_default(); + // Check for recursive include for a nicer error message. + let mut include_stack = ctx.get::<IncludeStack>().unwrap().0.clone(); + if !include_stack.insert(path.to_path_buf()) { + ctx.emit_error(DecodeError::missing( + node, + "recursive include (file includes itself)", + )); + continue; + } + // Store even if the include fails to read or parse, so it gets watched. includes.borrow_mut().0.push(path.to_path_buf()); @@ -316,6 +330,7 @@ where ctx.set(Recursion(recursion)); ctx.set(includes.clone()); ctx.set(include_errors.clone()); + ctx.set(IncludeStack(include_stack)); ctx.set(config.clone()); }); @@ -397,6 +412,7 @@ impl Config { let config = Rc::new(RefCell::new(Config::default())); let includes = Rc::new(RefCell::new(Includes(Vec::new()))); let include_errors = Rc::new(RefCell::new(IncludeErrors(Vec::new()))); + let include_stack = HashSet::from([path.to_path_buf()]); let part = knuffel::parse_with_context::<ConfigPart, knuffel::span::Span, _>( filename, @@ -407,6 +423,7 @@ impl Config { ctx.set(Recursion(0)); ctx.set(includes.clone()); ctx.set(include_errors.clone()); + ctx.set(IncludeStack(include_stack)); ctx.set(config.clone()); }, ); |
