Skip to content

Commit f76444d

Browse files
[swiftsrc2cpg] Fixed instanceOf checks (#5688)
1 parent 56950d6 commit f76444d

File tree

8 files changed

+103
-22
lines changed

8 files changed

+103
-22
lines changed

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstCreator.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ class AstCreator(
4444
protected val dynamicInstanceTypeStack = new Stack[String]
4545
protected val localAstParentStack = new Stack[NewBlock]()
4646
protected val scopeLocalUniqueNames = mutable.HashMap.empty[String, Int]
47-
protected val seenAliasTypes = mutable.HashSet.empty[NewTypeDecl]
4847

4948
protected lazy val definedSymbols: Map[String, String] = {
5049
config.defines.map {

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ object AstCreatorHelper {
7676
case "" => Defines.Any
7777
case t if t.contains("?") => Defines.Any
7878
// Map builtin types
79+
case "Any" => Defines.Any
7980
case "String" => Defines.String
8081
case "Character" => Defines.Character
8182
case "Int" => Defines.Int
@@ -283,7 +284,7 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
283284
typeNameInfoForNode(node, name)
284285
}
285286

286-
protected def nameForTypeSyntax(node: TypeSyntax): String = {
287+
private def nameForTypeSyntax(node: TypeSyntax): String = {
287288
val name = node match {
288289
case _: ArrayTypeSyntax => "array-type"
289290
case a: AttributedTypeSyntax => nameForTypeSyntax(a.baseType)
@@ -307,6 +308,29 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As
307308
scopeLocalUniqueName(cleanType(name))
308309
}
309310

311+
protected def simpleTypeNameForTypeSyntax(node: TypeSyntax): String = {
312+
node match {
313+
case _: ArrayTypeSyntax => Defines.Array
314+
case a: AttributedTypeSyntax => simpleTypeNameForTypeSyntax(a.baseType)
315+
case _: ClassRestrictionTypeSyntax => Defines.Class
316+
case _: CompositionTypeSyntax => scopeLocalUniqueName("composition-type")
317+
case _: DictionaryTypeSyntax => Defines.Dictionary
318+
case _: FunctionTypeSyntax => Defines.Function
319+
case id: IdentifierTypeSyntax => scopeLocalUniqueName(cleanType(code(id.name)))
320+
case w: ImplicitlyUnwrappedOptionalTypeSyntax => simpleTypeNameForTypeSyntax(w.wrappedType)
321+
case m: MemberTypeSyntax => scopeLocalUniqueName(cleanType(code(m)))
322+
case m: MetatypeTypeSyntax => simpleTypeNameForTypeSyntax(m.baseType)
323+
case _: MissingTypeSyntax => scopeLocalUniqueName("missing-type")
324+
case n: NamedOpaqueReturnTypeSyntax => simpleTypeNameForTypeSyntax(n.`type`)
325+
case o: OptionalTypeSyntax => simpleTypeNameForTypeSyntax(o.wrappedType)
326+
case p: PackElementTypeSyntax => simpleTypeNameForTypeSyntax(p.pack)
327+
case p: PackExpansionTypeSyntax => simpleTypeNameForTypeSyntax(p.repetitionPattern)
328+
case s: SomeOrAnyTypeSyntax => simpleTypeNameForTypeSyntax(s.constraint)
329+
case s: SuppressedTypeSyntax => simpleTypeNameForTypeSyntax(s.`type`)
330+
case _: TupleTypeSyntax => Defines.Tuple
331+
}
332+
}
333+
310334
protected def typeNameInfoForTypeSyntax(node: TypeSyntax): TypeInfo = {
311335
val name = nameForTypeSyntax(node)
312336
typeNameInfoForNode(node, name)

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstForDeclSyntaxCreator.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ trait AstForDeclSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
4848
astParentFullName,
4949
alias = aliasName
5050
)
51-
seenAliasTypes.add(typeDeclNode_)
5251

5352
attributes.foreach { ast =>
5453
Ast.storeInDiffGraph(ast, diffGraph)
@@ -328,7 +327,6 @@ trait AstForDeclSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
328327
astParentFullName,
329328
inherits = inherits
330329
)
331-
seenAliasTypes.add(typeDeclNode_)
332330

333331
attributes.foreach { ast =>
334332
Ast.storeInDiffGraph(ast, diffGraph)
@@ -472,7 +470,6 @@ trait AstForDeclSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
472470
astParentFullName,
473471
inherits = inherits
474472
)
475-
seenAliasTypes.add(typeDeclNode_)
476473

477474
attributes.foreach { ast =>
478475
Ast.storeInDiffGraph(ast, diffGraph)
@@ -856,7 +853,6 @@ trait AstForDeclSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
856853
astParentFullName,
857854
alias = Option(aliasName)
858855
)
859-
seenAliasTypes.add(typeDeclNode_)
860856

861857
attributes.foreach { ast =>
862858
Ast.storeInDiffGraph(ast, diffGraph)

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstForExprSyntaxCreator.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,15 +380,17 @@ trait AstForExprSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
380380
}
381381

382382
private def astForIsExprSyntax(node: IsExprSyntax): Ast = {
383+
val op = Operators.instanceOf
383384
val lhsAst = astForNode(node.expression)
384-
val rhsAst = astForNode(node.`type`)
385385

386-
val op = Operators.instanceOf
387-
val tpe = fullnameProvider.typeFullname(node).getOrElse(Defines.Any)
386+
val tpeNode = node.`type`
387+
val tpe = simpleTypeNameForTypeSyntax(tpeNode)
388388
registerType(tpe)
389-
val callNode_ = createStaticCallNode(node, code(node), op, op, tpe)
390389

391-
val argAsts = List(lhsAst, rhsAst)
390+
val callNode_ = createStaticCallNode(node, code(node), op, op, Defines.Bool)
391+
val typeRefNode_ = typeRefNode(node, code(tpeNode), tpe)
392+
393+
val argAsts = List(lhsAst, Ast(typeRefNode_))
392394
callAst(callNode_, argAsts)
393395
}
394396

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstForPatternSyntaxCreator.scala

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package io.joern.swiftsrc2cpg.astcreation
22

33
import io.joern.swiftsrc2cpg.parser.SwiftNodeSyntax.*
4-
import io.joern.x2cpg.{Ast, ValidationMode}
54
import io.joern.x2cpg.datastructures.VariableScopeManager
65
import io.joern.x2cpg.frontendspecific.swiftsrc2cpg.Defines
7-
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, EdgeTypes, Operators}
6+
import io.joern.x2cpg.{Ast, ValidationMode}
7+
import io.shiftleft.codepropertygraph.generated.{EdgeTypes, Operators}
88

99
import scala.annotation.{tailrec, unused}
1010

@@ -20,16 +20,17 @@ trait AstForPatternSyntaxCreator(implicit withSchemaValidation: ValidationMode)
2020
}
2121

2222
private def astForIsTypePatternSyntax(node: IsTypePatternSyntax): Ast = {
23-
val op = Operators.instanceOf
23+
val op = Operators.instanceOf
24+
2425
val tpeNode = node.`type`
25-
val tpeCode = code(tpeNode)
26-
val tpe = nameForTypeSyntax(tpeNode)
26+
val tpe = simpleTypeNameForTypeSyntax(tpeNode)
2727
registerType(tpe)
2828

29-
val callNode_ = createStaticCallNode(node, code(node), op, op, tpe)
30-
val typeRefNode_ = typeRefNode(node, tpeCode, tpe)
31-
val arg = Ast(typeRefNode_)
32-
callAst(callNode_, List(arg))
29+
val callNode_ = createStaticCallNode(node, code(node), op, op, Defines.Bool)
30+
val typeRefNode_ = typeRefNode(node, code(tpeNode), tpe)
31+
32+
val argAsts = List(Ast(typeRefNode_))
33+
callAst(callNode_, argAsts)
3334
}
3435

3536
private def astForMissingPatternSyntax(@unused node: MissingPatternSyntax): Ast = Ast()

joern-cli/frontends/swiftsrc2cpg/src/main/scala/io/joern/swiftsrc2cpg/astcreation/AstForTypeSyntaxCreator.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ trait AstForTypeSyntaxCreator(implicit withSchemaValidation: ValidationMode) {
1818
val typeDeclNode_ =
1919
typeDeclNode(node, typeName, typeFullName, parserResult.filename, code(node), astParentType, astParentFullName)
2020

21-
seenAliasTypes.add(typeDeclNode_)
2221
diffGraph.addEdge(methodAstParentStack.head, typeDeclNode_, EdgeTypes.AST)
2322
typeDeclNode_
2423
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.joern.swiftsrc2cpg.passes.ast
2+
3+
import io.joern.swiftsrc2cpg.testfixtures.SwiftCompilerSrc2CpgSuite
4+
import io.joern.x2cpg.frontendspecific.swiftsrc2cpg.Defines
5+
import io.shiftleft.codepropertygraph.generated.*
6+
import io.shiftleft.codepropertygraph.generated.nodes.*
7+
import io.shiftleft.semanticcpg.language.*
8+
9+
class InstanceOfTests extends SwiftCompilerSrc2CpgSuite {
10+
11+
"InstanceOfTests" should {
12+
"have correct structure for instanceOf checks" in {
13+
val cpg = code("""
14+
|func main(x: Int) -> Int {
15+
| if x is [[String: Any]] {
16+
| return 2
17+
| }
18+
| return 1
19+
|}""".stripMargin)
20+
inside(cpg.call.nameExact(Operators.instanceOf).argument.l) { case List(x: Identifier, typeRef: TypeRef) =>
21+
x.typeFullName shouldBe Defines.Int
22+
typeRef.typeFullName shouldBe "Swift.Array"
23+
}
24+
}
25+
26+
"have correct structure for instanceOf checks with compiler support" in {
27+
val cpg = codeWithSwiftSetup("""
28+
|func main(x: Int) -> Int {
29+
| if x is [[String: Any]] {
30+
| return 2
31+
| }
32+
| return 1
33+
|}""".stripMargin)
34+
inside(cpg.call.nameExact(Operators.instanceOf).argument.l) { case List(x: Identifier, typeRef: TypeRef) =>
35+
x.typeFullName shouldBe Defines.Int
36+
// Sadly, swiftc does not offer any information about the actual (deep) type of the RSH of the check
37+
typeRef.typeFullName shouldBe "Swift.Array"
38+
}
39+
}
40+
}
41+
42+
}

joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/frontendspecific/swiftsrc2cpg/Defines.scala

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ object Defines {
1616
val Double: String = "Swift.Double"
1717
val Bool: String = "Swift.Bool"
1818
val Function: String = "Swift.Function"
19+
val Tuple: String = "Swift.Tuple"
1920
val Array: String = "Swift.Array"
21+
val Class: String = "Swift.Class"
2022
val Dictionary: String = "Swift.Dictionary"
2123
val Nil: String = "Swift.Nil"
2224
val Iterator: String = "Swift.Iterator"
@@ -27,7 +29,23 @@ object Defines {
2729
val GlobalNamespace: String = NamespaceTraversal.globalNamespaceName
2830

2931
val SwiftTypes: List[String] =
30-
List(Any, Nil, Character, String, Int, Float, Double, Bool, Function, Array, Dictionary, Iterator, Void)
32+
List(
33+
Any,
34+
Nil,
35+
Character,
36+
String,
37+
Int,
38+
Float,
39+
Double,
40+
Bool,
41+
Tuple,
42+
Function,
43+
Class,
44+
Array,
45+
Dictionary,
46+
Iterator,
47+
Void
48+
)
3149

3250
val PostfixOperatorMap: Map[String, String] = Map(
3351
"++" -> Operators.postIncrement,

0 commit comments

Comments
 (0)