From e6b37c5643c75d3c9427834211970df65c06ae72 Mon Sep 17 00:00:00 2001 From: Andrei Dreyer Date: Wed, 4 Dec 2024 16:32:46 +0200 Subject: [PATCH] [ruby] Fixed `Paramater without method` issue (#5159) * Fixed issue where InstanceFieldIdentifier was wrongly mapped to SimpleIdentifier * Instance Field Assignment made more type safe --- .../parser/RubyJsonToNodeCreator.scala | 8 +++++-- .../rubysrc2cpg/querying/ClassTests.scala | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyJsonToNodeCreator.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyJsonToNodeCreator.scala index 8eba7d4cc907..8d416d21b90c 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyJsonToNodeCreator.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyJsonToNodeCreator.scala @@ -1045,8 +1045,12 @@ class RubyJsonToNodeCreator( case Some(rhs) => SingleAssignment(lhs, "=", rhs)(obj.toTextSpan) case None => - // `lvasgn` is used in exec_var for rescueExpr, which only has LHS - MandatoryParameter(lhs.span.text)(lhs.span) + if (AstType.fromString(obj(ParserKeys.Type).str) == AstType.LocalVariableAssign) { + // `lvasgn` is used in exec_var for rescueExpr, which only has LHS + MandatoryParameter(lhs.span.text)(lhs.span) + } else { + lhs + } } } diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala index 806f04f1ce0d..0476cc6395f3 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala @@ -1311,4 +1311,27 @@ class ClassTests extends RubyCode2CpgFixture { cpg.typeDecl("Foo").astChildren.whereNot(_.or(_.isMethod, _.isModifier, _.isTypeDecl, _.isMember)).size shouldBe 0 } + + "Proc-param in method with instance field assignment and instance field argument" in { + val cpg = code(""" + |class Batches + | def as_batches(query, &) + | records.each(&) + | @limit -= 100 + | return if @limit.zero? + | end + |end + |""".stripMargin) + + inside(cpg.method.name("as_batches").l) { + case batchesMethod :: Nil => + inside(batchesMethod.parameter.l) { + case _ :: _ :: procParam :: Nil => + procParam.code shouldBe "&" + procParam.name shouldBe "" + case xs => fail(s"Expected three parameters, got (${xs.size}) [${xs.code.mkString(",")}]") + } + case xs => + } + } }