Skip to content

Commit

Permalink
rubysrc2cpg: handle empty arrays (#3207)
Browse files Browse the repository at this point in the history
* handle empty array in rhs of assignment

* add arrayInitializer with no children

* add test for empty array in block
  • Loading branch information
tuxology authored Jul 26, 2023
1 parent c4acc14 commit bacba5c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,18 @@ class AstCreator(
}

def astForArrayConstructorPrimaryContext(ctx: ArrayConstructorPrimaryContext): Seq[Ast] = {
astForIndexingArgumentsContext(ctx.arrayConstructor().indexingArguments())
if (ctx.getText == "[]") {
/* we might have an empty array, so create an empty as there would be no indexing args */
val arrayInitCallNode = NewCall()
.name(Operators.arrayInitializer)
.methodFullName(Operators.arrayInitializer)
.signature(Operators.arrayInitializer)
.typeFullName(Defines.Any)
.dispatchType(DispatchTypes.STATIC_DISPATCH)
Seq(callAst(arrayInitCallNode))
} else {
astForIndexingArgumentsContext(ctx.arrayConstructor().indexingArguments())
}
}

def astForBeginExpressionPrimaryContext(ctx: BeginExpressionPrimaryContext): Seq[Ast] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.joern.rubysrc2cpg.passes.ast

import io.joern.rubysrc2cpg.testfixtures.RubyCode2CpgFixture
import io.shiftleft.codepropertygraph.generated.{EvaluationStrategies, NodeTypes, DispatchTypes, Operators, nodes}
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, EvaluationStrategies, NodeTypes, Operators, nodes}
import io.shiftleft.semanticcpg.language.*
import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal

Expand Down Expand Up @@ -173,4 +173,14 @@ class AssignCpgTests extends RubyCode2CpgFixture {
tmpAssignNode.lineNumber shouldBe Some(1)
}
}

"empty array assignment" should {
val cpg = code("""x.y = []""".stripMargin)

"have an empty assignment" in {
val List(assignment) = cpg.call.name(Operators.assignment).l
assignment.argument.where(_.argumentIndex(2)).isCall.name.l shouldBe List(Operators.arrayInitializer)
assignment.argument.where(_.argumentIndex(2)).isCall.argument.l shouldBe List()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package io.joern.rubysrc2cpg.passes.ast

import io.joern.rubysrc2cpg.testfixtures.RubyCode2CpgFixture
import io.shiftleft.codepropertygraph.generated.EvaluationStrategies
import io.shiftleft.codepropertygraph.generated.NodeTypes
import io.shiftleft.codepropertygraph.generated.{EvaluationStrategies, NodeTypes, Operators}
import io.shiftleft.semanticcpg.language.*
import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal

Expand Down Expand Up @@ -121,4 +120,17 @@ class MethodOneTests extends RubyCode2CpgFixture {
}
}
}

"Function with empty array in block" should {
val cpg = code("""
|def foo
| []
|end
|""".stripMargin)

"contain empty array" in {
cpg.method.name("foo").size shouldBe 1
cpg.method.name("foo").block.containsCallTo(Operators.arrayInitializer).size shouldBe 1
}
}
}

0 comments on commit bacba5c

Please sign in to comment.