Skip to content

Commit

Permalink
Adding new Overlay and Concept nodes to the graph. (#1897)
Browse files Browse the repository at this point in the history
  • Loading branch information
maximiliankaul authored Dec 17, 2024
1 parent 1f16d58 commit 698937e
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 18 deletions.
27 changes: 18 additions & 9 deletions cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ import de.fraunhofer.aisec.cpg.TranslationContext
import de.fraunhofer.aisec.cpg.TypeManager
import de.fraunhofer.aisec.cpg.frontends.Handler
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.graph.declarations.*
import de.fraunhofer.aisec.cpg.graph.edges.*
import de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.edges.ast.astEdgesOf
import de.fraunhofer.aisec.cpg.graph.edges.flows.ControlDependences
import de.fraunhofer.aisec.cpg.graph.edges.flows.Dataflows
import de.fraunhofer.aisec.cpg.graph.edges.flows.EvaluationOrders
import de.fraunhofer.aisec.cpg.graph.edges.flows.FullDataflowGranularity
import de.fraunhofer.aisec.cpg.graph.edges.flows.ProgramDependences
import de.fraunhofer.aisec.cpg.graph.scopes.*
import de.fraunhofer.aisec.cpg.graph.edges.flows.*
import de.fraunhofer.aisec.cpg.graph.edges.overlay.*
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import de.fraunhofer.aisec.cpg.graph.scopes.GlobalScope
import de.fraunhofer.aisec.cpg.graph.scopes.RecordScope
import de.fraunhofer.aisec.cpg.graph.scopes.Scope
import de.fraunhofer.aisec.cpg.helpers.SubgraphWalker
import de.fraunhofer.aisec.cpg.helpers.neo4j.LocationConverter
import de.fraunhofer.aisec.cpg.helpers.neo4j.NameConverter
Expand All @@ -52,7 +53,10 @@ import java.util.*
import kotlin.uuid.Uuid
import org.apache.commons.lang3.builder.ToStringBuilder
import org.apache.commons.lang3.builder.ToStringStyle
import org.neo4j.ogm.annotation.*
import org.neo4j.ogm.annotation.GeneratedValue
import org.neo4j.ogm.annotation.Id
import org.neo4j.ogm.annotation.Relationship
import org.neo4j.ogm.annotation.Transient
import org.neo4j.ogm.annotation.typeconversion.Convert
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -274,6 +278,11 @@ abstract class Node :
*/
val additionalProblems: MutableSet<ProblemNode> = mutableSetOf()

@Relationship(value = "OVERLAY", direction = Relationship.Direction.OUTGOING)
val overlayEdges: Overlays =
Overlays(this, mirrorProperty = OverlayNode::underlyingNodeEdge, outgoing = true)
var overlays by unwrapping(Node::overlayEdges)

/**
* If a node should be removed from the graph, just removing it from the AST is not enough (see
* issue #60). It will most probably be referenced somewhere via DFG or EOG edges. Thus, if it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.graph

import de.fraunhofer.aisec.cpg.graph.edges.overlay.OverlaySingleEdge
import de.fraunhofer.aisec.cpg.graph.edges.unwrapping
import org.neo4j.ogm.annotation.Relationship

/**
* Represents an extra node added to the CPG. These nodes can live next to the regular nodes,
* typically having shared edges to extend the original graph.
*/
abstract class OverlayNode() : Node() {
@Relationship(value = "OVERLAY", direction = Relationship.Direction.INCOMING)
/** All [OverlayNode]s nodes are connected to an original cpg [Node] by this. */
val underlyingNodeEdge: OverlaySingleEdge =
OverlaySingleEdge(
this,
of = null,
mirrorProperty = Node::overlayEdges,
outgoing = false,
)
var underlyingNode by unwrapping(OverlayNode::underlyingNodeEdge)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.graph.concepts

import de.fraunhofer.aisec.cpg.graph.OverlayNode

/**
* Represents a new concept added to the CPG. This is intended for modelling "concepts" like
* logging, files, databases. The relevant operations on this concept are modeled as [Operation]s
* and stored in [ops].
*/
abstract class Concept<T : Operation>() : OverlayNode() {
/** All [Operation]s belonging to this concept. */
val ops: MutableSet<T> = mutableSetOf()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2024, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.graph.concepts

import de.fraunhofer.aisec.cpg.graph.OverlayNode

/**
* Represents an operation executed on/with a [Concept] (stored in [concept]). This is typically a
* `write` on a file or log object or an `execute` on a database.
*/
abstract class Operation(
/** The [Concept] this operation belongs to. */
val concept: Concept<*>
) : OverlayNode()
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ import org.neo4j.ogm.annotation.Transient
*
* Therefore, we need to wrap the edge in a list with a single element.
*/
class EdgeSingletonList<NodeType : Node, NullableNodeType : NodeType?, EdgeType : Edge<NodeType>>(
open class EdgeSingletonList<
NodeType : Node,
NullableNodeType : NodeType?,
EdgeType : Edge<NodeType>
>(
override var thisRef: Node,
override var init: (Node, NodeType) -> EdgeType,
var onChanged: ((old: EdgeType?, new: EdgeType?) -> Unit)? = null,
Expand Down Expand Up @@ -71,7 +75,15 @@ class EdgeSingletonList<NodeType : Node, NullableNodeType : NodeType?, EdgeType
}

override fun add(element: EdgeType): Boolean {
throw UnsupportedOperationException()
if (this.element == null) {
this.element = element
onChanged?.invoke(null, this.element)
return true
} else {
throw UnsupportedOperationException(
"We cannot 'add' to a singleton edge list, that is already populated"
)
}
}

override fun addAll(elements: Collection<EdgeType>): Boolean {
Expand Down Expand Up @@ -151,6 +163,13 @@ class EdgeSingletonList<NodeType : Node, NullableNodeType : NodeType?, EdgeType
@Suppress("UNCHECKED_CAST") init(node, thisRef as NodeType)
}
onChanged?.invoke(old, this.element)

val element = this.element
if (element != null) {
handleOnAdd(element)
} else if (old != null) {
handleOnRemove(old)
}
}

fun <ThisType : Node> delegate(): UnwrapDelegate<ThisType> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2024, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.graph.edges.overlay

import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.edges.Edge
import de.fraunhofer.aisec.cpg.graph.edges.collections.EdgeSet
import de.fraunhofer.aisec.cpg.graph.edges.collections.EdgeSingletonList
import de.fraunhofer.aisec.cpg.graph.edges.collections.MirroredEdgeCollection
import kotlin.reflect.KProperty

/**
* Represents an edge in a graph specifically used for overlay purposes.
*
* @param start The starting node of the edge.
* @param end The ending node of the edge.
* @constructor Constructs an [OverlayEdge] with a specified [start] and [end] node.
* @property labels A predefined set of labels associated with the OverlayEdge. By default, it is
* initialized with the label "OVERLAY".
*/
class OverlayEdge(start: Node, end: Node) : Edge<Node>(start, end) {
override var labels: Set<String> = setOf("OVERLAY")
}

/**
* Represents a single edge in an overlay graph structure, linking nodes with specific properties.
*
* @param thisRef The current node that the edge originates from or is associated with.
* @param of The optional target node of the edge.
* @param mirrorProperty The property representing a mutable collection of mirrored overlay edges.
* @param outgoing A flag indicating whether the edge is outgoing (default is true).
* @constructor Initializes the [OverlaySingleEdge] instance with the provided parameters.
*/
class OverlaySingleEdge(
thisRef: Node,
of: Node?,
override var mirrorProperty: KProperty<MutableCollection<OverlayEdge>>,
outgoing: Boolean = true,
) :
EdgeSingletonList<Node, Node?, OverlayEdge>(
thisRef = thisRef,
init = ::OverlayEdge,
outgoing = outgoing,
of = of,
),
MirroredEdgeCollection<Node, OverlayEdge>

/**
* Represents a collection of overlay edges connected to a specific node. This class is used to
* manage and define relationships between nodes through overlay edges, providing both outgoing and
* incoming edge handling capabilities.
*
* @param thisRef The reference node that the overlays are associated with.
* @param mirrorProperty A reference to a property that mirrors the collection of overlay edges.
* @param outgoing A boolean indicating whether the edges managed by this collection are outgoing.
* @constructor Initializes the [Overlays] object with a reference node, a property for edge
* mirroring, and a direction to specify outgoing or incoming edges.
*/
class Overlays(
thisRef: Node,
override var mirrorProperty: KProperty<MutableCollection<OverlayEdge>>,
outgoing: Boolean,
) :
EdgeSet<Node, OverlayEdge>(thisRef = thisRef, init = ::OverlayEdge, outgoing = outgoing),
MirroredEdgeCollection<Node, OverlayEdge>
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class TestCommon {
"DFG",
"EOG",
"LANGUAGE",
"OVERLAY",
"OVERRIDES",
"PARAMETERS",
"PDG",
Expand All @@ -91,6 +92,7 @@ class TestCommon {
"DFG",
"EOG",
"LANGUAGE",
"OVERLAY",
"PDG",
"SCOPE",
),
Expand Down
Loading

0 comments on commit 698937e

Please sign in to comment.