Dal momento che un BSTR
è solo una typedef
per wchar_t*
la nostra base di codice ha diversi (molti?) Posti in cui sono passati stringhe a un metodo che prevede un BSTR
questo può rovinare con marshaller o chiunque tenti di utilizzare qualsiasi metodo specifico BSTR
(ad esempio SysStringLen
).Analisi statica del codice per rilevare il superamento di un wchar_t * a BSTR
C'è un modo per rilevare staticamente questo tipo di uso improprio?
la compilazione con VC10 /Wall
e con analisi statica del codice Microsoft Tutte le regole ma il seguente pezzo incriminato di codice non viene contrassegnato da una di esse.
void foo(BSTR str)
{
std::cout << SysStringLen(str) << std::endl;
}
int _tmain()
{
foo(L"Don't do that");
}
Aggiornamento: Dopo aver cercato di vandalizzare wtypes.h
in rilevare questi tipi di trasgressioni ho rinunciato.
Ho provato due percorsi, entrambi i quali ho avuto modo di lavorare con il mio programma di esempio sopra ma una volta che ho provato un vero progetto hanno fallito.
- creare una classe denominata
BSTR
ma dal momento che unVARIANT
ha unBSTR
come sindacalista della nuova classe non poteva avere alcun costruttori o operatori di assegnamento questo ha rotto ogni luogo sono statiNULL
è stata trattata come unBSTR
. Ho provato a sostituireNULL
con un tipo che ha operatori di conversione ma dopo aver aggiunto decine di nuovi operatori (confronto, conversione ecc.) Ho iniziato a imbattermi in chiamate ambigue e ho rinunciato. - Ho quindi provato la strada suggerita da @CashCow e @Hans (creando
BSTR
atypedef
in un altro tipo di puntatore). Non ha funzionato neanche dopo aver aggiuntotoBSTR
efromBSTR
metodi e rifiuti comutil.h (_bstr_t
) e in altri luoghi con conversioni Sono finalmente arrivato al punto in cui il compilatore si è soffocato alle intestazioni prodotte dagli IDL (i valori predefiniti vengono convertiti in valori letterali stringhe larghe).
In breve, ho rinunciato a cercare di ottenere questo risultato da solo, se qualcuno è a conoscenza di uno strumento di analisi del codice che può essere d'aiuto, sarei molto felice di sentirlo.
BSTR può essere un typedef ma ciò non significa che sia una stringa con terminazione null. La sua rappresentazione di stringa in realtà si trova con il terzo carattere wchar_t, il primo 2 è un prefisso di lunghezza (consentendo così una lunghezza fino a 0xFFFF). Possono contenere null incorporati. Penso che siano di solito a terminazione nulla. – CashCow
@CashCow, non esattamente, la lunghezza è posta * prima * dei dati effettivi (questo è ciò che 'SysStringLen' cerca) è per questo che non è corretto trattare un' wchar_t * 'come' BSTR'. – Motti
Sì, la lunghezza è prima dei dati. Quando si chiama SysAllocString, si restituisce il quinto byte. Quando si passa in un BSTR, si passa all'indirizzo del quinto byte assegnato. – CashCow