2017-04-13 10 views
0

メッセージ構造体の内容をバッファにエンコードしています。セグメンテーションフォールトにつながる空の文字列入力を処理する

int encode(const struct message *msg, unsigned char *buffer, size_t max_size) 
{ 
    if (buffer == NULL) 
    return -1; 

    unsigned char *buf_pos = buffer; 
    unsigned char *ep = buffer + max_size; 

    if (buf_pos + 1 <= ep) { 
    *buf_pos++ = SYNC_WORD_1; 
    } else { 
    return buf_pos - buffer; 
    } 
    . 
    . 
    . 
} 

私がencode(&message, "", 1024);と呼ぶと、予想通りセグメント化フォルトが発生します。私は、""にはヌルターミネーターだけが含まれているので、セグメンテーションがプログラムに割り当てられていないメモリにアクセスしようとしていることが原因であると私は理解しています。

私が抱えている問題は、このエラーを処理しようとするときです。私は、有効な入力または別のsegfaultで偽陽性を引き起こさない無効な入力を特定する方法を発見していません。

このような入力を除外する正しい方法は何ですか?

+1

どうすれば 'strlen(buffer)== 0' –

+3

どのくらいのメモリを知っているか、書き込み可能かどうかという問題を特定のメモリ位置に解決する方法はありません。 –

+2

'私はencode(&message、" "、1024);を呼び出します。 '第2引数は文字列定数であり、書き込むことはできません。あなたの '* buf_pos ++ = SYNC_WORD_1;'はそれに書き込もうとします。 – joop

答えて

2

これはできません。

あなたは基本的に "ポインタを与えられました。そこに書き込み可能スペースのn個のバイトがあることをどうすれば保証できますか?"これはCがあなたを助けない質問です。

これは、ポインタが単なるアドレスであるため、各ポインタ値に関連付けられた後の種類の追加のメタ情報はありません。

NULLであることを確認できますが、これは基本的に無効なポインタ値です。移植不可能な(特に埋め込みターゲット上で)あなたは巧みになり、ポインタがさまざまな既知の書き込み不可能な領域にあるかどうかをチェックできますが、それでもまだ非常に粗いです。

+0

問題はsegフォールトイベントを回避する方法です。これはその質問に対する答えではありません。 – user3629249

0

buf_posにコピーするときにバッファのサイズを確認していないと思います。 buf_pos + 1にアクセスしようとすると、アクセス権のないメモリにアクセスしてセグメンテーションフォルトが発生する可能性があります。 実行ファイルでvalgrindを試しましたか?

0

実行時の問題について質問するときは、実際の入力、予想される出力、実際の出力、最も重要なのは、きれいにコンパイルされたポストコードコードは短く、 。

次のコードは、NULバイトのみを含む文字列へのポインタを処理します。

しかし、それだけで問題ではありません。渡されたバッファポインタが読み込み専用メモリ内のchar配列を指している場合、投稿されたコードはsegaultイベントを引き起こします。

int encode(const struct message *msg, unsigned char *buffer, size_t max_size) 
{ 
    if (buffer == NULL) 
     return -1; 

    if(strlen(buffer) == 0) 
     return -1; 

    unsigned char *buf_pos = buffer; 
    unsigned char *ep = buffer + max_size; 

    if (buf_pos + 1 <= ep) 
    { 
     *buf_pos++ = SYNC_WORD_1; 
    } 

    else 
    { 
     return buf_pos - buffer; 
    } 
    . 
    . 
    . 
} 

この機能を呼び出すシナリオを投稿する必要があります。

関連する問題