Skip to content

Commit

Permalink
Fix flatten graph to cover node twice when needed. (#783)
Browse files Browse the repository at this point in the history
  • Loading branch information
asafambar committed Jun 11, 2023
1 parent a3b84a9 commit bc2be24
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 3 deletions.
9 changes: 8 additions & 1 deletion xray/services/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,17 @@ func FlattenGraph(graph []*xrayUtils.GraphNode) ([]*xrayUtils.GraphNode, error)
}

func populateUniqueDependencies(node *xrayUtils.GraphNode, allDependencies map[string]*xrayUtils.GraphNode) {
if _, exist := allDependencies[node.Id]; exist {
if value, exist := allDependencies[node.Id]; exist &&
(len(node.Nodes) == 0 || value.ChildrenExist) {
return
}
allDependencies[node.Id] = &xrayUtils.GraphNode{Id: node.Id}
if len(node.Nodes) > 0 {
// In some cases node can appear twice, with or without children, this because of the depth limit when creating the graph.
// If the node was covered with its children, we mark that, so we won't cover it again.
// If its without children, we want to cover it again when it comes with its children.
allDependencies[node.Id].ChildrenExist = true
}
for _, dependency := range node.Nodes {
populateUniqueDependencies(dependency, allDependencies)
}
Expand Down
8 changes: 6 additions & 2 deletions xray/services/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,25 @@ func TestFlattenGraph(t *testing.T) {
nodeD := &xrayUtils.GraphNode{Id: "D"}
nodeE := &xrayUtils.GraphNode{Id: "E"}
nodeF := &xrayUtils.GraphNode{Id: "F"}
nodeG := &xrayUtils.GraphNode{Id: "G"}
nodeGNoChildren := &xrayUtils.GraphNode{Id: "G"}
nodeH := &xrayUtils.GraphNode{Id: "H"}

// Set dependencies
nodeA.Nodes = []*xrayUtils.GraphNode{nodeB, nodeC}
nodeB.Nodes = []*xrayUtils.GraphNode{nodeC, nodeD}
nodeC.Nodes = []*xrayUtils.GraphNode{nodeD}
nodeD.Nodes = []*xrayUtils.GraphNode{nodeE, nodeF}
nodeF.Nodes = []*xrayUtils.GraphNode{nodeA, nodeB, nodeC}
nodeF.Nodes = []*xrayUtils.GraphNode{nodeGNoChildren, nodeA, nodeB, nodeC, nodeG}
nodeG.Nodes = []*xrayUtils.GraphNode{nodeH}

// Create graph
graph := []*xrayUtils.GraphNode{nodeA, nodeB, nodeC}
flatGraph, err := FlattenGraph(graph)
assert.NoError(t, err)

// Check that the graph has been flattened correctly
assert.Equal(t, len(flatGraph[0].Nodes), 6)
assert.Equal(t, len(flatGraph[0].Nodes), 8)
set := datastructures.MakeSet[string]()
for _, node := range flatGraph[0].Nodes {
assert.Len(t, node.Nodes, 0)
Expand Down
3 changes: 3 additions & 0 deletions xray/services/utils/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type GraphNode struct {
OtherComponentIds []OtherComponentIds `json:"other_component_ids,omitempty"`
// Node parent (for internal use)
Parent *GraphNode `json:"-"`
// Node Can appear in some cases without children. When adding node to flatten graph,
// we want to process node again if it was processed without children.
ChildrenExist bool `json:"-"`
}

type OtherComponentIds struct {
Expand Down

0 comments on commit bc2be24

Please sign in to comment.