アカウント名:
パスワード:
リンクの解説読みましたけど、問題は
strncat(passwd, "$", 1);をstrlcat(passwd, "$", 1);に、変更したことのようですから、正確には「strlcatの罠」じゃないですかね?
strcat→strncatの時点ではバグってないわけで。
まあ仰ることも間違いではないのですが、C言語界の背景というかstrncatのsize指定が「意外性最小原則にそぐわない」仕様だということで数々のバグの発生源となっており、散々非難されてきた、という今までの経緯があるのです。
で、srtncat使用者はそこを注意して使用してたけど、後からそれをstrlcatに置き換えた人はそんな罠があったと知らず、何も考えずそのまま関数だけ置き換えてしまったと。
ある意味、strncatというのは関数自体がバッドノウハウ的な存在なのですね。まさにバッドノウハウ的対応が、たとえその場は良くても将来に問題を引き起こすという好例となってしまったということでしょう。
そして、そんな些細なミスを誘発するような再発明をするくらいならstrcat(passwd, "$");でいいじゃん、と言うことで、振り出しに戻る。
>そして、そんな些細なミスを誘発するような再発明をするくらいなら>strcat(passwd, "$");でいいじゃん、と言うことで、振り出しに戻る。
戻りませんよ。
プログラムに限らず、人間の行う論理表現では「明示的なある」を示せても「暗黙のない」は示せません(コメントなど含め、また「”ない”と書いて”ある”」まで含まれます)。
ここで、strcatでは「バッファのサイズ溢れとか危険だけどその意識は”ある”のか”ない”のか」を示すことができません。ですので、そこで人間が明示的に「(意識は)ある」を保証するためには、適切なコード(strcatからstrncatにす
このタレコミについてるコメント全体に言えることだけど、strncat(passwd, "$", 1);自体は全く問題ない。strlcat(passwd, "$", 1);が間違ってるだけ。
そもそも全体テストが通らない状態でstrcatをstrncatに書き換える意義は殆ど無いんだが、strncatに変えた事自体は問題なかった。その後、一番の大馬鹿者がstrncatをstrlcatに差し替えたのが問題だった。
strlcatの存在を知っている奴がなぜstrncatとstrlcatでは動作が違い引数も違うということを意識しなかったのか…理解に苦しむ。
# くらいの事情は編集追記の「徳丸浩氏がブログにて詳細に解説している [tokumaru.org]」を読めば理解できるぞ
>大問題です。>そういう動けばいい、アラートが出なければいい、>というコーディングがすべての元凶です。
「動けばいい」のはstrcatのほうですよ。それが理解できませんか?
記述をより明確で確実なものにしていく、という観点でstrcatをstrncatにしたことは確実に意味と価値があります。これが理解できないのであれば、申し訳ありませんが他人とのコミュニケーションを数年経験してみてはどうでしょうか。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
ソースを見ろ -- ある4桁UID
strncatの罠? (スコア:0)
リンクの解説読みましたけど、問題は
strncat(passwd, "$", 1);
を
strlcat(passwd, "$", 1);
に、変更したことのようですから、正確には「strlcatの罠」じゃないですかね?
strcat→strncatの時点ではバグってないわけで。
Re: (スコア:5, 興味深い)
まあ仰ることも間違いではないのですが、C言語界の背景というか
strncatのsize指定が「意外性最小原則にそぐわない」仕様だということで
数々のバグの発生源となっており、散々非難されてきた、という今までの経緯があるのです。
で、srtncat使用者はそこを注意して使用してたけど、後からそれをstrlcatに置き換えた人は
そんな罠があったと知らず、何も考えずそのまま関数だけ置き換えてしまったと。
ある意味、strncatというのは関数自体がバッドノウハウ的な存在なのですね。
まさにバッドノウハウ的対応が、たとえその場は良くても将来に問題を引き起こすという好例となってしまったということでしょう。
Re: (スコア:1, すばらしい洞察)
第三引き数が size なのは strlcpy の方だぞ。
引き数の意味を間違えて「意外性」どうのこうのとか、知ったかぶりするのはやめて欲しい。
本人は悪意がないのかもしれないけど、まだぞろ誤解して、strcat() 使うなとか、
strncat() 使うなとか、頭の悪いコード規約作ろうとうするやつが多発するから。
今回のも罠でも何でもなくて strcat() で十分なのに、迷信に従って strncpy(), strlcpy() とかに書き換えた馬鹿がいるだけじゃないか。
# *passwd = '$'; passwd[1] = 0; <--- 本当にやりたっかったこと
Re: (スコア:1, おもしろおかしい)
蛇足の部分でミスった。
passwd_end = passwd + strlen(passwd);
*passwd_end = '$'; passwd_end[1] = 0;
と書かないと意味が通じないか。
Re: (スコア:1, すばらしい洞察)
そして、そんな些細なミスを誘発するような再発明をするくらいならstrcat(passwd, "$");でいいじゃん、と言うことで、振り出しに戻る。
Re: (スコア:0)
>そして、そんな些細なミスを誘発するような再発明をするくらいなら
>strcat(passwd, "$");でいいじゃん、と言うことで、振り出しに戻る。
戻りませんよ。
プログラムに限らず、人間の行う論理表現では
「明示的なある」を示せても「暗黙のない」は示せません
(コメントなど含め、また「”ない”と書いて”ある”」まで含まれます)。
ここで、strcatでは
「バッファのサイズ溢れとか危険だけどその意識は”ある”のか”ない”のか」
を示すことができません。
ですので、そこで人間が明示的に「(意識は)ある」を保証するためには、
適切なコード(strcatからstrncatにす
Re: (スコア:0)
少なくとも溢れないようにしたいですとか溢れなくしましたという意思は一切表現されてない。
意識があろうがなかろうが、バッファ溢れするコードは溢れるし、溢れないコードは溢れません。
こんな簡単なケースなら機械的に判断できるはずだし、静的解析を謳うんならそれくらい解析して欲しいものです。
Re: (スコア:0)
このタレコミについてるコメント全体に言えることだけど、
strncat(passwd, "$", 1);
自体は全く問題ない。
strlcat(passwd, "$", 1);
が間違ってるだけ。
そもそも全体テストが通らない状態でstrcatをstrncatに書き換える意義は殆ど無いんだが、strncatに変えた事自体は問題なかった。
その後、一番の大馬鹿者がstrncatをstrlcatに差し替えたのが問題だった。
strlcatの存在を知っている奴がなぜstrncatとstrlcatでは動作が違い引数も違うということを意識しなかったのか…理解に苦しむ。
# くらいの事情は編集追記の「徳丸浩氏がブログにて詳細に解説している [tokumaru.org]」を読めば理解できるぞ
Re: (スコア:0)
> 自体は全く問題ない。
大問題です。そういう動けばいい、アラートが出なければいい、というコーディングがすべての元凶です。
Re: (スコア:0)
>大問題です。
>そういう動けばいい、アラートが出なければいい、
>というコーディングがすべての元凶です。
「動けばいい」のはstrcatのほうですよ。
それが理解できませんか?
記述をより明確で確実なものにしていく、という観点で
strcatをstrncatにしたことは確実に意味と価値があります。
これが理解できないのであれば、
申し訳ありませんが他人とのコミュニケーションを数年経験してみてはどうでしょうか。
Re:strncatの罠? (スコア:0)
> strcatをstrncatにしたことは確実に意味と価値があります。
strncatにするときに第三引数をきちんと計算して渡せば、それは大いに意味があります。
でも、今回は違うでしょ?