NULL ENTERINED文字列 - 理解できる理由のないKLOCWARKエラー
質問
私は最近「Klocwork」をインストールし、既存のコードでバグを取り除こうとしています。表示されているエラーは単純なようです。の終了時にヌルはありません char * _p_
. 。私は手動でヌル終了を追加しました(必要はありませんが)が、Klocworkを喜ばせません。何か案は?
正確なメッセージは次のとおりです。-
誤って終了した文字列」p'バッファオーバーフローを引き起こします p.
char *ptr;
int writtenchars = 0 ;
va_list args;
char* destStr;
if (argc != 2) {
printf(" wrong parameters number - %d instead of %d\n", argc, 2);
char str[25]="wrong parameters number ";
char *_p_; /********************************************************/
va_start(args, str);
destStr = (char*) malloc(SNMP_BUF_LEN);
_p_= destStr;
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in in function \"snmp_rebuildstringinbuf!!!\" \n");
destStr="kukuRiko";
}
else {
writtenchars = (int) vsnprintf(destStr, 4095, str, args);
if (writtenchars>SNMP_BUF_LEN) {
printf("WARNING: Too long string rebuilded in function \"snmp_rebuildstringinbuf!!!\" %d chars\n",writtenchars);
}
destStr[writtenchars] = '\0' ; //Moshe - making sure the last value of the string is null terminated in order to prevent future buffer overflows.
}
va_end(args);
/******************************************************************************/
//The KlocWork error relates to this line //
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
free (_p_);
========================================================== ========こんにちはみんな、あなたの答えをありがとう、しかしそれはそれよりも少しあいまいなようです。この単純なケースのコードを洗練しました。-コードがすべて1つの関数に記述されている場合、エラーはありませんが、割り当てセクションが関数(およびパラメーターとして渡されたテキスト)にラップされると、Klocworkエラーが戻ります。このコードを参照してください: - エラーのないバージョン: -
char *_p_; /*+++++++++++++++++++*/
int writtenchars = 0 ;
va_list args;
char* destStr;
char* str = "hello World";
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
/*+++++++++++++++++++*/
_p_ = destStr ;
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
/***********************************************************/
一方、 / *++++ * /の間にコードを取得し、それを関数にラップすると、上記のKlocworkエラーが返されます。
したがって、
char *writingToSomeBuffer (char * str) {
int writtenchars = 0 ;
va_list args;
char* destStr;
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
return destStr;
}
int main () {
char *_p_;
_p_ = writingToSomeBuffer("hello world");
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
return 0 ;
}
何か案は?
解決
ジョナサンはそれを正します。私たちは最近、このチェッカーを2つの家族に分割しました。
http://www.klocwork.com/products/documentation/insight-9.1/checkers:nnts.might http://www.klocwork.com/products/documentation/insight-9.1/checkers:nnts.must
私たちは現在、これをきれいにして理解しやすくするために開発中です。問題だけでなく、解決策もあります。
他のヒント
Klocworkは、メモリの割り当てが失敗した場合、ヌルポインターで書くことができる問題を正しく診断しています。
_p_= destStr;
if (destStr == NULL)
{
printf("WARNING: Failed to alloc memory in in function ...\n");
destStr = "kukuRiko";
この時点で、(恐ろしく名付けられた)」_p_
'変数はまだnullですが、以下の印刷操作で使用して使用します。
また、追加の「些細な」修正が_p_
「これがあなたの記憶管理を破った後。あなたは後でします」free(_p_);
「これは恐ろしい問題につながります」_p_
'定数を指します。
また、「記憶」もあります の メッセージ内の関数。 「間違ったパラメーター番号」は、「間違った数のパラメーター」とほぼ同じを意味しますが、後者はより慣用的な英語です。感嘆符のいずれかがエラーメッセージに役立つとは確信していません。それらの1つが望ましいとみなされていても、彼らは関数名を囲む二重引用符の外に出るべきであるという強い議論があります。
問題の改訂版で、KlocworkがMicrosoftが言っていることを診断しているのだろうか vsnprintf(), 、それはヌル終了を保証しないこと(これはC99および Posix 言う)。
Klocworkのエラーは別として、このコードは間違っていると思います。なぜあなたは制限しているのですか vsnprintf
バッファサイズは4096までです SNMP_BUF_LEN
?これら2つはどのように互いに関係していますか?もしも SNMP_BUF_LEN
<4096、その後、バッファーを溢れさせたかもしれません。なぜあなたは合格しないのですか SNMP_BUF_LEN
vsnprintfの制限的な議論として?
また、書き込み destStr[writtenchars]
疑わしいです。 vsnprintfのバリアント(それらは異なります)に応じて、執筆者は文字の数である可能性があります 欲しかった 書くには、バッファの終わりを過ぎて書くことになります。
それはすべて、Klocworkは完璧ではありません。私たちは非常に明示的に安全であることを試みていたマクロを持っていました、そして、Klocworkはそれらを潜在的に文字列をオーバールする可能性があると誤解しました。それもSNPRINTFのケースだったと思います。
全体的に優れた製品ですが、いくつかの穴があり、すべての苦情を修正することはできません。