by
Anonymous Coward
on 2011年08月24日 21時12分
(#2008801)
ウィキにも書いてある。
strncpy strncpy writes exactly the given number of bytes, either only copying the start of the string if it is too long, or adding zeros to the end of the copy to fill the buffer. It was introduced into the C library to deal with fixed-length name fields in structures such as directory entries. Despite its name it is not a bounded version of strcpy, it does not guarantee that the result is a null-terminated string. The name of the function is misleading because strncat and snprintf are respectively bounded versions of strcat and sprintf. The assumption that the result is a null-terminated string leads to two problems. If the source string is too long, the result is not null-terminated, making data after the end of the buffer appear to be part of the string. And if the source string is much shorter than the buffer, considerable time will be wasted filling the rest of the buffer with null bytes. An alternative from the standard C library that will always append one null byte is to use strncat with an initially empty string as the destination.
> The name of the function is misleading because strncat and snprintf are respectively bounded versions of strcat and sprintf. っつーのは、そのWiki書いてる人の解釈でしかないようにしか読めない。
strncatの罠? (スコア:0)
リンクの解説読みましたけど、問題は
strncat(passwd, "$", 1);
を
strlcat(passwd, "$", 1);
に、変更したことのようですから、正確には「strlcatの罠」じゃないですかね?
strcat→strncatの時点ではバグってないわけで。
Re: (スコア:5, 興味深い)
まあ仰ることも間違いではないのですが、C言語界の背景というか
strncatのsize指定が「意外性最小原則にそぐわない」仕様だということで
数々のバグの発生源となっており、散々非難されてきた、という今までの経緯があるのです。
で、srtncat使用者はそこを注意して使用してたけど、後からそれをstrlcatに置き換えた人は
そんな罠があったと知らず、何も考えずそのまま関数だけ置き換えてしまったと。
ある意味、strncatというのは関数自体がバッドノウハウ的な存在なのですね。
まさにバッドノウハウ的対応が、たとえその場は良くても将来に問題を引き起こすという好例となってしまったということでしょう。
Re: (スコア:1)
文字列を安全にくっつける用途では罠が多いけど、バイナリとかでちょうどnバイト埋めたいって用途の場合はむしろ自然な仕様なんじゃないかと思う。
# けれど、文字列に使われることの方が圧倒的に多いのでやっぱ悪か?
1を聞いて0を知れ!
Re: (スコア:0)
strncpyと勘違いしてない?
# strncpyの仕様は当時まだ生き残っていた固定長レコード向けのもので、断じてセキュリティのためではない。
Re: (スコア:1)
strncpyと似たものだから、似たような用途かと思ったのだけど。
1を聞いて0を知れ!
Re: (スコア:1, すばらしい洞察)
Re: (スコア:1)
Ubuntuのuniverse/docにあるmanpages-ja-dev 0.5.0.0.20080615-1を確認した上で書いたけど。
挙動は当然書いてあったけど、それを何に使うためのものかまでは書いてなかった。
読んでおくことが推奨されるマニュアルで、strncatの挙動ではなく用途まで記述されているものがあるというのなら、教えてくださいな。
ないと思うけど。
1を聞いて0を知れ!
Re:strncatの罠? (スコア:0)
strncpy
strncpy writes exactly the given number of bytes, either only copying the start of the string if it is too long, or adding zeros to the end of the copy to fill the buffer. It was introduced into the C library to deal with fixed-length name fields in structures such as directory entries. Despite its name it is not a bounded version of strcpy, it does not guarantee that the result is a null-terminated string. The name of the function is misleading because strncat and snprintf are respectively bounded versions of strcat and sprintf.
The assumption that the result is a null-terminated string leads to two problems. If the source string is too long, the result is not null-terminated, making data after the end of the buffer appear to be part of the string. And if the source string is much shorter than the buffer, considerable time will be wasted filling the rest of the buffer with null bytes.
An alternative from the standard C library that will always append one null byte is to use strncat with an initially empty string as the destination.
Re:strncatの罠? (スコア:1)
まさか、人に不勉強を指摘するコメントで、Wikipediaのことをウィキと略してるってことはないよね?
> The name of the function is misleading because strncat and snprintf are respectively bounded versions of strcat and sprintf.
っつーのは、そのWiki書いてる人の解釈でしかないようにしか読めない。
俺には、strncpyに対するものとしてNUL終端するとは限らないstrncatとNUL終端するsnprintfを同列に書いているのはミスリーディングに見えるし、
strncatの挙動がstrncpy(NUL終端するとは限らない。指定したサイズに達するまでNULで埋める)かsnprintfかどっちに近いと聞かれると、俺ならstrncpyに近いと答える。
別に、俺の見方が正しいというつもりはないが、どこかのWikiに書いてあることも、書いた人の印象でしかない。
1を聞いて0を知れ!
Re: (スコア:0)
>Wikipediaのことをウィキと略してるってことはないよね?
いまだにWikipediaとWikiの区別がつかないヤツって多いんだよ。
そっとしておいてやれよ。:p
# MediaWikiの話をすると不思議そうな顔をされるのも恒例
Re: (スコア:0)
> NUL終端するとは限らないstrncat
Re: (スコア:0)
>ウィキと書いたのはもちろん君をバカにするためだが、
>まさかマニュアルを読んでこの理解とは恐れ入った。全面降伏するよ。
>
> NUL終端するとは限らないstrncat
横槍になりますが、
(最終的にヌル止め同等と必ず見なせる状況になる場合を除外しても)
strncatはコピー先バッファ溢れになったときの挙動が未定義です。
それに対してsnprintfはバッファ溢れになってもヌル止めは入ります。
実際にはstrncatで上記状況でもヌル止めされる処理系が多いんでしょうけど、
str"n"cat、s"n"printfともにバッファオーバーラン対策が主眼で導入されたものですから、
「実際にやっちゃった」ときの挙動の違いは非常に重要でしょう。
Re:strncatの罠? (スコア:1)
> ウィキと書いたのはもちろん君をバカにするためだが
それで人をバカにできたと思えるのはすごい。
1を聞いて0を知れ!
Re: (スコア:0)
それはいいからつまらないバグで他人に迷惑をかける前にちゃんとマニュアル読んどけよ。って偉そうに読んだと宣言した上での恥だったな(笑)
Re: (スコア:0)
通りすがりだけど・・・
いや、ちょっと・・・面白いな君・・・