Repository: joernio/joern (scala)

Issue:
jssrc2cpg: ANY Type Returned for Primitive Literal Parameter on a Field-Based Call
In the following code:

```javascript
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```

I've observed that:
* The `/` parameter on `.get` is being interpreted as an `ANY` literal when it's seemingly obvious what type it is. When asking for the label, code, and type full name, I get `(LITERAL,"/",ANY)`.
* The point above also happens when replacing the string literal with a number value.

A suggested fix is to parse the argument token to identify if it is either a boolean, number, or string literal.

Pull request:
Fixes: https://github.com/joernio/joern/issues/1915

Patch:
diff --git a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/AstNodeBuilder.scala b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/AstNodeBuilder.scala
index 9bff92410f97..76b72875008b 100644
--- a/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/AstNodeBuilder.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/main/scala/io/joern/jssrc2cpg/astcreation/AstNodeBuilder.scala
@@ -325,13 +325,18 @@ trait AstNodeBuilder { this: AstCreator =>
     dynamicTypeOption: Option[String],
     line: Option[Integer],
     column: Option[Integer]
-  ): NewLiteral =
+  ): NewLiteral = {
+    val typeFullName = dynamicTypeOption match {
+      case Some(value) if Defines.JSTYPES.contains(value) => value
+      case _                                              => Defines.ANY
+    }
     NewLiteral()
       .code(code)
-      .typeFullName(Defines.ANY)
+      .typeFullName(typeFullName)
       .lineNumber(line)
       .columnNumber(column)
       .dynamicTypeHintFullName(dynamicTypeOption.toList)
+  }
 
   protected def createEqualsCallAst(
     destId: NewNode,


Test patch:
diff --git a/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/passes/ast/SimpleAstCreationPassTest.scala b/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
index d92a5d0de50a..427f3a62d741 100644
--- a/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
+++ b/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/passes/ast/SimpleAstCreationPassTest.scala
@@ -21,6 +21,13 @@ class SimpleAstCreationPassTest extends AbstractPassTest {
       typeDecls.filename shouldBe "code.js"
     }
 
+    "have correct type for literals" in AstFixture("let x = 1; let y = 'y'; let z = false;") { cpg =>
+      val List(x, y, z) = cpg.literal.l
+      x.typeFullName shouldBe Defines.NUMBER
+      y.typeFullName shouldBe Defines.STRING
+      z.typeFullName shouldBe Defines.BOOLEAN
+    }
+
     "have correct structure for multiple declarators in one place" in AstFixture("let x = 1, y = 2, z = 3;") { cpg =>
       val List(xAssignment, yAssignment, zAssignment) = cpg.call.l.sortBy(_.code)
       xAssignment.code shouldBe "let x = 1"