Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package io.joern.c2cpg

import io.joern.c2cpg.parser.FileDefaults
import io.joern.c2cpg.passes.{AstCreationPass, PreprocessorPass, TypeDeclNodePass}
import io.joern.c2cpg.passes.FunctionDeclNodePass
import io.joern.c2cpg.passes.FullNameUniquenessPass
import io.shiftleft.codepropertygraph.generated.Cpg
import io.shiftleft.codepropertygraph.generated.Languages
import io.joern.x2cpg.passes.frontend.{MetaDataPass, TypeNodePass}
import io.joern.c2cpg.passes.*
import io.joern.x2cpg.X2Cpg.withNewEmptyCpg
import io.joern.x2cpg.X2CpgFrontend
import io.joern.x2cpg.{SourceFiles, X2CpgFrontend}
import io.joern.x2cpg.passes.frontend.{MetaDataPass, TypeNodePass}
import io.joern.x2cpg.utils.Report
import io.joern.x2cpg.SourceFiles
import io.shiftleft.codepropertygraph.generated.{Cpg, Languages}
import org.slf4j.LoggerFactory

import java.util.regex.Pattern
import scala.util.control.NonFatal
import scala.util.Try
import scala.util.control.NonFatal
import scala.util.matching.Regex

class C2Cpg extends X2CpgFrontend {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.joern.c2cpg

import io.joern.c2cpg.Frontend.*
import io.joern.x2cpg.{X2CpgConfig, X2CpgMain}
import io.joern.x2cpg.utils.server.FrontendHTTPServer
import io.joern.x2cpg.SourceFiles
import io.joern.x2cpg.{SourceFiles, X2CpgConfig, X2CpgMain}
import org.slf4j.LoggerFactory
import scopt.OParser

Expand Down Expand Up @@ -69,7 +68,7 @@ private object Frontend {

val cmdLineParser: OParser[Unit, Config] = {
val builder = OParser.builder[Config]
import builder._
import builder.*
OParser.sequence(
programName(classOf[C2Cpg].getSimpleName),
opt[Unit]("include-comments")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ import io.joern.x2cpg.AstCreatorBase
import io.joern.x2cpg.ValidationMode
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.datastructures.VariableScopeManager
import io.shiftleft.codepropertygraph.generated.NodeTypes
import io.shiftleft.codepropertygraph.generated.{DiffGraphBuilder, NodeTypes}
import io.shiftleft.codepropertygraph.generated.nodes.*
import io.shiftleft.codepropertygraph.generated.DiffGraphBuilder
import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal
import org.eclipse.cdt.core.dom.ast.IASTNode
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.eclipse.cdt.core.dom.ast.{IASTNode, IASTTranslationUnit}
import org.slf4j.{Logger, LoggerFactory}

import scala.collection.mutable

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
package io.joern.c2cpg.astcreation

import io.joern.x2cpg.Ast
import io.joern.x2cpg.{Ast, Defines as X2CpgDefines}
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.Defines as X2CpgDefines
import io.joern.x2cpg.datastructures.VariableScopeManager
import io.shiftleft.codepropertygraph.generated.{ControlStructureTypes, DispatchTypes, EvaluationStrategies, Operators}
import io.shiftleft.codepropertygraph.generated.nodes.ExpressionNew
import io.shiftleft.codepropertygraph.generated.{ControlStructureTypes, DispatchTypes, EvaluationStrategies, Operators}
import org.apache.commons.lang3.StringUtils
import org.eclipse.cdt.core.dom.ast
import org.eclipse.cdt.core.dom.ast.*
import org.eclipse.cdt.core.dom.ast.c.ICArrayType
import org.eclipse.cdt.core.dom.ast.cpp.*
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression
import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionCallExpression
import org.eclipse.cdt.internal.core.dom.parser.c.CASTIdExpression
import org.eclipse.cdt.internal.core.dom.parser.c.CFunctionType
import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType
import org.eclipse.cdt.internal.core.dom.parser.c.{
CASTFunctionCallExpression,
CASTIdExpression,
CFunctionType,
CPointerType
}
import org.eclipse.cdt.internal.core.dom.parser.cpp.{
CPPASTFoldExpression,
CPPASTIdExpression,
CPPASTQualifiedName,
CPPClosureType
}
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFoldExpression

import scala.annotation.tailrec
import scala.util.Try
Expand Down Expand Up @@ -123,7 +126,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
private def astForBinaryExpression(bin: IASTBinaryExpression): Ast = {
val op = OperatorMap.getOrElse(bin.getOperator, Defines.OperatorUnknown)
val callNode_ =
callNode(bin, code(bin), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(bin, code(bin), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val left = nullSafeAst(bin.getOperand1)
val right = nullSafeAst(bin.getOperand2)
callAst(callNode_, List(left, right))
Expand Down Expand Up @@ -298,31 +301,15 @@ trait AstForExpressionsCreator { this: AstCreator =>
val signature = X2CpgDefines.UnresolvedSignature
val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})"
val callCpgNode =
callNode(
call,
code(call),
name,
fullName,
DispatchTypes.STATIC_DISPATCH,
Some(signature),
Some(registerType(Defines.Any))
)
callNode(call, code(call), name, fullName, DispatchTypes.STATIC_DISPATCH, Some(signature), Some(Defines.Any))
createCallAst(callCpgNode, args, base = Some(instanceAst), receiver = Some(instanceAst))
case idExpr: CPPASTIdExpression =>
val args = call.getArguments.toList.map(a => astForNode(a))
val name = stripTemplateTags(StringUtils.normalizeSpace(idExpr.getName.getLastName.toString))
val signature = X2CpgDefines.UnresolvedSignature
val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})"
val callCpgNode =
callNode(
call,
code(call),
name,
fullName,
DispatchTypes.STATIC_DISPATCH,
Some(signature),
Some(registerType(Defines.Any))
)
callNode(call, code(call), name, fullName, DispatchTypes.STATIC_DISPATCH, Some(signature), Some(Defines.Any))
createCallAst(callCpgNode, args)
case otherExpr =>
// This could either be a pointer or an operator() call we do not know at this point
Expand All @@ -332,15 +319,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
val signature = X2CpgDefines.UnresolvedSignature
val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})"
val callCpgNode =
callNode(
call,
code(call),
name,
fullName,
DispatchTypes.STATIC_DISPATCH,
Some(signature),
Some(registerType(Defines.Any))
)
callNode(call, code(call), name, fullName, DispatchTypes.STATIC_DISPATCH, Some(signature), Some(Defines.Any))
val instanceAst = astForExpression(otherExpr)
createCallAst(callCpgNode, args, base = Some(instanceAst), receiver = Some(instanceAst))
}
Expand Down Expand Up @@ -417,7 +396,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
operatorMethod,
DispatchTypes.STATIC_DISPATCH,
None,
Some(registerType(Defines.Any))
Some(Defines.Any)
)
val operand = nullSafeAst(unary.getOperand)
callAst(cpgUnary, List(operand))
Expand All @@ -440,7 +419,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
Operators.sizeOf,
DispatchTypes.STATIC_DISPATCH,
None,
Some(registerType(Defines.Any))
Some(Defines.Any)
)
val arg = astForNode(typeId.getTypeId.getDeclSpecifier)
callAst(call, List(arg))
Expand All @@ -451,7 +430,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
private def astForConditionalExpression(expr: IASTConditionalExpression): Ast = {
val name = Operators.conditional
val call =
callNode(expr, code(expr), name, name, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(expr, code(expr), name, name, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))

val condAst = nullSafeAst(expr.getLogicalConditionExpression)
val posAst = nullSafeAst(expr.getPositiveResultExpression)
Expand All @@ -471,7 +450,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
name,
DispatchTypes.STATIC_DISPATCH,
None,
Some(registerType(Defines.Any))
Some(Defines.Any)
)

