Grundlegende Syntax von CodeQL-Notizen (1)


Vorwort

      Erfahren Sie, wie Sie CodeQL für die Java-Codeprüfung verwenden. Enthält einige Konzepte und Beispiele.


Grundlegende CodeQL-Syntax

     CodeQL verwendet eine Parsing-Engine, um die Projekte, die wir prüfen müssen, in eine Datenbank zu analysieren. Beachten Sie, dass die Datenbank hier in eine Datenbank der mittleren Ebene konvertiert wird, die CodeQL erkennen kann. Da die Kernanalyse-Engine nicht Open Source ist, wird eine Zwischendatenbank generiert. Dann können wir relevante QL-Regeln schreiben, und dann findet die CodeQL-Engine Daten, die die Bedingungen in der Datenbank gemäß den Regeln erfüllen, und wir können sie dann analysieren.

1. Grammatische Struktur

     1) Die Syntaxstruktur der QL-Abfrage ist:

from [datatype] var  /* ... 变量声明... */
where condition(var = something)   /* ... 逻辑公式 ... */
select var    /* ... 表达式 ... */

     2) Ein kleines Beispiel ist die Ausgabe von i unter allen ganzen Zahlen i, wenn i==1.

// 表示我们要引入CodeQL的类库,因为我们分析的项目是java的,所以在ql语句里,必不可少
import java

// 表示我们定义一个变量i,它的类型是int,表示我们获取所有的int类型的数据
from int i
// 表示当i等于1的时候,符合条件
where i = 1
// 表示输出i
select i

Fügen Sie hier eine Bildbeschreibung ein
     3) Sie können auch die offizielle Plattform nutzen, um das Schreiben einiger Regeln zu üben. LGTM-Abfragekonsole: https://lgtm.com/query
Fügen Sie hier eine Bildbeschreibung ein

2. Klassenbibliothek

     1) Die CodeQL-Parsing-Engine konvertiert den Projektcode, den wir prüfen müssen, in eine AST-Datenbank, die von CodeQL erkannt werden kann. Das Format ist wie folgt. Es ist ersichtlich, dass es im Allgemeinen zwei Ebenen gibt: eine ist das importierte Paket und die andere ist die Klasse. Unterhalb der Klasse befinden sich einige Methoden, Eigenschaften usw. Die Klassenbibliothek ist tatsächlich die entsprechende Beziehung des obigen AST.
Fügen Sie hier eine Bildbeschreibung ein
     2) Wenn Sie beispielsweise die Methoden in allen Klassen abrufen möchten, bedeutet Methode in AST, dass alle Methoden im aktuellen Projekt abgerufen werden. Wie folgt:

import java

from Method method
select method

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
     3) Aktualisieren Sie es und filtern Sie die Ergebnisse mithilfe einiger in die Method-Klasse integrierter Methoden. Rufen Sie beispielsweise den Methodennamen get ab.

import java
 
from Method method
where method.hasName("get")
/**
method.getName() 获取的是当前方法的名称
method.getDeclaringType() 获取的是当前方法所属class的名称。
**/
select method.getName(), method.getDeclaringType()

Fügen Sie hier eine Bildbeschreibung ein

3. Prädikat

     1) Prädikate werden verwendet, um die logischen Beziehungen zu beschreiben, die ein QL-Programm ausmachen. Vom Konzept her ähnelt es einer Funktion. Persönlich verstehe ich aus der offiziellen Dokumentation, dass das Prädikat ein Ein-Element-Array oder ein Zwei-Element-Array ist. Die Set-Prädikatarität eines Ein-Element-Arrays ist eins und die Set-Prädikatarität eines Zwei-Element-Arrays ist zwei. Normalerweise haben alle Tupel in einem Prädikat die gleiche Anzahl von Elementen. Die Anzahl der Prädikate ist die Anzahl der Elemente, ausgenommen mögliche Ergebnisvariablen. Es gibt viele integrierte Prädikate in QL. Sie können sich auf die offizielle Dokumentation beziehen: https://codeql.github.com/docs/ql-sprache-reference/ql-sprache-spezifikation/#built-ins.
     2) Definieren Sie eine Prädikatbedingung:

  • Schlüsselwortprädikat erforderlich
  • Es ist eine Kennung erforderlich, die mit einem Kleinbuchstaben beginnt, zum Beispiel: isCountry
  • Definieren Sie Parameter, verbinden Sie mehrere Parameter mit Kommas. Für jeden Parameter müssen Sie den Parametertyp und die Kennung der Parametervariablen angeben.
  • Das Prädikat selbst ist in große geschweifte Klammern „{ }“ eingeschlossen.

     3) Offizielles Beispiel:

