Skip to content

Commit

Permalink
Fix Type resolution for array subscriptions that use a mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
konradweiss committed Apr 24, 2024
1 parent 94ef0d9 commit aa7692b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class ExpressionHandler(lang: SolidityLanguageFrontend) : Handler<Expression, Pa
val arraySub = newArraySubscriptionExpression(frontend.getCodeFromRawNode(ctx), ctx)
this.handle(expressions[0])?.let { arraySub.arrayExpression = it }
this.handle(expressions[1])?.let { arraySub.subscriptExpression = it }

return arraySub
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration
import de.fraunhofer.aisec.cpg.graph.edge.Properties
import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge
import de.fraunhofer.aisec.cpg.graph.statements.ReturnStatement
import de.fraunhofer.aisec.cpg.graph.statements.expressions.ArraySubscriptionExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression
import de.fraunhofer.aisec.cpg.graph.types.ObjectType
import de.fraunhofer.aisec.cpg.graph.types.UnknownType
import de.fraunhofer.aisec.cpg.helpers.SubgraphWalker
import de.fraunhofer.aisec.cpg.passes.EvaluationOrderGraphPass
import de.fraunhofer.aisec.cpg.passes.Pass
Expand All @@ -23,9 +26,12 @@ class GraphExtensionsPass(ctx: TranslationContext): TranslationResultPass(ctx) {

override fun accept(result: TranslationResult) {
result?.let {
addAdditionalEOGEdges(it)
addAdditionalDFGEdges(it)
addReturnNodes(it)
val allNodes = SubgraphWalker.flattenAST(it)
var functions = allNodes.filterIsInstance<FunctionDeclaration>()
addSubscriptionType(allNodes)
addAdditionalEOGEdges(functions)
addAdditionalDFGEdges(functions)
addReturnNodes(allNodes)
result.components
result.components.map { it.language?.frontend }.filterIsInstance<SolidityLanguageFrontend>().forEach {
it.pragmas.forEach { result += it }
Expand All @@ -37,9 +43,26 @@ class GraphExtensionsPass(ctx: TranslationContext): TranslationResultPass(ctx) {
override fun cleanup() {
}

private fun addAdditionalEOGEdges(result: TranslationResult) {
var funcitons = SubgraphWalker.flattenAST(result).filterIsInstance<FunctionDeclaration>()
funcitons.forEach {
private fun addSubscriptionType(allNodes: List<Node>) {
var subscriptions = allNodes.filterIsInstance<ArraySubscriptionExpression>().toMutableList()
while(subscriptions.isNotEmpty()){
// Because a subscription expression can have another unresolved subscription expression as its arrayExpression
val toProcess = subscriptions.filter { !(it.arrayExpression.type is UnknownType) }
if(toProcess.isEmpty())
break // No more processeable expressions
toProcess.forEach {
// If the type of the subscript expression is a mapping access we have to set the type here as it is a custom type
val sType = it.arrayExpression.type
if(sType is ObjectType && sType.name.toString() == "mapping" && sType.generics.size >= 2){
it.type = sType.generics[1]
}
subscriptions.remove(it)
}
}
}

private fun addAdditionalEOGEdges(functions: List<FunctionDeclaration>) {
functions.forEach {
val function = it
var body = it.body
body?.let {
Expand All @@ -57,9 +80,8 @@ class GraphExtensionsPass(ctx: TranslationContext): TranslationResultPass(ctx) {
}
}
}
private fun addAdditionalDFGEdges(result: TranslationResult) {
var funcitons = SubgraphWalker.flattenAST(result).filterIsInstance<FunctionDeclaration>()
funcitons.forEach {
private fun addAdditionalDFGEdges(functions: List<FunctionDeclaration>) {
functions.forEach {
val function = it
var body = it.body
body?.let {
Expand All @@ -78,9 +100,9 @@ class GraphExtensionsPass(ctx: TranslationContext): TranslationResultPass(ctx) {
}
}

private fun addReturnNodes(result: TranslationResult){
private fun addReturnNodes(allNodes: List<Node>){

var calls = SubgraphWalker.flattenAST(result).filterIsInstance<CallExpression>()
var calls = allNodes.filterIsInstance<CallExpression>()
calls.forEach {
val call = it
call.invokes.forEach {
Expand Down

0 comments on commit aa7692b

Please sign in to comment.