All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.joern.x2cpg.frontendspecific.jssrc2cpg.ObjectPropertyCallLinker.scala Maven / Gradle / Ivy

There is a newer version: 4.0.131
Show newest version
package io.joern.x2cpg.frontendspecific.jssrc2cpg

import io.shiftleft.codepropertygraph.generated.nodes.{Call, MethodRef}
import io.shiftleft.codepropertygraph.generated.{Cpg, PropertyNames}
import io.shiftleft.passes.CpgPass
import io.shiftleft.semanticcpg.language.*

/** Perform a simple analysis to find a common pattern in JavaScript where objects are dynamically assigned function
  * pointers. To keep this precise, this will only match objects defined within the scope of the same file.
  *
  * This relies on JavaScriptTypeHintCallLinker.
  */
class ObjectPropertyCallLinker(cpg: Cpg) extends CpgPass(cpg) {

  override def run(builder: DiffGraphBuilder): Unit = {

    def propertyCallRegexPattern(withMatchingGroup: Boolean): String =
      "^(?:\\{.*\\}|.*):\\(" + (if withMatchingGroup then "(.*)" else ".*") + "\\):.*$"

    val propertyCallRegex = propertyCallRegexPattern(true).r
    val objectCalls       = cpg.call.methodFullName(propertyCallRegexPattern(false)).l
    val propertyAccessToCalls = objectCalls
      .flatMap { call =>
        call.methodFullName match {
          case propertyCallRegex(baseProperty) => Option(s"$baseProperty.${call.name}" -> call)
          case _                               => None
        }
      }
      .groupBy(_._1)
      .map { case (k, vs) => k -> vs.map(_._2) }
    cpg.assignment
      .and(_.source.isMethodRef, _.target.isCall.fieldAccess)
      .map { a => a.target.asInstanceOf[Call] -> a.source.asInstanceOf[MethodRef].referencedMethod.fullName }
      .foreach { (functionTarget, calleeFn) =>
        propertyAccessToCalls
          .filter { case (propertyAccess, _) => functionTarget.code.endsWith(propertyAccess) }
          .foreach { case (_, calls) =>
            calls.where(_.file.nameExact(functionTarget.file.name.toSeq*)).foreach { c =>
              builder.setNodeProperty(c, PropertyNames.METHOD_FULL_NAME, calleeFn)
            }
          }
      }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy