1. ホーム
  2. c

[解決済み] strncpyがNULL終了しないのはなぜですか?

2023-06-04 21:18:49

質問

strncpy() は、バッファオーバーフローから保護すると考えられています。しかし、もしそれが null 終端せずにオーバーフローを防ぐのであれば、すべての可能性において、その後の文字列操作はオーバーフローすることになります。そのため、これを防止するために、私は自分自身がそうしていることに気づきました。

strncpy( dest, src, LEN );
dest[LEN - 1] = '\0';


man strncpy を与える。

strncpy() 関数も同様ですが n バイトの src のバイトがコピーされます。したがって、もし最初の n のバイトが src を含む場合、結果はヌル文字で終端されません。

のような一見何の変哲もないものをヌル文字で終端することなく

   printf( "FOO: %s\n", dest );

...クラッシュする可能性があります。


より良い、より安全な strncpy() ?

どのように解決するのですか?

strncpy() は、より安全な strcpy() として使われるのではなく、ある文字列を別の文字列の途中に挿入するために使われることになっています。

のような文字列を扱う関数は、すべて snprintf()vsnprintf() は、バッファオーバーフローのエクスプロイトなどを緩和するために、後の規格で追加された修正です。

ウィキペディア 言及 strncat() を書く代わりに、安全な strncpy() :

*dst = '\0';
strncat(dst, src, LEN);

EDIT

私はそれを逃した strncat() は、文字列がLEN文字より長いか等しい場合、文字列をNULL終端するときにLEN文字を超えます。

とにかく strncat() のような自作ソリューションの代わりに memcpy(..., strlen(...)) /whatever の実装は strncat() がライブラリでターゲット/プラットフォーム最適化されている可能性があります。

もちろん、dstが少なくともnullcharを保持していることを確認する必要があるので、正しい使い方の strncat() のようなものでしょう。

if (LEN) {
    *dst = '\0'; strncat(dst, src, LEN-1);
}

また、私は strncpy() は、部分文字列を別の文字列にコピーするのにあまり有用ではないことを認めます。もしsrcがn文字より短ければ、コピー先の文字列は切り捨てられます。