Skip to content

Commit

Permalink
Fix/issue 62 (#63)
Browse files Browse the repository at this point in the history
* Fix importCode predef. Default to reachables slicing by default

Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>

* native image fixes for java

Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>

---------

Signed-off-by: Prabhu Subramanian <prabhu@appthreat.com>
  • Loading branch information
prabhu authored Jan 14, 2024
1 parent 3229c13 commit 812f317
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 70 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name := "chen"
ThisBuild / organization := "io.appthreat"
ThisBuild / version := "2.0.2"
ThisBuild / version := "2.0.3"
ThisBuild / scalaVersion := "3.3.1"

val cpgVersion = "1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ LABEL maintainer="appthreat" \
org.opencontainers.image.authors="Team AppThreat <cloud@appthreat.com>" \
org.opencontainers.image.source="https://github.com/appthreat/chen" \
org.opencontainers.image.url="https://github.com/appthreat/chen" \
org.opencontainers.image.version="1.1.x" \
org.opencontainers.image.version="2.0.x" \
org.opencontainers.image.vendor="appthreat" \
org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.title="chen" \
Expand Down
2 changes: 1 addition & 1 deletion codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"downloadUrl": "https://github.com/AppThreat/chen",
"issueTracker": "https://github.com/AppThreat/chen/issues",
"name": "chen",
"version": "2.0.2",
"version": "2.0.3",
"description": "Code Hierarchy Exploration Net (chen) is an advanced exploration toolkit for your application source code and its dependency hierarchy.",
"applicationCategory": "code-analysis",
"keywords": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.appthreat.console.cpgcreation

import better.files.File
import io.appthreat.console.FrontendConfig
import io.shiftleft.codepropertygraph.Cpg

Expand All @@ -10,8 +11,8 @@ case class AtomGenerator(
config: FrontendConfig,
rootPath: Path,
language: String,
sliceMode: String = "usages",
slicesFile: String = "usages.json"
sliceMode: String = "reachables",
slicesFile: String = "reachables.slices.json"
) extends CpgGenerator:
private lazy val command: String = "atom"

Expand All @@ -24,12 +25,12 @@ case class AtomGenerator(
"-s",
slicesFile,
"--output",
outputPath,
(File(inputPath) / outputPath).pathAsString,
"--language",
language,
inputPath
) ++ config.cmdLineParams
runShellCommand(command, arguments).map(_ => outputPath)
runShellCommand(command, arguments).map(_ => (File(inputPath) / outputPath).pathAsString)

override def isAvailable: Boolean = true

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package io.appthreat.console.cpgcreation

import better.files.File
import io.appthreat.console.{Console, FrontendConfig, Reporting}
import io.appthreat.console.workspacehandling.Project
import io.appthreat.console.{ConsoleException, FrontendConfig, Reporting}
import io.appthreat.console.{Console, ConsoleException, FrontendConfig, Reporting}
import io.shiftleft.codepropertygraph.Cpg
import io.shiftleft.codepropertygraph.generated.Languages
import overflowdb.traversal.help.Table
import me.shadaj.scalapy.py
import me.shadaj.scalapy.py.SeqConverters
import py.PyQuote
import me.shadaj.scalapy.interpreter.CPythonInterpreter
import overflowdb.traversal.help.Table

import java.nio.file.Path
import scala.util.{Failure, Success, Try}
Expand Down
2 changes: 1 addition & 1 deletion meta.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% set version = "2.0.2" %}
{% set version = "2.0.3" %}

package:
name: chen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,8 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str
val jdkPath = (config.jdkPath, jdkPathFromEnvVar) match
case (None, None) =>
val javaHome = System.getProperty("java.home")
logger.debug(
s"No explicit jdk-path set in , so using system java.home for JDK type information: $javaHome"
)
javaHome

