EN JP CN

チュートリアル 3 - カスタム関数を使用した C/C++ KAST チェッカーの作成

チュートリアル 3 - カスタム関数を使用した C/C++ KAST チェッカーの作成

チュートリアル 3 - カスタム関数を使用した C/C++ KAST チェッカーの作成

チュートリアル 3 - カスタム関数を使用した C/C++ KAST チェッカーの作成

このチュートリアルでは、カスタム関数を使用した C/C++ KAST チェッカーの作成方法について説明します。このチュートリアルは、Checker Studio と、チュートリアル 1 - C/C++ KAST チェッカーの作成によるチェッカー作成の基本プロセスに精通していることを前提としています。また、前のチュートリアルを読み返すかまたは実行しておく必要があります。チュートリアル 2 - 組み込み関数を使用した C/C++ KAST チェッカーの作成

--kast-library オプションを設定して kwcreatechecker を実行する

カスタム関数の例として、次のコマンドを実行します。

kwcreatechecker --language cxx --type kast --kast-library foo --code C.KAST.CUST.FUNC
注: エラー ID (チェッカー名) では、マルチバイト文字はサポートされていません。また、255 文字までという制限があります。

結果

--code で指定した名前で C.KAST.CUST.FUNC というディレクトリが作成されます。このディレクトリには以下が含まれます。

  • チェッカー設定ファイル (checkers.xmlhelp.xml)
  • テストケースサンプル (testcase.cc)
  • build file (ビルドファイル) (Makefile)
  • プラグインソースファイル (PluginSource.cpp)

テストケースを追加する

KAST 式 (カスタム関数を含む) をテストするには、C.KAST.CUST.FUNC ディレクトリの testcase.cc ファイルに以下を追加します。

int main() {

   int* x;

//Reporting ckastcustfunc  
   x = 0;  
   cin >> x;
 
   return 0;

}

Checker Studio を使用して目的のノードを検索する

  1. デスクトップで Checker Studio アイコンをダブルクリックするか、コマンドラインで以下を実行します。
    kwstudio
    
  2. 抜粋を Checker Studio の [ソースコード] セクションに貼り付けます。
    KAST 式の構成要素を取得するには、KAST ノード名、コード例、および階層情報を表示します。
  3. [ソースコード] ペインで x = 0; をクリックします。
    抽象構文ツリーで ExprStmt がハイライトされます。ExprStmt は、ツリーに 1 つの子 BinaryExpr を持っています。
  4. "=" 記号をクリックします。
    ツリーで BinaryExpr ノードがハイライトされ、その属性が [属性] ペインに表示されます。
    Image:test_case_cust_func.png

Checker Studio の使用の詳細については、チュートリアル 1 - C/C++ KAST チェッカーの作成を参照してください。

KAST 式のドラフトを作成する

Checker Studio で特定したノードを使用して、KAST 式のドラフトを作成するためのテストファイルを作成します。たとえば、KAST 式は次のとおりです。

// ExprStmt / Expr::BinaryExpr [ @Op = KTC_OPCODE_ASR ] [ getMostleftArg().isCin() ] [ Right.isPointer() | Right.isArray() ]

この式には、次の 2 つのカスタム関数があります。

  • getMostleftArg
  • isCin

C/C++ KAST 構文リファレンスも参照してください。

プラグインソースを PluginSource.cpp ファイルに追加する

このステップでは、カスタム関数とその戻り値型を PluginSource.cpp ファイルに追加します。

各プラグイン関数には名前が関連付けられている必要があります。 KAST チェッカーではこの名前を呼び出しに使用します。

PluginSource.cpp ファイルを開きます。この例では、このファイルは C.KAST.CUST.FUNC ディレクトリにあります。

ファイルのデフォルトコンテンツは次のとおりです。

# include <XPath_plugins.h>

# include <ktcAPI.h> int my_int_func(ktc_tree_t node) {

...

} ktc_tree_t my_tree_func(ktc_tree_t node) {

...

} HOOKS_SET_START

XPath_register_int_hook("myInt", my_int_func);
XPath_register_tree_hook("myTree", my_tree_func);

HOOKS_SET_END

プラグイン関数

プラグイン関数には、タイプ 'ktc_tree_t' を持ち、整数値 (int hook) またはタイプ 'ktc_tree_t' のポインター (tree hook) を返す単一のパラメーターが必要です。

関数がブール値関数として使用される場合は、false の場合はゼロ、true の場合は非ゼロを返す必要があります。KAST チェッカーでカスタム関数を呼び出す場合、'tree' タイプの単一の引数を指定することができますが、引数をまったく指定しない場合もあります。後者の場合、現在のノードが処理されます。

注: 使用しない戻り値型テンプレートは削除することも、希望どおりに順序変更することもできます。

例:"int" の関数の戻り値型

