Поскольку BSTR
лишь typedef
для wchar_t*
наш код базы имеет несколько (много?) Места, где строковые литералы передаются методу, ожидающей BSTR
это может испортить с marshallers или любой, кто пытается использовать какой-либо конкретный метод BSTR
(например, SysStringLen
).Статический анализ кода для обнаружения прохождения wchar_t * в BSTR
Есть ли способ статического обнаружения такого рода злоупотреблений?
Я попытался компиляции с VC10 /Wall
и статического анализа кода Microsoft Все правила но следующий обижая часть кода не получает помечено либо из них.
void foo(BSTR str)
{
std::cout << SysStringLen(str) << std::endl;
}
int _tmain()
{
foo(L"Don't do that");
}
Update: После попытки хулиганить wtypes.h
в обнаружении такого рода проступки я отказавших.
Я пробовал два пути, оба из которых я получил, чтобы работать с моей примерной программой выше, но как только я попробовал настоящий проект, они потерпели неудачу.
- создать класс с именем
BSTR
, но так какVARIANT
имеетBSTR
в качестве члена профсоюза нового класс не может иметь никаких конструкторов или оператор присваивания это нарушившие каждое место былоNULL
трактовалось какBSTR
. Я попытался заменитьNULL
на тип, в котором есть операторы преобразования, но после добавления десятков новых операторов (сравнение, преобразование и т. Д.) Я начал сталкиваться с неоднозначными вызовами и сдавался. - Затем я попробовал путь, предложенный @CashCow и @Hans (составление
BSTR
atypedef
другому типу указателя). Это также не сработало, после добавления методовtoBSTR
иfromBSTR
и засорения comutil.h (_bstr_t
) и в других местах с конверсиями. Я, наконец, дошел до того момента, когда компилятор подавился в заголовках, созданных из IDL (значения по умолчанию переводятся в буквальные широкие струны).
Вкратце я отказался от попыток достичь этого самостоятельно, если кто-нибудь знает инструмент анализа кода, который может помочь, я был бы очень рад услышать об этом.
BSTR может быть такой typedef, но это не означает, что это строка с нулевым символом. Его строковое представление фактически существа с третьим символом wchar_t, причем первые 2 являются префиксом длины (таким образом, длина до 0xFFFF). Они могут содержать встроенные нули. Я думаю, что они, как правило, заканчиваются нулями. – CashCow
@CashCow, а не точно, длина помещается * перед * фактическими данными (это то, что ищет 'SysStringLen'), поэтому неправильно рассматривать' wchar_t * 'как' BSTR'. – Motti
Да, длина перед данными. Когда вы вызываете SysAllocString, он возвращает вам 5-й байт. Когда вы проходите в BSTR, вы передаете адрес 5-го выделенного байта. – CashCow