if javaHome != null && javaHome.nonEmpty then javaHome
else System.getenv("JAVA_HOME")
case (None, Some(jdkPath)) =>
logger.debug(
s"Using JDK path from environment variable ${JavaSrcEnvVar.JdkPath.name} for JDK type information: $jdkPath"
Expand All @@ -104,10 +101,11 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str
s"Using JDK path set with jdk-path option for JDK type information: $jdkPath"
)
jdkPath

val jdkJarTypeSolver = JdkJarTypeSolver.fromJdkPath(jdkPath)
combinedTypeSolver.addNonCachingTypeSolver(jdkJarTypeSolver)

var jdkJarTypeSolver: JdkJarTypeSolver = null
// native-image could have empty JAVA_HOME
if jdkPath != null && jdkPath.nonEmpty then
jdkJarTypeSolver = JdkJarTypeSolver.fromJdkPath(jdkPath)
combinedTypeSolver.addNonCachingTypeSolver(jdkJarTypeSolver)
val relativeSourceFilenames =
sourceFilenames.map(filename =>
Path.of(config.inputPath).relativize(Path.of(filename)).toString
Expand All @@ -120,7 +118,6 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str
combinedTypeSolver,
symbolSolver
)

combinedTypeSolver.addCachingTypeSolver(sourceTypeSolver)
combinedTypeSolver.addNonCachingTypeSolver(new ReflectionTypeSolver())
// Add solvers for inference jars
Expand All @@ -130,8 +127,8 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str
Try(new JarTypeSolver(path)).toOption
}
.foreach { combinedTypeSolver.addNonCachingTypeSolver(_) }

(symbolSolver, jdkJarTypeSolver.packagesJarMappings)
if jdkJarTypeSolver != null then (symbolSolver, jdkJarTypeSolver.packagesJarMappings)
else (symbolSolver, null)
end createSymbolSolver

