Desde un BSTR
es sólo una typedef
para wchar_t*
nuestra base de código tiene varios (muchos?) Los lugares donde se pasan los literales de cadena a un método esperando un desastre BSTR
esta lata con señaleros o cualquiera que intente utilizar cualquier método específico BSTR
(por ejemplo, SysStringLen
).análisis de código estático para detectar pasando un wchar_t * a BSTR
¿Hay alguna forma de detectar estáticamente este tipo de uso indebido?
he intentado compilar con VC10 /Wall
y con el análisis de código estático Microsoft Todas las reglas pero el siguiente fragmento de código que no quede marcado por uno de ellos.
void foo(BSTR str)
{
std::cout << SysStringLen(str) << std::endl;
}
int _tmain()
{
foo(L"Don't do that");
}
Actualización: Después de tratar de destrozar wtypes.h
en la detección de este tipo de transgresiones que he dado por vencido.
Intenté dos rutas, ambas de las cuales comencé a trabajar con mi programa de ejemplo anterior, pero una vez que probé un proyecto real fallaron.
- crear una clase llamada
BSTR
pero desde unVARIANT
tiene unBSTR
como un miembro de un sindicato de la nueva clase no podían tener ningún constructor o los operadores de asignación Esto rompió todos los lugares seNULL
fue tratado como unBSTR
. Traté de reemplazarNULL
con un tipo que tiene operadores de conversión pero después de agregar docenas de nuevos operadores (comparación, conversión, etc.) comencé a encontrarme con llamadas ambiguas y desistí. - Probé de la manera sugerida por @CashCow y @Hans (haciendo
BSTR
atypedef
a otro tipo de puntero). Eso tampoco funcionó, después de agregar los métodostoBSTR
yfromBSTR
y tirar basura comutil.h (_bstr_t
) y otros lugares con conversiones finalmente llegué al punto en que el compilador se atascó en los encabezados producidos a partir de IDL (los valores predeterminados se traducen al literal cuerdas anchas).
En resumen, he dejado de tratar de lograr esto por mi cuenta, si alguien sabe de una herramienta de análisis de código que pueda ayudar, estaría encantado de saberlo.
BSTR puede ser un typedef pero eso no significa que sea una cadena terminada en nulo. Su representación de cuerdas en realidad se forma con el tercer carácter wchar_t, el primero de los cuales es un prefijo de longitud (lo que permite una longitud de hasta 0xFFFF). Pueden contener nulos incorporados. Creo que generalmente son terminados en nulo. – CashCow
@CashCow, no exactamente, la longitud se coloca * antes * de los datos reales (esto es lo que 'SysStringLen' busca) es por eso que es incorrecto tratar un' wchar_t * 'como un' BSTR'. – Motti
Sí, la longitud es anterior a los datos. Cuando llamas a SysAllocString, te devuelve el quinto byte. Cuando pasa en un BSTR, pasa la dirección del quinto byte asignado. – CashCow