Repository: joernio/joern (scala)

Issue:
A problem about `wchar_t *`
I used joern to parse the following code
```
void CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_10_bad()
{
    wchar_t * data;
    wchar_t * dataBadBuffer = (wchar_t *)ALLOCA(50*sizeof(wchar_t));
    wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA(100*sizeof(wchar_t));
    ……
}
```
but the `code` of data is `wchar_t  data`,missing `*`
```
joern> cpg.method("CWE121_Stack_Based_Buffer_Overflow__CWE805_wchar_t_alloca_memmove_10_bad").local.code.l 
res9: List[String] = List(
  "wchar_t data",
  "wchar_t dataBadBuffer",
  "wchar_t dataGoodBuffer",
  "wchar_t[100] source"
)
```

Pull request description:
Fixes: https://github.com/joernio/joern/issues/1296
Fixes: https://github.com/joernio/joern/issues/1297

Patch:
diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala
index bacb15bde4ef..577b92298323 100644
--- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala
+++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala
@@ -333,7 +333,8 @@ trait AstCreatorHelper {
     }
     if (pointers.isEmpty) { s"$tpe$arr" }
     else {
-      s"$tpe$arr${"*" * pointers.size}".strip()
+      val refs = "*" * (pointers.length - pointers.count(_.isInstanceOf[ICPPASTReferenceOperator]))
+      s"$tpe$arr$refs".strip()
     }
   }
 
@@ -455,6 +456,9 @@ trait AstCreatorHelper {
       case s: IASTNamedTypeSpecifier if s.getParent.isInstanceOf[IASTParameterDeclaration] =>
         val parentDecl = s.getParent.asInstanceOf[IASTParameterDeclaration].getDeclarator
         pointersAsString(s, parentDecl, stripKeywords)
+      case s: IASTNamedTypeSpecifier if s.getParent.isInstanceOf[IASTSimpleDeclaration] =>
+        val parentDecl = s.getParent.asInstanceOf[IASTSimpleDeclaration].getDeclarators.head
+        pointersAsString(s, parentDecl, stripKeywords)
       case s: IASTNamedTypeSpecifier     => ASTStringUtil.getSimpleName(s.getName)
       case s: IASTCompositeTypeSpecifier => ASTStringUtil.getSimpleName(s.getName)
       case s: IASTEnumerationSpecifier   => ASTStringUtil.getSimpleName(s.getName)


Test patch:
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/querying/LocalsTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/querying/LocalsTests.scala
index f41ac3cfc08c..c9ecbfc5b5e3 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/querying/LocalsTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/querying/LocalsTests.scala
@@ -33,15 +33,12 @@ class LocalsTests extends CCodeToCpgSuite {
     | 
     | void test() {
     |   static int a, b, c;
+    |   wchar_t *foo;
     | }
     | """.stripMargin
 
   "should allow to query for all locals" in {
-    cpg.local.name.toSetMutable shouldBe Set("a", "b", "c", "z", "x", "q", "p")
-  }
-
-  "should allow to query for all locals in method `free_list`" in {
-    cpg.method.name("free_list").local.name.toSetMutable shouldBe Set("q", "p")
+    cpg.local.name.toSetMutable shouldBe Set("a", "b", "c", "z", "x", "q", "p", "foo")
   }
 
   "should prove correct (name, type) pairs for locals" in {
@@ -56,7 +53,7 @@ class LocalsTests extends CCodeToCpgSuite {
   }
 
   "should prove correct (name, type, code) pairs for locals" in {
-    inside(cpg.method.name("test").local.l) { case List(a, b, c) =>
+    inside(cpg.method.name("test").local.l) { case List(a, b, c, foo) =>
       a.name shouldBe "a"
       a.typeFullName shouldBe "int"
       a.code shouldBe "static int a"
@@ -66,6 +63,9 @@ class LocalsTests extends CCodeToCpgSuite {
       c.name shouldBe "c"
       c.typeFullName shouldBe "int"
       c.code shouldBe "static int c"
+      foo.name shouldBe "foo"
+      foo.typeFullName shouldBe "wchar_t"
+      foo.code shouldBe "wchar_t* foo"
     }
   }
 
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/standard/CMethodTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/standard/CMethodTests.scala
index 18b11b9a9113..5a1747a76554 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/standard/CMethodTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/standard/CMethodTests.scala
@@ -86,3 +86,17 @@ class CMethodTest4 extends CCodeToCpgSuite {
     cpg.typeDecl.fullName.l should not contain "doFoo"
   }
 }
+
+class CMethodTest5 extends CCodeToCpgSuite(fileSuffix = ".cpp") {
+  override val code = "void foo(int &data) {};"
+
+  "should be correct for pointer dereference parameter" in {
+    inside(cpg.method("foo").parameter.l) { case List(data) =>
+      data.index shouldBe 1
+      data.name shouldBe "data"
+      data.code shouldBe "int &data"
+      data.typeFullName shouldBe "int"
+      data.isVariadic shouldBe false
+    }
+  }
+}