private def recursiveJarsFromPath(path: String): List[String] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ class AstCreator(
.signature(signature)
val typeNameLookup =
methodFullName.takeWhile(_ != ':').split("\\.").dropRight(1).mkString(".")
if packagesJarMappings.contains(typeNameLookup) then
if packagesJarMappings != null && packagesJarMappings.contains(typeNameLookup) then
methodNode.astParentType(packagesJarMappings.getOrElse(
typeNameLookup,
mutable.Set.empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class SimpleCombinedTypeSolver extends TypeSolver:
// RecordDeclarations aren't handled by JavaParser yet
None
case unhandled: Throwable =>
logger.debug("Caught unhandled exception", unhandled)
None
}
.collectFirst { case Some(symbolReference) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ class JdkJarTypeSolver extends TypeSolver:
archivePaths.foreach { archivePath =>
addPathToClassPool(archivePath) match
case Success(_) => registerPackagesForJar(archivePath)

case Failure(e) =>
logger.debug(s"Could not load jar at path $archivePath", e.getMessage)
}

private def registerPackagesForJar(archivePath: String): Unit =
Expand All @@ -114,11 +112,6 @@ class JdkJarTypeSolver extends TypeSolver:
}
catch
case ioException: IOException =>
logger.debug(
s"Could register classes for archive at $archivePath",
ioException.getMessage
)
end try
end registerPackagesForJar
end JdkJarTypeSolver

Expand All @@ -136,11 +129,8 @@ object JdkJarTypeSolver:

def fromJdkPath(jdkPath: String): JdkJarTypeSolver =
val jarPaths = SourceFiles.determine(jdkPath, Set(JarExtension, JmodExtension))
if jarPaths.isEmpty then
throw new IllegalArgumentException(
s"No .jar or .jmod files found at JDK path ${jdkPath}"
)
new JdkJarTypeSolver().withJars(jarPaths)
if jarPaths.nonEmpty then new JdkJarTypeSolver().withJars(jarPaths)
else new JdkJarTypeSolver()

/** Convert JavaParser class name foo.bar.qux.Baz to package prefix foo.bar Only use first 2
* parts since this is sufficient to deterimine whether a class has been registered in most
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,39 @@ object Delombok:
val javaPath = analysisJavaHome.getOrElse(systemJavaPath)
val classPathArg = Try(File.newTemporaryFile("classpath").deleteOnExit()) match
case Success(file) =>
// Write classpath to a file to work around Windows length limits.
file.write(System.getProperty("java.class.path"))
s"@${file.canonicalPath}"

if System.getProperty("java.class.path").nonEmpty then
// Write classpath to a file to work around Windows length limits.
file.write(System.getProperty("java.class.path"))
s"@${file.canonicalPath}"
else System.getProperty("java.class.path")
case Failure(t) =>
logger.debug(
s"Failed to create classpath file for delombok execution. Results may be missing on Windows systems",
t
s"Failed to create classpath file for delombok execution. Results may be missing on Windows systems"
)
System.getProperty("java.class.path")
s"$javaPath -cp $classPathArg lombok.launch.Main delombok . -d ${tempDir.canonicalPath}"
if classPathArg.nonEmpty then
s"$javaPath -cp $classPathArg lombok.launch.Main delombok . -d ${tempDir.canonicalPath}"
else ""

def run(projectDir: String, analysisJavaHome: Option[String]): String =
Try(File.newTemporaryDirectory(prefix = "delombok").deleteOnExit()) match
case Success(tempDir) =>
ExternalCommand.run(
delombokToTempDirCommand(tempDir, analysisJavaHome),
cwd = projectDir
) match
case Success(_) =>
tempDir.path.toAbsolutePath.toString
val externalCommand = delombokToTempDirCommand(tempDir, analysisJavaHome)
if externalCommand.nonEmpty then
ExternalCommand.run(
externalCommand,
cwd = projectDir
) match
case Success(_) =>
tempDir.path.toAbsolutePath.toString

case Failure(t) =>
logger.debug(s"Executing delombok failed", t)
logger.debug(
"Creating AST with original source instead. Some methods and type information will be missing."
)
projectDir
case Failure(t) =>
logger.debug(s"Executing delombok failed", t)
logger.debug(
"Creating AST with original source instead. Some methods and type information will be missing."
)
projectDir
else ""

case Failure(e) =>
logger.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ object SourceParser:
config.delombokMode,
hasLombokDependency
)

new SourceParser(Path.of(canonicalInputPath), Path.of(analysisDir), Path.of(typesDir))

def getSourceFilenames(
Expand Down Expand Up @@ -126,18 +125,19 @@ object SourceParser:
hasLombokDependency: Boolean
): (String, String) =
lazy val delombokDir = Delombok.run(originalDir, delombokJavaHome)
if delombokDir.nonEmpty then
Delombok.parseDelombokModeOption(delombokMode) match
case Default if hasLombokDependency =>
logger.debug(s"Analysing delomboked code as lombok dependency was found.")
(delombokDir, delombokDir)

Delombok.parseDelombokModeOption(delombokMode) match
case Default if hasLombokDependency =>
logger.debug(s"Analysing delomboked code as lombok dependency was found.")
(delombokDir, delombokDir)

case Default => (originalDir, originalDir)
case Default => (originalDir, originalDir)

case NoDelombok => (originalDir, originalDir)
case NoDelombok => (originalDir, originalDir)

case TypesOnly => (originalDir, delombokDir)
case TypesOnly => (originalDir, delombokDir)

case RunDelombok => (delombokDir, delombokDir)
case RunDelombok => (delombokDir, delombokDir)
else (delombokDir, delombokDir)
end getAnalysisAndTypesDirs
end SourceParser
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "appthreat-chen"
version = "2.0.2"
version = "2.0.3"
description = "Code Hierarchy Exploration Net (chen)"
authors = ["Team AppThreat <cloud@appthreat.com>"]
license = "Apache-2.0"
Expand Down

0 comments on commit 812f317

Please sign in to comment.