From 1c8b581c26301b6d1d3914d56b0b6bbd690416af Mon Sep 17 00:00:00 2001 From: Selina Lin Date: Fri, 30 Jun 2023 17:42:57 +0200 Subject: [PATCH 1/5] change the DFG to use PropertyEdges --- .../de/fraunhofer/aisec/cpg/graph/Node.kt | 66 +++++++++++++------ .../aisec/cpg/graph/edge/PropertyEdge.kt | 25 ++++++- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt index 7089f436fd..7d180e24ec 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt @@ -39,6 +39,7 @@ import de.fraunhofer.aisec.cpg.graph.edge.Properties import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate +import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeSetDelegate import de.fraunhofer.aisec.cpg.graph.scopes.GlobalScope import de.fraunhofer.aisec.cpg.graph.scopes.RecordScope import de.fraunhofer.aisec.cpg.graph.scopes.Scope @@ -187,13 +188,25 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider this.nextEOGEdges = PropertyEdge.transformIntoOutgoingPropertyEdgeList(value, this) } + /** Incoming data flow edges */ @Relationship(value = "DFG", direction = Relationship.Direction.INCOMING) @PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class) - var prevDFG: MutableSet = HashSet() + var prevDFGEdges: MutableList> = mutableListOf() + internal set + /** Virtual property for accessing [prevDFGEdges] without property edges. */ @PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class) - @Relationship(value = "DFG") - var nextDFG: MutableSet = HashSet() + var prevDFG: MutableSet by PropertyEdgeSetDelegate(Node::prevDFGEdges, false) + + /** Outgoing data flow edges */ + @PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class) + @Relationship(value = "DFG", direction = Relationship.Direction.OUTGOING) + var nextDFGEdges: MutableList> = mutableListOf() + internal set + + /** Virtual property for accessing [nextDFGEdges] without property edges. */ + @PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class) + var nextDFG: MutableSet by PropertyEdgeSetDelegate(Node::nextDFGEdges, true) var typedefs: MutableSet = HashSet() @@ -245,20 +258,27 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider } fun addNextDFG(next: Node) { - nextDFG.add(next) - next.prevDFG.add(this) + val edge = PropertyEdge(this, next) + nextDFGEdges.add(edge) + next.prevDFGEdges.add(edge) } fun removeNextDFG(next: Node?) { if (next != null) { - nextDFG.remove(next) - next.prevDFG.remove(this) + val thisRemove = + PropertyEdge.findPropertyEdgesByPredicate(nextDFGEdges) { it.end === next } + nextDFGEdges.removeAll(thisRemove) + + val nextRemove = + PropertyEdge.findPropertyEdgesByPredicate(next.prevDFGEdges) { it.start == this } + next.prevDFGEdges.removeAll(nextRemove) } } fun addPrevDFG(prev: Node) { - prevDFG.add(prev) - prev.nextDFG.add(this) + val edge = PropertyEdge(prev, this) + prevDFGEdges.add(edge) + prev.nextDFGEdges.add(edge) } fun addPrevCDG(prev: Node) { @@ -268,14 +288,18 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider } fun addAllPrevDFG(prev: Collection) { - prevDFG.addAll(prev) - prev.forEach { it.nextDFG.add(this) } + prev.forEach { addPrevDFG(it) } } fun removePrevDFG(prev: Node?) { if (prev != null) { - prevDFG.remove(prev) - prev.nextDFG.remove(this) + val thisRemove = + PropertyEdge.findPropertyEdgesByPredicate(prevDFGEdges) { it.start === prev } + prevDFGEdges.removeAll(thisRemove) + + val prevRemove = + PropertyEdge.findPropertyEdgesByPredicate(prev.nextDFGEdges) { it.end === this } + prev.nextDFGEdges.removeAll(prevRemove) } } @@ -309,15 +333,19 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider * further children that have no alternative connection paths to the rest of the graph. */ fun disconnectFromGraph() { - for (n in nextDFG) { - n.prevDFG.remove(this) + for (n in nextDFGEdges) { + val remove = + PropertyEdge.findPropertyEdgesByPredicate(n.end.prevDFGEdges) { it.start == this } + n.end.prevDFGEdges.removeAll(remove) } - nextDFG.clear() + nextDFGEdges.clear() - for (n in prevDFG) { - n.nextDFG.remove(this) + for (n in prevDFGEdges) { + val remove = + PropertyEdge.findPropertyEdgesByPredicate(n.start.nextDFGEdges) { it.end == this } + n.start.nextDFGEdges.removeAll(remove) } - prevDFG.clear() + prevDFGEdges.clear() for (n in nextEOGEdges) { val remove = diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt index 1b5e59d4f2..5dd863015b 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt @@ -168,7 +168,7 @@ open class PropertyEdge : Persistable { ): MutableList> { val propertyEdges: MutableList> = ArrayList() for (n in nodes) { - var propertyEdge = PropertyEdge(commonRelationshipNode, n) + val propertyEdge = PropertyEdge(commonRelationshipNode, n) propertyEdge.addProperty(Properties.INDEX, propertyEdges.size) propertyEdges.add(propertyEdge) } @@ -373,3 +373,26 @@ class PropertyEdgeDelegate( } } } + + +/** + * Similar to a [PropertyEdgeDelegate], but with a [Set] instead of [List]. + */ +@Transient +class PropertyEdgeSetDelegate( + val edge: KProperty1>>, + val outgoing: Boolean = true +) { + operator fun getValue(thisRef: S, property: KProperty<*>): MutableSet { + return PropertyEdge.unwrap(edge.get(thisRef), outgoing).toMutableSet() + } + + operator fun setValue(thisRef: S, property: KProperty<*>, value: MutableSet) { + if (edge is KMutableProperty1) { + edge.setter.call( + thisRef, + PropertyEdge.transformIntoOutgoingPropertyEdgeList(value.toList(), thisRef as Node) + ) + } + } +} From 74aacd12098ca77558a616b5b642df576170a9f5 Mon Sep 17 00:00:00 2001 From: Selina Lin Date: Fri, 7 Jul 2023 18:54:32 +0200 Subject: [PATCH 2/5] remove calls where the same DFG edge would be a second time --- .../de/fraunhofer/aisec/cpg/passes/CXXCallResolverHelper.kt | 5 +---- .../de/fraunhofer/aisec/cpg/passes/inference/Inference.kt | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/CXXCallResolverHelper.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/CXXCallResolverHelper.kt index 24ba098441..1030524b39 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/CXXCallResolverHelper.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/CXXCallResolverHelper.kt @@ -378,10 +378,7 @@ fun applyTemplateInstantiation( // Template. for ((declaration) in initializationSignature) { if (declaration is ParamVariableDeclaration) { - initializationSignature[declaration]?.let { - declaration.addPrevDFG(it) - it.addNextDFG(declaration) // TODO: This should be unnecessary - } + initializationSignature[declaration]?.let { declaration.addPrevDFG(it) } } } diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/inference/Inference.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/inference/Inference.kt index 76bcd8c09a..6d1af8f6f1 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/inference/Inference.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/inference/Inference.kt @@ -293,8 +293,6 @@ class Inference(val start: Node, override val ctx: TranslationContext) : node .startInference(ctx) .inferNonTypeTemplateParameter(inferredNonTypeIdentifier) - - paramVariableDeclaration.addPrevDFG(node) node.addNextDFG(paramVariableDeclaration) nonTypeCounter++ inferred.addParameter(paramVariableDeclaration) From 0d606d20d5649d1dc8d33cba1810074f00d7e8dc Mon Sep 17 00:00:00 2001 From: Selina Lin Date: Fri, 7 Jul 2023 19:11:43 +0200 Subject: [PATCH 3/5] add properties parameter to addNextDFG and addPrevDFG function to be able to specify properties for the edges --- .../kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt index 7d180e24ec..6b2320609d 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt @@ -257,8 +257,8 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider nextEOGEdges.clear() } - fun addNextDFG(next: Node) { - val edge = PropertyEdge(this, next) + fun addNextDFG(next: Node, properties: MutableMap = EnumMap(Properties::class.java)) { + val edge = PropertyEdge(this, next, properties) nextDFGEdges.add(edge) next.prevDFGEdges.add(edge) } @@ -275,8 +275,8 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider } } - fun addPrevDFG(prev: Node) { - val edge = PropertyEdge(prev, this) + fun addPrevDFG(prev: Node, properties: MutableMap = EnumMap(Properties::class.java)) { + val edge = PropertyEdge(prev, this, properties) prevDFGEdges.add(edge) prev.nextDFGEdges.add(edge) } @@ -287,8 +287,8 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider prev.nextCDGEdges.add(edge) } - fun addAllPrevDFG(prev: Collection) { - prev.forEach { addPrevDFG(it) } + fun addAllPrevDFG(prev: Collection, properties: MutableMap = EnumMap(Properties::class.java)) { + prev.forEach { addPrevDFG(it, properties.toMutableMap()) } } fun removePrevDFG(prev: Node?) { From 621a9c22abfee18429d3aee6d9419f9cb036160c Mon Sep 17 00:00:00 2001 From: Selina Lin Date: Fri, 7 Jul 2023 19:25:02 +0200 Subject: [PATCH 4/5] fix spotless issues --- .../kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt index 6b2320609d..0e3b01f1b8 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/Node.kt @@ -257,7 +257,10 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider nextEOGEdges.clear() } - fun addNextDFG(next: Node, properties: MutableMap = EnumMap(Properties::class.java)) { + fun addNextDFG( + next: Node, + properties: MutableMap = EnumMap(Properties::class.java) + ) { val edge = PropertyEdge(this, next, properties) nextDFGEdges.add(edge) next.prevDFGEdges.add(edge) @@ -275,7 +278,10 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider } } - fun addPrevDFG(prev: Node, properties: MutableMap = EnumMap(Properties::class.java)) { + fun addPrevDFG( + prev: Node, + properties: MutableMap = EnumMap(Properties::class.java) + ) { val edge = PropertyEdge(prev, this, properties) prevDFGEdges.add(edge) prev.nextDFGEdges.add(edge) @@ -287,7 +293,10 @@ open class Node : IVisitable, Persistable, LanguageProvider, ScopeProvider prev.nextCDGEdges.add(edge) } - fun addAllPrevDFG(prev: Collection, properties: MutableMap = EnumMap(Properties::class.java)) { + fun addAllPrevDFG( + prev: Collection, + properties: MutableMap = EnumMap(Properties::class.java) + ) { prev.forEach { addPrevDFG(it, properties.toMutableMap()) } } From c7d5ed8c127e24c0528accae9ef00030a5f22059 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Thu, 27 Jul 2023 16:50:12 +0200 Subject: [PATCH 5/5] Fix after merge --- .../de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt index 5dd863015b..8e74020131 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/edge/PropertyEdge.kt @@ -374,10 +374,7 @@ class PropertyEdgeDelegate( } } - -/** - * Similar to a [PropertyEdgeDelegate], but with a [Set] instead of [List]. - */ +/** Similar to a [PropertyEdgeDelegate], but with a [Set] instead of [List]. */ @Transient class PropertyEdgeSetDelegate( val edge: KProperty1>>,