Skip to content

Bug: jssrc2cpg produces an empty CPG when a single file is provided as input #47

@n0isy

Description

@n0isy

Description

When running joern-parse (which invokes jssrc2cpg) on a single JavaScript or TypeScript file, the process completes without any apparent errors, but the resulting CPG is empty (contains no AST from the source file).

This behavior is counter-intuitive, as users expect to be able to analyze a single file. Other Joern frontends typically support this workflow. The current implementation silently fails, which can be confusing.

Expected Behavior:
Running joern-parse my_file.js should produce a valid CPG containing the AST for my_file.js.

Actual Behavior:
Running joern-parse my_file.js produces an empty CPG. No error message is displayed to the user indicating why the file was not processed.

Steps to Reproduce

  1. Create a simple JavaScript file:
    echo "console.log('Hello, World!');" > test.js
  2. Run joern-parse on the single file:
    joern-parse test.js
  3. Observe the output. The process will finish successfully.
  4. Inspect the generated CPG:
    joern
    joern> importCpg("cpg.bin.zip")
    joern> cpg.file.name.l
    // Result: List()
    joern> cpg.method("log").size
    // Result: 0
    The CPG is effectively empty.

Root Cause Analysis

The issue stems from the interaction between jssrc2cpg's AstGenRunner (in Scala) and the astgen tool (in TypeScript).

  1. The jssrc2cpg's AstGenRunner.scala receives the single file path as its inputPath.
  2. It then attempts to execute the astgen binary by setting the workingDir of the external command to this inputPath.
    // jssrc2cpg/utils/AstGenRunner.scala
    private def jsFiles(in: Path, out: Path): Try[Seq[String]] = {
      ExternalCommand
        .run((astGenCommand +: executableArgs) ++ Seq("-t", "ts", "-o", out.toString), workingDir = Option(in))
        .toTry
    }
  3. An operating system process cannot have a file as its working directory; it must be a directory. This causes the ExternalCommand.run to fail.
  4. The failure is caught by a Try, and jssrc2cpg proceeds to look for generated JSON files. Since astgen never ran, no JSON files are found, and an empty CPG is produced.
  5. The underlying astgen tool itself appears to be designed to scan a directory provided via the --src option (or the current working directory by default) rather than accepting a single file path as a primary argument.

Proposed Solution(s)

  • Modify astgen to accept one or more file paths directly as positional arguments or via a new flag.
  • If file paths are provided, astgen should process only those files, bypassing the directory scanning logic in FileUtils.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions