Skip to content

Commit 30fc37a

Browse files
[c2cpg] Make NamespaceBlock fullNames unique (#5767)
- prepended filename - appended suffix with incrementing counter (file-local) - removed special handling for duplicated NamespaceBlocks in FullNameUniquenessPass Fixes: ShiftLeftSecurity/codescience#8593
1 parent 7cbedf3 commit 30fc37a

File tree

8 files changed

+239
-105
lines changed

8 files changed

+239
-105
lines changed

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
package io.joern.c2cpg.astcreation
22

33
import io.joern.c2cpg.passes.FunctionDeclNodePass
4-
import io.joern.x2cpg.Ast
5-
import io.joern.x2cpg.AstNodeBuilder
64
import io.joern.x2cpg.AstNodeBuilder.dependencyNode
7-
import io.joern.x2cpg.SourceFiles
8-
import io.shiftleft.codepropertygraph.generated.nodes.{AstNodeNew, ExpressionNew, NewCall, NewNode}
5+
import io.joern.x2cpg.{Ast, AstNodeBuilder, SourceFiles}
96
import io.shiftleft.codepropertygraph.generated.EdgeTypes
7+
import io.shiftleft.codepropertygraph.generated.nodes.{ExpressionNew, NewCall, NewNode}
108
import org.eclipse.cdt.core.dom.ast.*
11-
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator
12-
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer
13-
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator
9+
import org.eclipse.cdt.core.dom.ast.c.{ICASTArrayDesignator, ICASTDesignatedInitializer, ICASTFieldDesignator}
1410
import org.eclipse.cdt.core.dom.ast.cpp.*
1511
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayRangeDesignator
16-
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayRangeDesignator
17-
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation
12+
import org.eclipse.cdt.internal.core.dom.parser.cpp.{CPPASTArrayRangeDesignator, ICPPEvaluation}
1813

1914
import scala.collection.mutable
20-
import scala.util.Success
21-
import scala.util.Try
15+
import scala.util.{Success, Try}
2216

2317
trait AstCreatorHelper { this: AstCreator =>
2418

@@ -72,6 +66,22 @@ trait AstCreatorHelper { this: AstCreator =>
7266
s"$name$idx"
7367
}
7468

69+
protected def scopeLocalUniqueNamespaceFullName(fullName: String): String = {
70+
val newFullName = fullName match {
71+
case "" => "<anonymous>"
72+
case s"$p." => s"$p.<anonymous>"
73+
case other => other
74+
}
75+
scopeLocalUniqueNames.get(newFullName) match {
76+
case None =>
77+
scopeLocalUniqueNames.update(newFullName, 0)
78+
newFullName
79+
case Some(index) =>
80+
val suffix = s"${Defines.NamespaceExtension}$index"
81+
s"$newFullName$suffix"
82+
}
83+
}
84+
7585
protected def scopeLocalUniqueName(name: String, fullName: String, targetName: String): (String, String) = {
7686
if (name.isEmpty && (fullName.isEmpty || fullName.endsWith("."))) {
7787
val newName = scopeLocalUniqueName(targetName, fullName)

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForTypesCreator.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ trait AstForTypesCreator { this: AstCreator =>
2424
}
2525

2626
protected def astForNamespaceAlias(namespaceAlias: ICPPASTNamespaceAlias): Ast = {
27-
val TypeFullNameInfo(name, fullName) = typeFullNameInfo(namespaceAlias)
28-
val codeString = code(namespaceAlias)
29-
val filename = fileName(namespaceAlias)
30-
Ast(namespaceBlockNode(namespaceAlias, name, s"$fullName<alias>", filename).code(codeString))
27+
// Namespace alias does not create any new AST nodes, so we return an empty AST here.
28+
// Ideally, we would create a namespace block node with an alias property, but that's not in the CPG schema.
29+
// Anyway, namespace aliases do not affect the AST structure. When used, CDT resolves them to the original namespace.
30+
Ast()
3131
}
3232

3333
private def typeForIASTDeclarator(
@@ -335,8 +335,9 @@ trait AstForTypesCreator { this: AstCreator =>
335335
val TypeFullNameInfo(name, fullName) = typeFullNameInfo(namespaceDefinition)
336336
val codeString = code(namespaceDefinition)
337337
val filename = fileName(namespaceDefinition)
338-
val namespaceBlockNode_ = namespaceBlockNode(namespaceDefinition, name, fullName, filename).code(codeString)
339-
val blockNode_ = blockNode(namespaceDefinition)
338+
val namespaceBlockNode_ =
339+
namespaceBlockNode(namespaceDefinition, name, s"$filename:$fullName", filename).code(codeString)
340+
val blockNode_ = blockNode(namespaceDefinition)
340341
methodAstParentStack.push(blockNode_)
341342
scope.pushNewMethodScope(fullName, name, namespaceBlockNode_, None)
342343
scope.pushNewBlockScope(blockNode_)

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/Defines.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ object Defines {
2323
val OperatorCall: String = "<operator>()"
2424
val OperatorNew: String = "<operator>.new"
2525
val DuplicateSuffix = "<duplicate>"
26+
val NamespaceExtension = "<extension>"
2627
val ConstSuffix = "<const>"
2728
val GlobalTag = "<global>"
2829
val UnknownTag = "<unknown>"

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/FullNameProvider.scala

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ object FullNameProvider {
1919

2020
private val TagsToKeepInFullName = List(
2121
"<anonymous>",
22+
"<const>",
23+
"<duplicate>",
24+
"<enum>",
25+
"<extension>",
26+
"<global>",
2227
"<iterator>",
2328
"<lambda>",
24-
"<global>",
2529
"<param>",
26-
"<const>",
27-
"<alias>",
28-
"<type>",
29-
"<enum>",
30-
"<tmp>"
30+
"<tmp>",
31+
"<type>"
3132
)
3233

3334
/** Removes template type parameters from qualified names while preserving special tags.
@@ -108,7 +109,6 @@ trait FullNameProvider { this: AstCreator =>
108109
case d: CPPASTIdExpression => shortNameForCPPASTIdExpression(d)
109110
case u: IASTUnaryExpression => shortName(u.getOperand)
110111
case c: IASTFunctionCallExpression => shortName(c.getFunctionNameExpression)
111-
case a: ICPPASTNamespaceAlias => shortName(a.getAlias)
112112
case d: IASTIdExpression => shortName(d.getName)
113113
case m: IASTPreprocessorMacroDefinition => shortName(m.getName)
114114
case n: ICPPASTNamespaceDefinition => shortName(n.getName)
@@ -131,7 +131,6 @@ trait FullNameProvider { this: AstCreator =>
131131
case None =>
132132
val qualifiedName = node match {
133133
case _: IASTTranslationUnit => ""
134-
case alias: ICPPASTNamespaceAlias => fullNameForICPPASTNamespaceAlias(alias)
135134
case aliasDecl: ICPPASTAliasDeclaration => fullNameForICPPASTAliasDeclaration(aliasDecl)
136135
case namespace: ICPPASTNamespaceDefinition => fullNameForICPPASTNamespaceDefinition(namespace)
137136
case compType: IASTCompositeTypeSpecifier => fullNameForIASTCompositeTypeSpecifier(compType)
@@ -184,10 +183,6 @@ trait FullNameProvider { this: AstCreator =>
184183
Try(ASTStringUtil.getQualifiedName(qfn)).getOrElse(nextClosureName())
185184
}
186185

187-
private def fullNameForICPPASTNamespaceAlias(alias: ICPPASTNamespaceAlias): String = {
188-
ASTStringUtil.getQualifiedName(alias.getMappingName)
189-
}
190-
191186
private def fullNameForICPPASTAliasDeclaration(alias: ICPPASTAliasDeclaration): String = {
192187
ASTStringUtil.getQualifiedName(alias.getAlias)
193188
}

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/TypeNameProvider.scala

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import scala.util.Try
1313

1414
object TypeNameProvider {
1515

16-
private type TypeLike = IASTEnumerationSpecifier | ICPPASTNamespaceDefinition | ICPPASTNamespaceAlias |
17-
IASTCompositeTypeSpecifier | IASTElaboratedTypeSpecifier
16+
private type TypeLike = IASTEnumerationSpecifier | ICPPASTNamespaceDefinition | IASTCompositeTypeSpecifier |
17+
IASTElaboratedTypeSpecifier
1818

1919
}
2020

@@ -26,19 +26,19 @@ trait TypeNameProvider { this: AstCreator =>
2626
// Sadly, there is no predefined List / Enum of this within Eclipse CDT:
2727
private val ReservedKeywordsAtTypes: List[String] =
2828
List(
29+
"auto",
30+
"class",
2931
"const",
30-
"static",
31-
"restrict",
32-
"extern",
33-
"typedef",
34-
"inline",
3532
"constexpr",
36-
"auto",
37-
"virtual",
3833
"enum",
39-
"struct",
34+
"extern",
35+
"inline",
4036
"interface",
41-
"class"
37+
"restrict",
38+
"static",
39+
"struct",
40+
"typedef",
41+
"virtual"
4242
)
4343

4444
private val KeywordsAtTypesToKeep: List[String] = List("unsigned", "volatile")
@@ -174,19 +174,17 @@ trait TypeNameProvider { this: AstCreator =>
174174
val fullName_ = registerType(cleanType(fullName(typeLike)))
175175
TypeFullNameInfo(name_, fullName_)
176176
case e: IASTEnumerationSpecifier =>
177-
val name_ = shortName(e)
178-
val fullName_ = fullName(e)
179-
val (uniqueName_, uniqueNameFullName_) = scopeLocalUniqueName(name_, fullName_, "enum")
180-
TypeFullNameInfo(uniqueName_, uniqueNameFullName_)
177+
val name_ = shortName(e)
178+
val fullName_ = fullName(e)
179+
val (uniqueName, uniqueNameFullName) = scopeLocalUniqueName(name_, fullName_, "enum")
180+
TypeFullNameInfo(uniqueName, uniqueNameFullName)
181181
case n: ICPPASTNamespaceDefinition =>
182-
val name_ = shortName(n)
183-
val fullName_ = fullName(n)
184-
val (uniqueName_, uniqueNameFullName_) = scopeLocalUniqueName(name_, fullName_, "namespace")
185-
TypeFullNameInfo(uniqueName_, uniqueNameFullName_)
186-
case a: ICPPASTNamespaceAlias =>
187-
val name_ = shortName(a)
188-
val fullName_ = fullName(a)
189-
TypeFullNameInfo(name_, fullName_)
182+
val name = shortName(n) match {
183+
case "" => "<anonymous>"
184+
case other => other
185+
}
186+
val fullName_ = fullName(n)
187+
TypeFullNameInfo(name, scopeLocalUniqueNamespaceFullName(fullName_))
190188
case s: IASTCompositeTypeSpecifier =>
191189
val fullName_ = registerType(cleanType(fullName(s)))
192190
val name_ = shortName(s) match {
@@ -255,11 +253,15 @@ trait TypeNameProvider { this: AstCreator =>
255253
}
256254

257255
private def typeForIASTName(name: IASTName): String = {
256+
val x = safeGetNodeType(name)
258257
safeGetBinding(name) match {
259258
case Some(v: IVariable) =>
260259
v.getType match {
261-
case f: IFunctionType => f.getReturnType.toString
262-
case other => other.toString
260+
case f: IFunctionType =>
261+
f.getReturnType.toString
262+
case c: ICPPBinding =>
263+
c.getQualifiedName.mkString(".")
264+
case other => other.toString
263265
}
264266
case _ => safeGetNodeType(name)
265267
}

joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/passes/FullNameUniquenessPass.scala

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package io.joern.c2cpg.passes
22

33
import io.joern.c2cpg.astcreation.Defines
4+
import io.shiftleft.codepropertygraph.generated.nodes.{Method, NamespaceBlock, TypeDecl}
45
import io.shiftleft.codepropertygraph.generated.{Cpg, PropertyNames}
5-
import io.shiftleft.codepropertygraph.generated.nodes.Binding
6-
import io.shiftleft.codepropertygraph.generated.nodes.Call
7-
import io.shiftleft.codepropertygraph.generated.nodes.Method
8-
import io.shiftleft.codepropertygraph.generated.nodes.NamespaceBlock
9-
import io.shiftleft.codepropertygraph.generated.nodes.TypeDecl
106
import io.shiftleft.passes.CpgPass
117
import io.shiftleft.semanticcpg.language.*
128
import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal
@@ -40,7 +36,6 @@ class FullNameUniquenessPass(cpg: Cpg) extends CpgPass(cpg) {
4036
override def run(dstGraph: DiffGraphBuilder): Unit = {
4137
handleMethods(dstGraph)
4238
handleTypeDecls(dstGraph)
43-
handleNamespaceBlocks(dstGraph)
4439
}
4540

4641
private def handleMethods(dstGraph: DiffGraphBuilder): Unit = {
@@ -112,14 +107,6 @@ class FullNameUniquenessPass(cpg: Cpg) extends CpgPass(cpg) {
112107
)
113108
}
114109

115-
private def handleNamespaceBlocks(dstGraph: DiffGraphBuilder): Unit = {
116-
handleDuplicateFullNames(
117-
cpg.namespaceBlock.nameNot(NamespaceTraversal.globalNamespaceName),
118-
PropertyNames.FullName,
119-
dstGraph
120-
)
121-
}
122-
123110
private def handleDuplicateFullNames[T <: AffectedNodeType](
124111
nodes: Iterator[T],
125112
fullNameProperty: String,

0 commit comments

Comments
 (0)