13

aBSTRはコードベースのaにすぎないtypedefためwchar_t*、文字列リテラルがメソッドに渡される場所がいくつか(多く?)あります。BSTRこれは、マーシャラーや特定のメソッドを使用しようとする人BSTR(たとえばSysStringLen)を混乱させる可能性があります。

このタイプの誤用を静的に検出する方法はありますか?

/WallVC10と静的コード分析のMicrosoftAllRulesを使用してコンパイルしようとしましたが、次の問題のあるコードはどちらからもフラグが付けられません。

void foo(BSTR str)  
{
    std::cout << SysStringLen(str) << std::endl; 
}

int _tmain()
{
    foo(L"Don't do that");
}

更新:wtypes.h私が諦めたこれらの種類の違反を検出するために破壊しようとした後。

2つのパスを試しましたが、どちらも上記のサンプルプログラムで作業することができましたが、実際のプロジェクトを試すと失敗しました。

  1. 名前の付いたクラスを作成しますBSTRが、はユニオンメンバーとしてをVARIANT持っているBSTRため、新しいクラスにはコンストラクターや代入演算子を含めることができませんでした。これはすべての場所で壊れ、NULLとして扱われましたBSTR。変換演算子を持つ型に置き換えようとしましNULLたが、数十の新しい演算子(比較、変換など)を追加した後、あいまいな呼び出しに遭遇し、あきらめました。
  2. 次に、@ CashCowと@Hansによって提案された方法を試しました(BSTRtypedefのタイプのポインターを作成します)。これも機能しませんでした。メソッドを追加toBSTRし、comutil.h()やその他の場所を変換して散らかした後、コンパイラがIDLから生成されたヘッダーをチョークするようになりました(デフォルト値はリテラル幅の文字列に変換されます)。fromBSTR_bstr_t

要するに、私は自分でこれを達成しようとすることをあきらめました。誰かがそれについて聞くのを助けることができるコード分析ツールを知っているなら、私はそれについて聞いてとてもうれしいです。

4

4 に答える 4

4

Coverityは、この種の脆弱性を検出すると主張していると思います。彼らが私が働いていた会社にデモをしたときに、特にCOMのことについて言及したことを覚えています。

彼らのデータシートは確かに彼らが不適切なBSTR使用のクラスをチェックすることを暗示しているようです。デモ期間があります。それを試して、サンプル入力にフラグが立てられるかどうかを確認できます。

于 2012-03-08T00:56:21.790 に答える
1

代わりに_bstr_tまたはCComBSTRを使用するようにメソッドを変更できますか?

そうでない場合、リテラルは技術的にはconst wchar_t *であり、literal-> non-constポインター変換を許可しないコンパイラ設定がある場合は、それを行うことができます。

これに失敗すると、BSTRの定義をunsignedshort*に変更する可能性があります。次に、すべてのソースをビルドすると、リテラルが渡される場所でコンパイラエラーが発生し、このすべてのコードを修正できます。次に、元に戻すことをお勧めします...

于 2012-01-24T12:19:37.250 に答える
1

Clangでコンパイルしてみてください。静的/動的分析により、探しているものが見つかる場合があります。

于 2012-02-03T19:56:13.730 に答える
0

すべての関数をBSTRでオーバーロードし、適切な変換で転送します。

void foo( BSTR str )
{
    std::cout << SysStringLen(str) << std::endl; 
}

void foo( const WCHAR *str )
{
    foo( SysAllocString( str ));
}

int _tmain()
{
    foo( L"don't do this" );
    return 0;
}

または、コンパイラエラーを生成するには、すべてのパラメータタイプをBSTRから別のものに変更し、エラーを探します。

typedef UINT bar;

void foo( bar _str )
{
    // make the compiler happy below
    BSTR str = (BSTR)_str;
    std::cout << SysStringLen(str) << std::endl;
}

int _tmain()
{
    foo( L"don't do this" );
    foo( (bar)42 );
    return 0;
}

エラーC2664:'foo':パラメータ1を'constwchar_t[14]'から'bar'に変換できません

C2664エラーとコンパイラーによって識別された'constwchar_t []'タイプは、BSTRを使用して関数に対して行われたすべての内部呼び出しに対してコンパイラーが検出するものであると思いますか?

于 2012-02-01T20:56:22.273 に答える