Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package utils
import (
"crypto/rand"
"encoding/json"
"errors"
"fmt"
"math/big"
"net/http"
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
68 changes: 0 additions & 68 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
Expand Down Expand Up @@ -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)))
Expand Down