From d80ec4aaa7ab393387554c58a2ea907fa9edd6ff Mon Sep 17 00:00:00 2001 From: James Shubin Date: Sat, 15 Feb 2025 06:58:15 -0500 Subject: [PATCH] engine: resources: Detect simple self-referential frags It would be a likely mistake to create a self-referential frag, and mgmt would spin forever updating the file... We probably don't want this, so let's just catch this case in Validate. Of course you could get around this with multiple files, and a fancier search could statically check the graph, but the goal isn't to prevent any bad code, since that's not likely to be possible. --- engine/resources/file.go | 7 +++++++ lang/interpret_test/TestAstFunc3/frag1.txtar | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 lang/interpret_test/TestAstFunc3/frag1.txtar diff --git a/engine/resources/file.go b/engine/resources/file.go index 95c8f783..02ec9ab6 100644 --- a/engine/resources/file.go +++ b/engine/resources/file.go @@ -327,6 +327,13 @@ func (obj *FileRes) Validate() error { if !strings.HasPrefix(frag, "/") { return fmt.Errorf("the frag (`%s`) isn't an absolute path", frag) } + // If the file is inside one of our fragment dirs, then this + // would make an infinite loop mess. We can't prevent this + // happening in other ways with multiple dirs doing this for + // each other, but we can at least catch the common case. + if util.HasPathPrefix(obj.getPath(), frag) { + return fmt.Errorf("inside a frag (`%s`)", frag) + } } if obj.Purge && (isContent || isFrag) { diff --git a/lang/interpret_test/TestAstFunc3/frag1.txtar b/lang/interpret_test/TestAstFunc3/frag1.txtar new file mode 100644 index 00000000..8d1ff4af --- /dev/null +++ b/lang/interpret_test/TestAstFunc3/frag1.txtar @@ -0,0 +1,16 @@ +-- main.mcl -- +file "/tmp/frags/" { + state => "exists", +} +file "/tmp/frags/f1" { + state => "exists", + content => "f1 contents\n", +} +file "/tmp/frags/all" { + state => "exists", + fragments => [ + "/tmp/frags/", + ], +} +-- OUTPUT -- +# err: errValidate: file[/tmp/frags/all] did not Validate: inside a frag (`/tmp/frags/`)