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

io.shiftleft.passes.propagateedges.PropagateEdgePass.scala Maven / Gradle / Ivy

package io.shiftleft.passes.propagateedges

import gremlin.scala._
import io.shiftleft.semanticsloader.Semantics
import io.shiftleft.codepropertygraph.generated._
import io.shiftleft.diffgraph.DiffGraph
import io.shiftleft.passes.CpgPass
import org.apache.logging.log4j.{LogManager, Logger}
import org.apache.tinkerpop.gremlin.structure.Direction

import scala.collection.JavaConverters._

/**
  * Create PROPAGATE edges which mark parameters defined by a method.
  * PROPAGATE edges can be picked up by the reachingdef pass to calculate
  * reaching definition edges.
  */
class PropagateEdgePass(graph: ScalaGraph, semantics: Semantics) extends CpgPass(graph) {
  import PropagateEdgePass.logger

  var dstGraph: DiffGraph = _

  override def run(): Iterator[DiffGraph] = {
    dstGraph = new DiffGraph()

    semantics.elements.foreach { semantic =>
      val methodOption =
        graph.V().hasLabel(NodeTypes.METHOD).has(NodeKeys.FULL_NAME -> semantic.methodFullName).headOption()

      methodOption match {
        case Some(method) =>
          addSelfDefSemantic(method, semantic.parameterIndex)
        case None =>
      }
    }

    Iterator(dstGraph)
  }

  private def addSelfDefSemantic(method: Vertex, parameterIndex: Int): Unit = {
    // From where the PROPAGATE edge is coming does not matter for the open source reachable by.
    // Thus we let it start from the corresponding METHOD_PARAMETER_IN.
    val parameterInOption = method
      .vertices(Direction.OUT, EdgeTypes.AST)
      .asScala
      .find(node => node.label() == NodeTypes.METHOD_PARAMETER_IN && node.value2(NodeKeys.ORDER) == parameterIndex)

    val parameterOutOption = method
      .vertices(Direction.OUT, EdgeTypes.AST)
      .asScala
      .find(node => node.label() == NodeTypes.METHOD_PARAMETER_OUT && node.value2(NodeKeys.ORDER) == parameterIndex)

    (parameterInOption, parameterOutOption) match {
      case (Some(parameterIn), Some(parameterOut)) =>
        addPropagateEdge(parameterIn, parameterOut, isAlias = false)
      case (None, _) =>
        logger.warn(s"Could not find parameter $parameterIndex of ${method.value2(NodeKeys.FULL_NAME)}.")
      case _ =>
        logger.warn(s"Could not find output parameter $parameterIndex of ${method.value2(NodeKeys.FULL_NAME)}.")
    }
  }

  private def addPropagateEdge(src: Vertex, dst: Vertex, isAlias: java.lang.Boolean): Unit = {
    dstGraph.addEdgeInOriginal(src.asInstanceOf[nodes.StoredNode],
                               dst.asInstanceOf[nodes.StoredNode],
                               EdgeTypes.PROPAGATE,
                               (EdgeKeyNames.ALIAS, isAlias) :: Nil)
  }
}

object PropagateEdgePass {
  private val logger: Logger = LogManager.getLogger(classOf[PropagateEdgePass])
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy