Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed rather intricate bug in property edge list #1292

Merged
merged 1 commit into from
Aug 25, 2023
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
31 changes: 5 additions & 26 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 @@ -35,12 +35,8 @@ 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.declarations.TypedefDeclaration
import de.fraunhofer.aisec.cpg.graph.edge.DependenceType
import de.fraunhofer.aisec.cpg.graph.edge.*
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
Expand All @@ -51,7 +47,6 @@ import de.fraunhofer.aisec.cpg.passes.*
import de.fraunhofer.aisec.cpg.processing.IVisitable
import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
import java.util.*
import kotlin.collections.ArrayList
import org.apache.commons.lang3.builder.ToStringBuilder
import org.apache.commons.lang3.builder.ToStringStyle
import org.neo4j.ogm.annotation.*
Expand Down Expand Up @@ -164,33 +159,17 @@ open class Node : IVisitable<Node>, Persistable, LanguageProvider, ScopeProvider

/** Virtual property for accessing [prevEOGEdges] without property edges. */
@PopulatedByPass(EvaluationOrderGraphPass::class)
var prevEOG: List<Node>
get() = unwrap(prevEOGEdges, false)
set(value) {
val propertyEdgesEOG: MutableList<PropertyEdge<Node>> = ArrayList()

for ((idx, prev) in value.withIndex()) {
val propertyEdge = PropertyEdge(prev, this)
propertyEdge.addProperty(Properties.INDEX, idx)
propertyEdgesEOG.add(propertyEdge)
}

this.prevEOGEdges = propertyEdgesEOG
}
var prevEOG: List<Node> by PropertyEdgeDelegate(Node::prevEOGEdges, false)

/** Virtual property for accessing [nextEOGEdges] without property edges. */
@PopulatedByPass(EvaluationOrderGraphPass::class)
var nextEOG: List<Node>
get() = unwrap(nextEOGEdges)
set(value) {
this.nextEOGEdges = PropertyEdge.transformIntoOutgoingPropertyEdgeList(value, this)
}
var nextEOG: List<Node> by PropertyEdgeDelegate(Node::nextEOGEdges)

/** Incoming data flow edges */
@Relationship(value = "DFG", direction = Relationship.Direction.INCOMING)
@PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class)
var prevDFGEdges: MutableList<PropertyEdge<Node>> = mutableListOf()
internal set
protected set

/** Virtual property for accessing [prevDFGEdges] without property edges. */
@PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class)
Expand All @@ -200,7 +179,7 @@ open class Node : IVisitable<Node>, Persistable, LanguageProvider, ScopeProvider
@PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class)
@Relationship(value = "DFG", direction = Relationship.Direction.OUTGOING)
var nextDFGEdges: MutableList<PropertyEdge<Node>> = mutableListOf()
internal set
protected set

/** Virtual property for accessing [nextDFGEdges] without property edges. */
@PopulatedByPass(DFGPass::class, ControlFlowSensitiveDFGPass::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ package de.fraunhofer.aisec.cpg.graph

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.transformIntoOutgoingPropertyEdgeList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.wrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate
import de.fraunhofer.aisec.cpg.graph.statements.Statement

/**
Expand All @@ -44,13 +45,17 @@ interface StatementHolder : Holder<Statement> {
/** List of statements as property edges. */
var statementEdges: MutableList<PropertyEdge<Statement>>

/** Virtual property to access [statementEdges] without property edges. */
/**
* Virtual property to access [statementEdges] without property edges.
*
* Note: We cannot use [PropertyEdgeDelegate] because delegates are not allowed in interfaces.
*/
var statements: List<Statement>
get() {
return unwrap(statementEdges)
}
set(value) {
statementEdges = transformIntoOutgoingPropertyEdgeList(value, this as Node)
statementEdges = wrap(value, this as Node)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ package de.fraunhofer.aisec.cpg.graph.declarations

import de.fraunhofer.aisec.cpg.graph.AST
import de.fraunhofer.aisec.cpg.graph.DeclarationHolder
import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.StatementHolder
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.propertyEqualsList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate
import de.fraunhofer.aisec.cpg.graph.statements.Statement
import de.fraunhofer.aisec.cpg.passes.PassTarget
import java.util.Objects
Expand Down Expand Up @@ -63,11 +63,8 @@ class TranslationUnitDeclaration : Declaration(), DeclarationHolder, StatementHo
override val declarations: List<Declaration>
get() = unwrap(declarationEdges)

override var statements: List<Statement>
get() = unwrap(statementEdges)
set(value) {
statementEdges = PropertyEdge.transformIntoOutgoingPropertyEdgeList(value, this as Node)
}
override var statements: List<Statement> by
PropertyEdgeDelegate(TranslationUnitDeclaration::statementEdges)

val includes: List<IncludeDeclaration>
get() = unwrap(includeEdges)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import java.util.*
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
import kotlin.reflect.jvm.isAccessible
import org.neo4j.ogm.annotation.*
import org.neo4j.ogm.annotation.typeconversion.Convert
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -162,15 +163,21 @@ open class PropertyEdge<T : Node> : Persistable {
* @return List of PropertyEdges with the targets of the nodes and index property.
*/
@JvmStatic
fun <T : Node> transformIntoOutgoingPropertyEdgeList(
fun <T : Node> wrap(
nodes: List<T>,
commonRelationshipNode: Node
commonRelationshipNode: Node,
outgoing: Boolean = true
): MutableList<PropertyEdge<T>> {
val propertyEdges: MutableList<PropertyEdge<T>> = ArrayList()
for (n in nodes) {
val propertyEdge = PropertyEdge(commonRelationshipNode, n)
val propertyEdge =
if (outgoing) {
PropertyEdge(commonRelationshipNode, n)
} else {
PropertyEdge(n, commonRelationshipNode)
}
propertyEdge.addProperty(Properties.INDEX, propertyEdges.size)
propertyEdges.add(propertyEdge)
propertyEdges.add(propertyEdge as PropertyEdge<T>)
}
return propertyEdges
}
Expand Down Expand Up @@ -366,10 +373,9 @@ class PropertyEdgeDelegate<T : Node, S : Node>(

operator fun setValue(thisRef: S, property: KProperty<*>, value: List<T>) {
if (edge is KMutableProperty1) {
edge.setter.call(
thisRef,
PropertyEdge.transformIntoOutgoingPropertyEdgeList(value, thisRef as Node)
)
val callable = edge.setter
callable.isAccessible = true
edge.setter.call(thisRef, PropertyEdge.wrap(value, thisRef as Node, outgoing))
}
}
}
Expand All @@ -386,10 +392,9 @@ class PropertyEdgeSetDelegate<T : Node, S : Node>(

operator fun setValue(thisRef: S, property: KProperty<*>, value: MutableSet<T>) {
if (edge is KMutableProperty1) {
edge.setter.call(
thisRef,
PropertyEdge.transformIntoOutgoingPropertyEdgeList(value.toList(), thisRef as Node)
)
val callable = edge.setter
callable.isAccessible = true
edge.setter.call(thisRef, PropertyEdge.wrap(value.toList(), thisRef as Node, outgoing))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import de.fraunhofer.aisec.cpg.graph.declarations.TemplateDeclaration.TemplateIn
import de.fraunhofer.aisec.cpg.graph.edge.*
import de.fraunhofer.aisec.cpg.graph.edge.Properties
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.propertyEqualsList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.transformIntoOutgoingPropertyEdgeList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.wrap
import de.fraunhofer.aisec.cpg.graph.types.*
import de.fraunhofer.aisec.cpg.graph.types.HasSecondaryTypeEdge
import de.fraunhofer.aisec.cpg.passes.CallResolver
Expand Down Expand Up @@ -74,7 +74,7 @@ open class CallExpression :
}
set(value) {
unwrap(invokeEdges).forEach { it.unregisterTypeObserver(this) }
invokeEdges = transformIntoOutgoingPropertyEdgeList(value, this)
invokeEdges = wrap(value, this)
value.forEach { it.registerTypeObserver(this) }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ package de.fraunhofer.aisec.cpg.graph.types
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.propertyEqualsList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.transformIntoOutgoingPropertyEdgeList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.unwrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.wrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate
import de.fraunhofer.aisec.cpg.graph.types.PointerType.PointerOrigin
import java.util.*
Expand Down Expand Up @@ -59,7 +59,7 @@ class FunctionPointerType : Type {
language: Language<*>? = null,
returnType: Type = UnknownType.getUnknownType(language)
) : super(EMPTY_NAME, language) {
parametersPropertyEdge = transformIntoOutgoingPropertyEdgeList(parameters, this)
parametersPropertyEdge = wrap(parameters, this)
this.returnType = returnType
}

Expand All @@ -69,7 +69,7 @@ class FunctionPointerType : Type {
language: Language<*>? = null,
returnType: Type = UnknownType.getUnknownType(language)
) : super(type) {
parametersPropertyEdge = transformIntoOutgoingPropertyEdgeList(parameters, this)
parametersPropertyEdge = wrap(parameters, this)
this.returnType = returnType
this.language = language
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
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.propertyEqualsList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.transformIntoOutgoingPropertyEdgeList
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge.Companion.wrap
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdgeDelegate
import de.fraunhofer.aisec.cpg.graph.types.PointerType.PointerOrigin
import de.fraunhofer.aisec.cpg.graph.unknownType
Expand Down Expand Up @@ -61,7 +61,7 @@ open class ObjectType : Type, HasSecondaryTypeEdge {
primitive: Boolean,
language: Language<*>?
) : super(typeName, language) {
this.genericsPropertyEdges = transformIntoOutgoingPropertyEdgeList(generics, this)
this.genericsPropertyEdges = wrap(generics, this)
isPrimitive = primitive
this.language = language
}
Expand All @@ -73,7 +73,7 @@ open class ObjectType : Type, HasSecondaryTypeEdge {
language: Language<*>?
) : super(type) {
this.language = language
this.genericsPropertyEdges = transformIntoOutgoingPropertyEdgeList(generics, this)
this.genericsPropertyEdges = wrap(generics, this)
isPrimitive = primitive
}

Expand Down
Loading