diff --git a/utils/utils.go b/utils/utils.go index 41df5816..8a7afe87 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -3,7 +3,6 @@ package utils import ( "crypto/rand" "encoding/json" - "errors" "fmt" "math/big" "net/http" @@ -51,8 +50,6 @@ type cachedJSONPath struct { // jsonPathCache stores compiled JSONPath expressions keyed by normalized string. var jsonPathCache sync.Map -var errCircularReference = errors.New("circular reference detected in YAML node graph") - var jsonPathQuery = func(path *jsonpath.JSONPath, node *yaml.Node) []*yaml.Node { return path.Query(node) } @@ -73,61 +70,6 @@ func getJSONPath(rawPath string) (*jsonpath.JSONPath, error) { return path, err } -func hasCircularReference(root *yaml.Node) bool { - if root == nil { - return false - } - - type frame struct { - node *yaml.Node - index int - aliasDone bool - } - - visited := make(map[*yaml.Node]uint8, 64) // 0 = unvisited, 1 = visiting, 2 = done - stack := []frame{{node: root}} - for len(stack) > 0 { - top := &stack[len(stack)-1] - n := top.node - - if visited[n] == 0 { - visited[n] = 1 - } - - if !top.aliasDone { - top.aliasDone = true - if n.Kind == yaml.AliasNode && n.Alias != nil { - if visited[n.Alias] == 1 { - return true - } - if visited[n.Alias] == 0 { - stack = append(stack, frame{node: n.Alias}) - continue - } - } - } - - if top.index < len(n.Content) { - child := n.Content[top.index] - top.index++ - if child == nil { - continue - } - if visited[child] == 1 { - return true - } - if visited[child] == 0 { - stack = append(stack, frame{node: child}) - } - continue - } - - visited[n] = 2 - stack = stack[:len(stack)-1] - } - return false -} - // FindNodes will find a node based on JSONPath, it accepts raw yaml/json as input. func FindNodes(yamlData []byte, jsonPath string) ([]*yaml.Node, error) { var node yaml.Node @@ -205,10 +147,6 @@ func FindNodesWithoutDeserializingWithTimeout(node *yaml.Node, jsonPath string, return nil, err } - if hasCircularReference(node) { - return nil, errCircularReference - } - // this can spin out, to lets gatekeep it. done := make(chan struct{}, 1) var results []*yaml.Node diff --git a/utils/utils_test.go b/utils/utils_test.go index d5581026..06c0003b 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -1542,26 +1542,6 @@ func TestIsNodeNull(t *testing.T) { assert.True(t, IsNodeNull(noNode)) } -func TestFindNodesWithoutDeserializingWithTimeout(t *testing.T) { - // create a and b node that reference each other - a := &yaml.Node{ - Value: "beans", - Tag: "!!map", - Kind: yaml.MappingNode, - } - b := &yaml.Node{ - Tag: "!!map", - Value: "cake", - Kind: yaml.MappingNode, - } - a.Content = []*yaml.Node{b} - b.Content = []*yaml.Node{a} - - nodes, err := FindNodesWithoutDeserializingWithTimeout(a, "$..chicken", 10*time.Millisecond) - assert.Nil(t, nodes) - assert.ErrorIs(t, err, errCircularReference) -} - func TestFindNodesWithoutDeserializingWithTimeout_Timeout(t *testing.T) { root, _ := FindNodes(getPetstore(), "$") block := make(chan struct{}) @@ -1591,54 +1571,6 @@ func TestFindNodesWithoutDeserializingWithTimeout_Success(t *testing.T) { assert.Len(t, nodes, 1) } -func TestHasCircularReference_NoCycle(t *testing.T) { - leaf := &yaml.Node{ - Kind: yaml.ScalarNode, - Value: "leaf", - } - root := &yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{leaf, leaf}, - } - assert.False(t, hasCircularReference(root)) -} - -func TestHasCircularReference_NilRoot(t *testing.T) { - assert.False(t, hasCircularReference(nil)) -} - -func TestHasCircularReference_NilChild(t *testing.T) { - root := &yaml.Node{ - Kind: yaml.SequenceNode, - Content: []*yaml.Node{nil}, - } - assert.False(t, hasCircularReference(root)) -} - -func TestHasCircularReference_AliasNoCycle(t *testing.T) { - target := &yaml.Node{ - Kind: yaml.ScalarNode, - Value: "target", - } - alias := &yaml.Node{ - Kind: yaml.AliasNode, - Alias: target, - } - root := &yaml.Node{ - Kind: yaml.MappingNode, - Content: []*yaml.Node{alias}, - } - assert.False(t, hasCircularReference(root)) -} - -func TestHasCircularReference_AliasCycle(t *testing.T) { - alias := &yaml.Node{ - Kind: yaml.AliasNode, - } - alias.Alias = alias - assert.True(t, hasCircularReference(alias)) -} - func TestGenerateAlphanumericString(t *testing.T) { reg := regexp.MustCompile("^[0-9A-Za-z]{1,4}$") assert.NotNil(t, reg.MatchString(GenerateAlphanumericString(4)))