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/`)