KAST 式にはカスタム関数 isCin および getMostleftArg が含まれます。

// ExprStmt / Expr::BinaryExpr [ @Op = KTC_OPCODE_ASR ] [ getMostleftArg().isCin() ] [ Right.isPointer() | Right.isArray() ]

isCin カスタム関数の戻り値型は整数 (int) 型であるため、PluginSource.cpp ファイルの整数値には、以下を使用します。

int is_cin_function(ktc_tree_t node) {    
   if (ktc_is_IdExpr(node)) {      
      char *name = (char *)ktc_getIdentifier(node);       
      if (name && ! strcmp(name, "cin"))            
         return 1;   
   }   
   return 0;
}

例:ポインター 'ktc_tree_t' の関数の戻り値型

KAST 式にはカスタム関数 getMostleftArg も含まれます。これには ktc_tree_t の戻り値型があるので、以下を PluginSource.cpp の ktc_tree_t テンレートに追加します。

ktc_tree_t get_mostleft_arg_function(ktc_tree_t node) {    
   int isBinary = ktc_is_BinaryExpr(node);    
   if (! isBinary)        
      return 0;    
   do {        
      node = ktc_proceed(node, cid_Left);    
   } while(ktc_is_BinaryExpr(node));    
   return node;
}

カスタム関数を登録する

すべての関数登録は、HOOKS_SET_START マクロと HOOKS_SET_END マクロの間に配置されます。KAST 式内の両方のカスタム関数を登録する必要があります。

例:isCin と getMostleftArg の登録

HOOKS_SET_START
XPath_register_int_hook("isCin", is_cin_function);
XPath_register_tree_hook("getMostleftArg", get_mostleft_arg_function);

HOOKS_SET_END

:次に checkers.xml ファイルを更新します。

checkers.xml ファイルを更新する

KAST 式を checkers.xml ファイルの <pattern> タグに追加します。このファイルには、カスタムチェッカーの正確なタイトルとメッセージも含める必要があります。

  1. 好みのエディターで checkers.xml ファイルを開きます。この例では、このファイルは C.KAST.CUST.FUNC/checkers.xml にあります。

ファイルが生成されると、その値にはエラー ID、重要度、メッセージ、タイトル、およびサンプル KAST 式が自動的に指定されます。このファイル内のタグの詳細については、「checkers.xml:チェッカー設定」を参照してください。

  1. <pattern> タグを探します。
  2. サンプル KAST 式を KAST 式で置換します。
    ExprStmt / Expr::BinaryExpr [ @Op = KTC_OPCODE_ASR ] [ getMostleftArg().isCin() ] [ Right.isPointer() | Right.isArray() ]
  3. さらに、必要に応じて <error> ノードの属性を編集することもできます。このチュートリアルでは、タイトル属性を C_KAST_Custom_Function に、メッセージ属性を dangerous input stream usage に変更します。
  4. ファイルを保存します。

チェッカーのヘルプを作成する

help.xml ファイル内のカスタムチェッカーのドキュメンテーションを追加します。このファイルは、kwcreatechecker--code オプションで指定したディレクトリにあります。

最小限でも <description> タグ内に指摘の説明を入力する必要があります。

例については、チュートリアル 1 - C/C++ KAST チェッカーの作成を参照してください。

チェッカーをビルドする

Unix:

make install buildspec

Windows: Visual Studio プロンプトから以下を実行します。

nmake install buildspec
ヒント: これは make buildspecmake install (Windows では nmake buildspecnmake install) の 2 つのコマンドを実行することと同等です。

これによって、以下が生成されます。

  • C.KAST.CUST.FUNC.zip というファイル
  • コンパイル済みのチェッカーをテストするための build specification (ビルドスペック) ファイル

チェッカーをテストする

  1. 選択したディレクトリにアーカイブファイルを解凍します。
    ヒント:チェッカースタブファイルを作成した同じディレクトリにアーカイブファイルを解凍することもできます。
    C/C++ チェッカーがプラットフォーム固有の場合は、xml ファイルを <username>/.klocwork/<plugins>/<platform-name> にコピーします。
    サーバー プロジェクト レベルでチェッカーを展開する準備が完了したら、デスクトップからチェッカーをアンインストールします。
    詳細については、デスクトップへのチェッカーパッケージの展開を参照してください。
  2. 同じディレクトリに次のようにローカルプロジェクトを設定します。
    kwcheck create -b <build_specification>
    
    フィールド、<build_specification> は make install buildspec または nmake install buildspecを使用して作成されました。
  3. 次のように kwcheck を実行して、テストケースで指摘が検出されたかどうか確認します。
    kwcheck run
    
    チェッカーはテストケースから指摘を検出します。
  4. 結果に満足した段階で、チェッカーをサーバーに展開できます。