Skip to content

Commit

Permalink
fix(reset): Add cycle detector in reset.go
Browse files Browse the repository at this point in the history
  • Loading branch information
idsulik committed Oct 26, 2024
1 parent 156e22d commit 3bac93c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
20 changes: 18 additions & 2 deletions loader/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ import (
)

type ResetProcessor struct {
target interface{}
paths []tree.Path
target interface{}
paths []tree.Path
visitedNodes map[*yaml.Node]bool
}

// UnmarshalYAML implement yaml.Unmarshaler
func (p *ResetProcessor) UnmarshalYAML(value *yaml.Node) error {
resolved, err := p.resolveReset(value, tree.NewPath())
p.visitedNodes = nil
if err != nil {
return err
}
Expand All @@ -45,6 +47,20 @@ func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.No
if strings.Contains(path.String(), ".<<") {
path = tree.NewPath(strings.Replace(path.String(), ".<<", "", 1))
}

// Check for cycle
if p.visitedNodes == nil {
p.visitedNodes = make(map[*yaml.Node]bool)
}

// Check if the current node has been visited before (cycle detection)
if p.visitedNodes[node] {
return nil, fmt.Errorf("cycle detected at path: %s", path.String())
}

// Mark the current node as visited
p.visitedNodes[node] = true

// If the node is an alias, We need to process the alias field in order to consider the !override and !reset tags
if node.Kind == yaml.AliasNode {
return p.resolveReset(node.Alias, path)
Expand Down
21 changes: 21 additions & 0 deletions loader/reset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,24 @@ networks:
assert.NilError(t, err)
assert.Check(t, p.Networks["test"].External == false)
}

func TestResetCycle(t *testing.T) {
_, err := Load(
types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "(inline)",
Content: []byte(`
x-healthcheck: &healthcheck
egress-service:
<<: *healthcheck
`),
},
},
}, func(options *Options) {
options.SkipNormalization = true
options.SkipConsistencyCheck = true
},
)
assert.Error(t, err, "cycle detected at path: x-healthcheck.egress-service")
}

0 comments on commit 3bac93c

Please sign in to comment.