
これはオープンソースコード解析プラットフォーム Joern の中央クエリデータベースです。目的は2つあります:
クエリデータベースは、Joernを依存関係として含むスタンドアロンライブラリとして配布されます。つまり、データベース内のクエリを利用するためにJoernをインストールする必要はありません。
同時に、データベースはJoernの拡張機能であり、起動時に動的にロードされると、その機能がインタラクティブなJoernシェルやJoernスクリプトで利用可能になります。
このプロジェクトをフォークして独自のカスタムクエリやスキャナを構築するか、このリポジトリにPRを送ってデフォルト配布に含めることを検討してもらうこともできます。
インストールスクリプトはjoernをダウンロードし、サブディレクトリにインストールします。クエリデータベースは拡張機能としてインストールされます。
./install.sh
すべてのクエリを次のように実行できます:
./joern-scan path/to/code
例:
mkdir foo
echo "int foo(int a, int b, int c, int d, int e, int f) {}" > foo/foo.c
./joern-scan foo
これはディレクトリ foo 内のサンプルコードに対してすべてのクエリを実行し、関数 foo のパラメータが多すぎることを検出します。
ストレスフリーなクエリ作成体験のために、以下のルールに従ってください:
io.joern.scanners 内のクエリは実行時に自動的に認識されるので、クエリはそこに配置してください。@q で始まり、クエリバンドル内に配置する必要があります。クエリバンドルとは、単に QueryBundle を継承した object です。sbt scalafmt Test/scalafmt を使用してコードをフォーマットしてください。例として、src/main/scala/io/joern/scanners/c/Metrics.scala にあるクエリバンドル Metrics を見てください:
object Metrics extends QueryBundle {
@q
def tooManyParameters(n: Int = 4): Query =
Query.make(
name = "too-many-params",
author = Crew.fabs,
title = s"Number of parameters larger than $n",
description = s"This query identifies functions with more than $n formal parameters",
score = 1.0,
withStrRep({ cpg =>
cpg.method.internal.filter(_.parameter.size > n)
}),
tags = List(QueryTags.metrics)
)
@q
def tooHighComplexity(n: Int = 4): Query =
Query.make(
name = "too-high-complexity",
author = Crew.fabs,
title = s"Cyclomatic complexity higher than $n",
description = s"This query identifies functions with a cyclomatic complexity higher than $n",
score = 1.0,
withStrRep({ cpg =>
cpg.method.internal.filter(_.controlStructure.size > n)
}),
tags = List(QueryTags.metrics)
)
...
}
クエリの対応するテストは src/test/scala/io/joern/scanners にあります。例えば、メトリクスクエリのテストは src/test/scala/io/joern/scanners/c/MetricsTests.scala にあります:
class MetricsTests extends Suite {
override val code = """
int too_many_params(int a, int b, int c, int d, int e) {
}
...
"""
"find functions with too many parameters" in {
Metrics.tooManyParameters(4)(cpg).map(_.evidence) match {
case List(List(method: nodes.Method)) =>
method.name shouldBe "too_many_params"
case _ => fail
}
}
...
}
これらのテストは、クエリ開発中にIntelliJ IDEから個別に実行できます。
Scala Build Tool (sbt) を使用します。sbtがインストールされていることを確認してください。バージョンは重要ではありません。sbtはビルドファイル (build.sbt) に基づいて必要なバージョンを取得します。
sbt がインストールされたら、次のようにデータベースをビルドおよびテストできます:
sbt test
新しく開発したクエリをテストするには
新しく作成したクエリを joern-scan でテストするには、次のようにします:
sbt joerncli/stage
./querydb-install.sh && ./joern-scan <src>
install.sh を実行した後、次のコマンドを起動できます:
./joern-scan --dump
これにより、利用可能なすべてのクエリとそのメタ情報を含む querydb.json というファイルが作成されます。