Skip to content

Commit b9d3b1d

Browse files
idsulikglours
authored andcommitted
fix(reset): Add cycle detection fix
Signed-off-by: Suleiman Dibirov <[email protected]>
1 parent 0e87616 commit b9d3b1d

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

loader/reset.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,12 @@ func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.No
4949
path = tree.NewPath(strings.Replace(pathStr, ".<<", "", 1))
5050
}
5151

52-
// Check for cycle
53-
if p.visitedNodes == nil {
54-
p.visitedNodes = make(map[*yaml.Node]string)
55-
}
56-
57-
// Check for cycle by seeing if the node has already been visited at this path
58-
if previousPath, found := p.visitedNodes[node]; found {
59-
// If the current node has been visited, we have a cycle if the previous path is a prefix
60-
if strings.HasPrefix(pathStr, previousPath) {
61-
return nil, fmt.Errorf("cycle detected at path: %s", pathStr)
62-
}
63-
}
64-
65-
// Mark the current node as visited
66-
p.visitedNodes[node] = pathStr + "."
67-
6852
// If the node is an alias, We need to process the alias field in order to consider the !override and !reset tags
6953
if node.Kind == yaml.AliasNode {
54+
if err := p.checkForCycle(node.Alias, path); err != nil {
55+
return nil, err
56+
}
57+
7058
return p.resolveReset(node.Alias, path)
7159
}
7260

@@ -154,3 +142,22 @@ func (p *ResetProcessor) applyNullOverrides(target any, path tree.Path) error {
154142
}
155143
return nil
156144
}
145+
146+
func (p *ResetProcessor) checkForCycle(node *yaml.Node, path tree.Path) error {
147+
if p.visitedNodes == nil {
148+
p.visitedNodes = make(map[*yaml.Node]string)
149+
}
150+
151+
// Check for cycle by seeing if the node has already been visited at this path
152+
if previousPath, found := p.visitedNodes[node]; found {
153+
// If the current node has been visited, we have a cycle if the previous path is a prefix
154+
if strings.HasPrefix(path.String(), strings.TrimRight(previousPath, "<<")) {
155+
return fmt.Errorf("cycle detected at path: %s", previousPath)
156+
}
157+
}
158+
159+
// Mark the current node as visited
160+
p.visitedNodes[node] = path.String()
161+
162+
return nil
163+
}

loader/reset_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,26 @@ services:
109109
a2: &a
110110
image: alpine
111111
a: *a
112+
`,
113+
expectError: false,
114+
errorMsg: "",
115+
},
116+
{
117+
name: "no cycle 2",
118+
config: `
119+
name: blah
120+
x-templates:
121+
x-gluetun: &gluetun
122+
environment: &gluetun_env
123+
a: b
124+
x-gluetun-pia: &gluetun_pia
125+
<<: *gluetun
126+
x-gluetun-env-pia: &gluetun_env_pia
127+
<<: *gluetun_env
128+
vp0:
129+
<<: *gluetun_pia
130+
environment:
131+
<<: *gluetun_env_pia
112132
`,
113133
expectError: false,
114134
errorMsg: "",

0 commit comments

Comments
 (0)