predicate isCountry(string country) {
    
    
  country = "Germany"
  or
  country = "Belgium"
  or
  country = "France"
}

predicate hasCapital(string country, string capital) {
    
    
  country = "Belgium" and capital = "Brussels"
  or
  country = "Germany" and capital = "Berlin"
  or
  country = "France" and capital = "Paris"
}

     4) Das obige Beispiel für die Abfrage von get kann auch wie folgt umgeschrieben werden.

import java
 
predicate isGet(Method method) {
    
    
exists(|method.hasName("get"))
}
 
from Method method
where isGet(method)
select method.getName(), method.getDeclaringType()
语法解释:
predicate 表示当前方法没有返回值。
exists子查询,是CodeQL谓词语法里非常常见的语法结构,它根据内部的子查询返回true or false,
来决定筛选出哪些数据。

Fügen Sie hier eine Bildbeschreibung ein
     5) Prädikate können in Prädikate mit Ergebnissen und Prädikate ohne Ergebnisse unterteilt werden. Der Unterschied besteht darin, ob die spezielle Variable result eingeführt wird. Wenn ein Ergebnis vorhanden ist, kann es das Prädikat ersetzen. Siehe den offiziellen Fall:

// 无结果的谓词 
predicate isSmall(int i) {
    
    
  i in [1 .. 9]
}
// 如果i是正整数并且小于10,则isSmall(i)成立。


// 有结果的谓词 
int getSuccessor(int i) {
    
    
  result = i + 1 and
  i in [1 .. 9]
}

// 如果i是正整数并且小于10,则这个谓词的结果就是接替i

4. Grundlegende Datentypen und ihre integrierten Funktionen

     1) Grundlegende Datentypen in der QL-Sprache, einschließlich Ganzzahl-, Gleitkomma-, Datums-, Boolescher- und Zeichenfolgentypen. Es ist zu beachten, dass für die QL-Sprache alle von ihr unterstützten Datentypen über entsprechende integrierte Funktionen verfügen. Laienhaft ausgedrückt sind die Funktionen, die das System für uns geschrieben hat, Prädikate, und wir können sie direkt verwenden.
     2) Wenn wir beispielsweise den Absolutwert einer Ganzzahl ermitteln möchten, können wir die integrierte Funktion abs() direkt aufrufen, z. B. 1.abs().
Fügen Sie hier eine Bildbeschreibung ein
     2) Wenn wir einen bestimmten Variablentyp aufrufen möchten, lautet die allgemeine Form: Fügen Sie direkt nach der Variablen einen Punkt hinzu und fügen Sie dann die aufzurufende integrierte Funktion hinzu. Gleichzeitig können wir auch mehrere Funktionen durch Punkte in Reihe schalten, d dieser Prozess Für: s.abs().sqrt().
Fügen Sie hier eine Bildbeschreibung ein
     3) String-Typ, ähnlich wie in anderen Sprachen.

from string s
where s = "he\"llo"
select s

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
     4) Ganzzahl- und Gleitkommatypen.

from float a, int b
where a = 5.3 and b = 2
// pow的作用就是参数的几次幂  下方例子就是5.3的2次幂
select a.pow(b)

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
     5) Datumstyp. Schreiben Sie eine Abfrage, um zu berechnen, wie viele Tage seit der ersten Wuhan-Epidemie vergangen sind.

from date start, date now
// toDate()作用就是将指定的字符串转换为日期值
where start = "1/12/2019".toDate() and now = "25/10/2022".toDate()
select start.daysTo(now)

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Ich denke du magst

Origin blog.csdn.net/qq_44029310/article/details/127387768
Empfohlen
Rangfolge