From 9538b249126720e9928df9bb856e58e5eb2dab54 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Thu, 19 Oct 2023 13:46:51 +0200 Subject: [PATCH] ++ --- .../cpg/frontends/ruby/DeclarationHandler.kt | 8 +-- .../cpg/frontends/ruby/ExpressionHandler.kt | 57 +++++++++++-------- .../cpg/frontends/ruby/StatementHandler.kt | 7 +++ 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/DeclarationHandler.kt b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/DeclarationHandler.kt index 182695dfd7..8471964f79 100644 --- a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/DeclarationHandler.kt +++ b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/DeclarationHandler.kt @@ -35,7 +35,7 @@ import de.fraunhofer.aisec.cpg.graph.newReturnStatement import de.fraunhofer.aisec.cpg.graph.statements.ReturnStatement import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block import org.jruby.ast.ArgumentNode -import org.jruby.ast.MethodDefNode +import org.jruby.ast.DefnNode import org.jruby.ast.Node class DeclarationHandler(lang: RubyLanguageFrontend) : @@ -43,7 +43,7 @@ class DeclarationHandler(lang: RubyLanguageFrontend) : init { map.put(ArgumentNode::class.java, ::handleArgumentNode) - map.put(MethodDefNode::class.java, ::handleMethodDefNode) + map.put(DefnNode::class.java, ::handleDefnNode) } private fun handleArgumentNode(node: Node?): Declaration? { @@ -54,8 +54,8 @@ class DeclarationHandler(lang: RubyLanguageFrontend) : return newParameterDeclaration(node.name.idString(), variadic = false) } - private fun handleMethodDefNode(node: Node): FunctionDeclaration? { - if (node !is MethodDefNode) { + private fun handleDefnNode(node: Node): FunctionDeclaration? { + if (node !is DefnNode) { return null } diff --git a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/ExpressionHandler.kt b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/ExpressionHandler.kt index 7d6b25e837..3599460ace 100644 --- a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/ExpressionHandler.kt +++ b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/ExpressionHandler.kt @@ -29,57 +29,58 @@ import de.fraunhofer.aisec.cpg.frontends.Handler import de.fraunhofer.aisec.cpg.graph.* import de.fraunhofer.aisec.cpg.graph.statements.ReturnStatement import de.fraunhofer.aisec.cpg.graph.statements.Statement +import de.fraunhofer.aisec.cpg.graph.statements.expressions.BinaryOperator import de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression import de.fraunhofer.aisec.cpg.graph.statements.expressions.ProblemExpression import de.fraunhofer.aisec.cpg.graph.types.UnknownType import org.jruby.ast.* import org.jruby.ast.Node +import org.jruby.ast.visitor.OperatorCallNode class ExpressionHandler(lang: RubyLanguageFrontend) : Handler({ ProblemExpression() }, lang) { init { map.put(CallNode::class.java, ::handleCallNode) - map.put(FCallNode::class.java, ::handleFCallNode) + map.put(OperatorCallNode::class.java, ::handleOperatorCallNode) map.put(IterNode::class.java, ::handleIterNode) map.put(StrNode::class.java, ::handleStrNode) + map.put(FixnumNode::class.java, ::handleFixnumNode) map.put(DVarNode::class.java, ::handleDVarNode) map.put(LocalVarNode::class.java, ::handleLocalVarNode) - map.put(AttrAssignNode::class.java, ::handleAttrAssignNode) + map.put(LocalAsgnNode::class.java, ::handleLocalAsgnNode) map.put(AssignableNode::class.java, ::handleAssignableNode) map.put(ReturnNode::class.java, ::handleReturnNode) } - private fun handleFCallNode(node: Node?): Statement? { - if (node !is FCallNode) { + private fun handleOperatorCallNode(node: Node?): BinaryOperator? { + if (node !is OperatorCallNode) { return null } - // FIXME: what is this? Unimplemented or intentional? - return null + + val binOp = newBinaryOperator(node.name.idString()) + + (this.handle(node.receiverNode) as? Expression)?.let { binOp.lhs = it } + + // Always seems to be an array? + val list = node.argsNode as ArrayNode + (this.handle(list.get(0)) as? Expression)?.let { binOp.rhs = it } + + return binOp } - private fun handleAttrAssignNode(node: Node?): Statement? { - if (node !is AttrAssignNode) { + private fun handleLocalAsgnNode(node: Node?): Statement? { + if (node !is LocalAsgnNode) { return null } - val binOp = newBinaryOperator("=", frontend.codeOf(node)) + val binOp = newAssignExpression("=") - val base = - this.handle(node.receiverNode) as? Expression - ?: return ProblemExpression("could not parse base") - val expr = - newMemberExpression( - node.name.idString(), - base, - UnknownType.getUnknownType(frontend.language), - "=" - ) - - binOp.lhs = expr - (this.handle(node.argsNode) as? Expression)?.let { binOp.rhs = it } - - return expr + binOp.lhs = listOfNotNull(this.handle(node.valueNode) as? Expression) + + binOp.rhs = node.childNodes().mapNotNull { (this.handle(it) as? Expression) } + + return binOp } private fun handleDVarNode(node: Node?): Statement? { @@ -200,6 +201,14 @@ class ExpressionHandler(lang: RubyLanguageFrontend) : return newLiteral(String(node.value.bytes()), primitiveType("String")) } + private fun handleFixnumNode(node: Node): Expression? { + if (node !is FixnumNode) { + return null + } + + return newLiteral(node.value, primitiveType("Integer")) + } + private fun handleReturnNode(node: Node): ReturnStatement? { if (node !is ReturnNode) { return null diff --git a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/StatementHandler.kt b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/StatementHandler.kt index ba9dd72681..66bb97c225 100644 --- a/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/StatementHandler.kt +++ b/cpg-language-ruby/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/ruby/StatementHandler.kt @@ -26,17 +26,20 @@ package de.fraunhofer.aisec.cpg.frontends.ruby import de.fraunhofer.aisec.cpg.frontends.Handler +import de.fraunhofer.aisec.cpg.graph.Node import de.fraunhofer.aisec.cpg.graph.newBlock import de.fraunhofer.aisec.cpg.graph.statements.Statement import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block import de.fraunhofer.aisec.cpg.graph.statements.expressions.ProblemExpression import org.jruby.ast.BlockNode +import org.jruby.ast.LocalAsgnNode class StatementHandler(lang: RubyLanguageFrontend) : Handler({ ProblemExpression() }, lang) { init { map.put(BlockNode::class.java, ::handleBlockNode) + map.put(LocalAsgnNode::class.java, ::handleLocalAsgnNode) } private fun handleBlockNode(blockNode: org.jruby.ast.Node): Block? { @@ -54,4 +57,8 @@ class StatementHandler(lang: RubyLanguageFrontend) : return compoundStatement } + + private fun handleLocalAsgnNode(node: org.jruby.ast.Node): Statement? { + return frontend.expressionHandler.handle(node) + } }