Skip to content

Commit 3b945bf

Browse files
[javasrc2cpg] Fix null type handling in TypeInferencePass (#5678)
1 parent f3719d3 commit 3b945bf

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

joern-cli/frontends/javasrc2cpg/src/main/scala/io/joern/javasrc2cpg/passes/TypeInferencePass.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import org.slf4j.LoggerFactory
1212
import scala.jdk.OptionConverters.RichOptional
1313
import io.joern.x2cpg.Defines.UnresolvedNamespace
1414
import io.shiftleft.codepropertygraph.generated.PropertyNames
15-
import io.joern.javasrc2cpg.typesolvers.TypeInfoCalculator.TypeConstants
15+
import io.joern.javasrc2cpg.typesolvers.TypeInfoCalculator.{PrimitiveTypes, TypeConstants}
1616

1717
class TypeInferencePass(cpg: Cpg) extends ForkJoinParallelCpgPass[Call](cpg) {
1818

@@ -55,7 +55,9 @@ class TypeInferencePass(cpg: Cpg) extends ForkJoinParallelCpgPass[Call](cpg) {
5555

5656
val hasDifferingArg = method.parameter.zip(callArgs).exists { case (parameter, argument) =>
5757
val maybeArgumentType = argument.propertyOption(Properties.TypeFullName).getOrElse(TypeConstants.Any)
58-
val argMatches = maybeArgumentType == TypeConstants.Any || maybeArgumentType == parameter.typeFullName
58+
val argMatches =
59+
maybeArgumentType == TypeConstants.Any || maybeArgumentType == parameter.typeFullName || (maybeArgumentType == TypeConstants.Null && !PrimitiveTypes
60+
.contains(parameter.typeFullName))
5961

6062
!argMatches
6163
}

joern-cli/frontends/javasrc2cpg/src/main/scala/io/joern/javasrc2cpg/typesolvers/TypeInfoCalculator.scala

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ object TypeInfoCalculator {
264264
val Record: String = "java.lang.Record"
265265
val Void: String = "void"
266266
val Any: String = "ANY"
267+
val Null: String = "null"
267268
}
268269

269270
object TypeNameConstants {
@@ -288,15 +289,9 @@ object TypeInfoCalculator {
288289
"registerNatives()"
289290
)
290291

291-
val NumericTypes: Set[String] = Set(
292-
"byte",
293-
"short",
294-
"int",
295-
"long",
296-
"float",
297-
"double",
298-
"char",
299-
"boolean",
292+
val PrimitiveTypes: Set[String] = Set("byte", "short", "int", "long", "float", "double", "char", "boolean")
293+
294+
val NumericTypes: Set[String] = PrimitiveTypes ++ Set(
300295
"java.lang.Byte",
301296
"java.lang.Short",
302297
"java.lang.Integer",

joern-cli/frontends/javasrc2cpg/src/test/scala/io/joern/javasrc2cpg/querying/TypeInferenceTests.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,41 @@ class NewTypeInferenceTests extends JavaSrcCode2CpgFixture {
4444
)
4545
}
4646

47+
"a call with an unresolved argument with a null type" when {
48+
"there is only one matching method should be resolved" in {
49+
val cpg = code(
50+
"""
51+
|package foo;
52+
|
53+
|import a.b.Bar;
54+
|
55+
|public class Foo {
56+
| public static Bar test(String s) {
57+
| return new Bar(s);
58+
| }
59+
|
60+
| public void sink(Bar b) {}
61+
|}
62+
|""".stripMargin,
63+
fileName = "Foo.java"
64+
).moreCode("""
65+
|import foo.Foo;
66+
|
67+
|import baz.Baz;
68+
|
69+
|class Test {
70+
| public static Bar stringCall() {
71+
| sink(Foo.test(null));
72+
| }
73+
|}
74+
|""".stripMargin)
75+
76+
cpg.method.name("stringCall").call.name("test").methodFullName.l shouldBe List(
77+
"foo.Foo.test:a.b.Bar(java.lang.String)"
78+
)
79+
}
80+
}
81+
4782
"there are multiple matching methods should not be resolved" in {
4883
val cpg = code(
4984
"""

0 commit comments

Comments
 (0)