val expr = astForExpression(arrayIndexExpression.getArrayExpression)
Expand Down Expand Up @@ -542,7 +521,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
constructorCallCode: String,
args: List[Ast]
): Ast = {
val blockNode_ = blockNode(node, constructorCallCode, registerType(Defines.Any))
val blockNode_ = blockNode(node, constructorCallCode, Defines.Any)
scope.pushNewBlockScope(blockNode_)

val tmpNodeName = scopeLocalUniqueName("tmp")
Expand Down Expand Up @@ -585,15 +564,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
private def astForNewExpression(newExpression: ICPPASTNewExpression): Ast = {
val name = Defines.OperatorNew
val newCallNode =
callNode(
newExpression,
code(newExpression),
name,
name,
DispatchTypes.STATIC_DISPATCH,
None,
Some(registerType(Defines.Any))
)
callNode(newExpression, code(newExpression), name, name, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))

val typeId = newExpression.getTypeId
val newCallArgAst =
Expand Down Expand Up @@ -687,7 +658,7 @@ trait AstForExpressionsCreator { this: AstCreator =>
val op = Operators.fieldAccess
val accessCode = s"$name.${memberId.code}"
val ma =
callNode(init, accessCode, op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(init, accessCode, op, op, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val maAst = callAst(ma, List(Ast(specifierId), Ast(memberId)))
val assignmentCallNode =
callNode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import io.joern.c2cpg.passes.FunctionDeclNodePass
import io.joern.x2cpg.Ast
import io.joern.x2cpg.datastructures.Stack.*
import io.joern.x2cpg.datastructures.VariableScopeManager
import io.shiftleft.codepropertygraph.generated.nodes.*
import io.shiftleft.codepropertygraph.generated.*
import io.shiftleft.codepropertygraph.generated.nodes.*
import org.eclipse.cdt.core.dom.ast.*
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault
import org.eclipse.cdt.core.dom.ast.cpp.*
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator
import org.eclipse.cdt.internal.core.dom.parser.c.{CASTFunctionDeclarator, CASTParameterDeclaration, CVariable}
import org.eclipse.cdt.internal.core.dom.parser.cpp.*
Expand Down Expand Up @@ -178,8 +178,8 @@ trait AstForFunctionsCreator { this: AstCreator =>
}
Ast(ref)
case None =>
val typeDeclAst = createFunctionTypeAndTypeDecl(methodNode_)
astForMethod.merge(typeDeclAst)
val bindingAst = createFunctionBinding(methodNode_)
astForMethod.merge(bindingAst)
}
}

Expand All @@ -195,7 +195,7 @@ trait AstForFunctionsCreator { this: AstCreator =>
}
}

private def createFunctionTypeAndTypeDecl(method: NewMethod): Ast = {
private def createFunctionBinding(method: NewMethod): Ast = {
val parentNode: NewTypeDecl = methodAstParentStack.collectFirst { case t: NewTypeDecl => t }.get
method.astParentFullName = parentNode.fullName
method.astParentType = parentNode.label
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package io.joern.c2cpg.astcreation

import io.joern.x2cpg.Ast
import io.shiftleft.codepropertygraph.generated.DispatchTypes
import io.shiftleft.codepropertygraph.generated.Operators
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
import org.eclipse.cdt.core.dom.ast.*
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer
import org.eclipse.cdt.core.dom.ast.cpp.{ICPPASTConstructorInitializer, ICPPASTDesignatedInitializer}
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayRangeDesignator
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayRangeDesignator

Expand All @@ -16,7 +14,7 @@ trait AstForInitializersCreator { this: AstCreator =>
val MAX_INITIALIZERS = 1000
val op = Operators.arrayInitializer
val initCallNode =
callNode(l, code(l), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(l, code(l), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val clauses = l.getClauses.slice(0, MAX_INITIALIZERS)
val args = clauses.toList.map(x => astForNode(x))
val ast = callAst(initCallNode, args)
Expand All @@ -32,7 +30,7 @@ trait AstForInitializersCreator { this: AstCreator =>
protected def astForCPPASTConstructorInitializer(c: ICPPASTConstructorInitializer): Ast = {
val name = Defines.OperatorConstructorInitializer
val callNode_ =
callNode(c, code(c), name, name, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(c, code(c), name, name, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val args = c.getArguments.toList.map(a => astForNode(a))
callAst(callNode_, args)
}
Expand Down Expand Up @@ -72,7 +70,7 @@ trait AstForInitializersCreator { this: AstCreator =>
protected def astForCASTArrayRangeDesignator(des: CASTArrayRangeDesignator): Ast = {
val op = Operators.arrayInitializer
val callNode_ =
callNode(des, code(des), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(des, code(des), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val floorAst = nullSafeAst(des.getRangeFloor)
val ceilingAst = nullSafeAst(des.getRangeCeiling)
callAst(callNode_, List(floorAst, ceilingAst))
Expand All @@ -81,7 +79,7 @@ trait AstForInitializersCreator { this: AstCreator =>
protected def astForCPPASTArrayRangeDesignator(des: CPPASTArrayRangeDesignator): Ast = {
val op = Operators.arrayInitializer
val callNode_ =
callNode(des, code(des), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
callNode(des, code(des), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(Defines.Any))
val floorAst = nullSafeAst(des.getRangeFloor)
val ceilingAst = nullSafeAst(des.getRangeCeiling)
callAst(callNode_, List(floorAst, ceilingAst))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,13 @@ trait AstForPrimitivesCreator { this: AstCreator =>
protected def astForFieldReference(fieldRef: IASTFieldReference): Ast = {
val isInConstructor =
Try(CPPVisitor.findEnclosingFunctionOrClass(fieldRef)).toOption.exists(_.isInstanceOf[ICPPConstructor])
val op =
if (fieldRef.isPointerDereference && !isInConstructor) Operators.indirectFieldAccess else Operators.fieldAccess
val ma =
callNode(fieldRef, code(fieldRef), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
val owner = astForExpression(fieldRef.getFieldOwner)
val member = fieldIdentifierNode(fieldRef, fieldRef.getFieldName.toString, fieldRef.getFieldName.toString)
val dispatchType = DispatchTypes.STATIC_DISPATCH
val isDeref = fieldRef.isPointerDereference && !isInConstructor
val op = if (isDeref) Operators.indirectFieldAccess else Operators.fieldAccess
val ma = callNode(fieldRef, code(fieldRef), op, op, dispatchType, None, Some(Defines.Any))
val owner = astForExpression(fieldRef.getFieldOwner)
val memberName = fieldRef.getFieldName.toString
val member = fieldIdentifierNode(fieldRef, memberName, memberName)
callAst(ma, List(owner, Ast(member)))
}

Expand All @@ -232,32 +233,29 @@ trait AstForPrimitivesCreator { this: AstCreator =>
val fullNameNoSig = StringUtils.normalizeSpace(function.getQualifiedName.mkString("."))
s"$fullNameNoSig:$signature"
}
Ast(methodRefNode(qualId, name, fullName, registerType(function.getType.toString)))
val functionType = cleanType(safeGetType(function.getType))
Ast(methodRefNode(qualId, name, fullName, registerType(functionType)))
case _ =>
val op = Operators.fieldAccess
val ma =
callNode(qualId, code(qualId), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
val op = Operators.fieldAccess
val dispatchType = DispatchTypes.STATIC_DISPATCH
val ma = callNode(qualId, code(qualId), op, op, dispatchType, None, Some(Defines.Any))

def fieldAccesses(names: List[IASTNode], argIndex: Int = -1): Ast = names match {
case Nil => Ast()
case head :: Nil =>
astForNode(head)
case head :: tail =>
val codeString = s"${code(head)}::${tail.map(code).mkString("::")}"
val callNode_ =
callNode(head, code(head), op, op, DispatchTypes.STATIC_DISPATCH, None, Some(registerType(Defines.Any)))
.argumentIndex(argIndex)
callNode_.code = codeString
val arg1 = astForNode(head)
val arg2 = fieldAccesses(tail)
def fieldAccesses(names: List[IASTNode]): Ast = names match {
case Nil => Ast()
case head :: Nil => astForNode(head)
case _ =>
val init = names.init
val last = names.last
val codeString = names.map(code).mkString("::")
val callNode_ = callNode(names.head, codeString, op, op, dispatchType, None, Some(Defines.Any))
val arg1 = fieldAccesses(init)
val lastCode = code(last)
val arg2 = Ast(fieldIdentifierNode(last, lastCode, lastCode))
callAst(callNode_, List(arg1, arg2))
}
val qualifier = fieldAccesses(qualId.getQualifier.toIndexedSeq.toList)
val owner = if (qualifier != Ast()) {
qualifier
} else {
Ast(literalNode(qualId.getLastName, "<global>", Defines.Any))
}
val owner = if (qualifier != Ast()) { qualifier }
else { Ast(literalNode(qualId.getLastName, "<global>", Defines.Any)) }
val member = fieldIdentifierNode(
qualId.getLastName,
replaceQualifiedNameSeparator(qualId.getLastName.toString),
Expand Down
Loading
Loading