AviUtlプラグインを作る時GetFilterTableListの戻り値に注意せよ

  • 1
    Like
  • 0
    Comment
More than 1 year has passed since last update.

正直AviUtlのプラグイン作成は詳しくないけど
https://github.com/MaverickTse/SigContrastFastAviUtl
に関わってて気がついたこととしてメモしておく。

現象

プラグイン情報構造体初期化
FILTER_DLL scon_en = {               // English UI filter info
    //  filter flags, use bitwise OR to add more
    //  FILTER_FLAG_ALWAYS_ACTIVE       //: フィルタを常にアクティブにします
    //  FILTER_FLAG_CONFIG_POPUP        //: 設定をポップアップメニューにします
    //  FILTER_FLAG_CONFIG_CHECK        //: 設定をチェックボックスメニューにします
    //  FILTER_FLAG_CONFIG_RADIO        //: Only one of the checkboxes can be ticked at one time.
    //  FILTER_FLAG_EX_DATA             //: 拡張データを保存出来るようにします。
    //  FILTER_FLAG_PRIORITY_HIGHEST    //: Make this plugin highest priority(i.e. always run before other filters)
        FILTER_FLAG_PRIORITY_LOWEST     //: Make this plugin lowest priority
    //  FILTER_FLAG_WINDOW_THICKFRAME   //: user-draggable dialog box
    //  FILTER_FLAG_WINDOW_SIZE         //: Custom dialogbox size (size defined in argument 2 and 3)
    //  FILTER_FLAG_DISP_FILTER         //: 表示フィルタにします
    |   FILTER_FLAG_EX_INFORMATION      //: フィルタの拡張情報を設定できるようにします
    //  FILTER_FLAG_NO_CONFIG           //: 設定ウィンドウを表示しないようにします
    //  FILTER_FLAG_AUDIO_FILTER        //: オーディオフィルタにします
    //  FILTER_FLAG_RADIO_BUTTON        //: チェックボックスをラジオボタンにします
    //  FILTER_FLAG_WINDOW_HSCROLL      //: 水平スクロールバーを持つウィンドウを作ります
    //  FILTER_FLAG_WINDOW_VSCROLL      //: 垂直スクロールバーを持つウィンドウを作ります
    //  FILTER_FLAG_IMPORT              //: インポートメニューを作ります
    //  FILTER_FLAG_EXPORT              //: エクスポートメニューを作ります
    ,
    0, 0,                       //  dialogbox size
    PLUGIN_NAME_SCON,           //  Filter plugin name
    TRACK_N,                    //  トラックバーの数 (0なら名前初期値等もNULLでよい)
    en_name,                    //  slider label names in English
    track_default,              //  トラックバーの初期値郡へのポインタ
    track_s, track_e,           //  トラックバーの数値の下限上限 (NULLなら全て0~256)
    CHECK_N,                    //  チェックボックスの数 (0なら名前初期値等もNULLでよい)
    check_name_en,                  //  チェックボックスの名前郡へのポインタ
    check_default,              //  チェックボックスの初期値郡へのポインタ
    func_proc_con,                  //  main filter function, use NULL to skip
    func_init_con,                      //  initialization function, use NULL to skip
    func_exit_con,                      //  on-exit function, use NULL to skip
    func_update_con,                        //  invokes when when settings changed. use NULL to skip
    func_WndProc_con,                       //  for capturing dialog's control messages. Essential if you use button or auto uncheck some checkboxes.
    NULL, NULL,                 //  Reserved. Do not use.
    NULL,                       //  pointer to extra data when FILTER_FLAG_EX_DATA is set
    NULL,                       //  extra data size
    VERSION_STR_SCON,
    //  pointer or c-string for full filter info when FILTER_FLAG_EX_INFORMATION is set.
    func_save_start_con,                        //  invoke just before saving starts. NULL to skip
    NULL,                       //  invoke just after saving ends. NULL to skip
};

こういう構造体を作って

登録
FILTER_DLL* pluginlist[] = { &scon_en, &sdecon_en };
// Export the above filter table
EXTERN_C  __declspec(dllexport) FILTER_DLL** GetFilterTableList(void)
{

    return pluginlist;
}

こんな風に登録するごくごくありきたりなプログラムを書いていました。

ところが

img

WM_COMMANDが来てかつwparam50344749のときのプロージャーが呼ばれた直後、AviUtl内部でバグります。

対策

GetFilterTableListの戻り値に利用する配列は必ずNULL終端させましょう

登録
FILTER_DLL* pluginlist[] = { &scon_en, &sdecon_en, nullptr };//NULL終端させる!
// Export the above filter table
EXTERN_C  __declspec(dllexport) FILTER_DLL** GetFilterTableList(void)
{

    return pluginlist;
}

つまりは単なるバッファオーバーラン。