アカウント名:
パスワード:
printf(SSID)かsprintf(buffer, SSID)をやってると飛びそうな文字列だけど…。
まず知ってないとマズい話として、ユーザが入力した何が入ってるか分からん文字列を表示したい、という場合に、
printf(ユーザが入力した文字列とか);
は絶対にやっちゃダメな書き方なんだけど。
printf("%s", ユーザが入力した文字列とか);
とかputs()を使う必要あり。
%pはポインタのアドレスを表示なので引数が16進で表示される。%sはポインタが指す先を文字列として表示%nはそこまでに出力した文字数をポインタが指す先に格納
なので、もしその書き方をしてしまったというセキュリティホールなら、フォーマット文字列以降に引数は付いてないだろうから、その瞬間にスタックに積んであるデータが対象になってしまう。
%pは要らないデータを読み飛ばしてる? %sはスタックに積んであるポインタの先を文字列と見なして処理される。\0がなかなか出てこないとえらいことになる。%nはスタックに積んであるポインタの先に数値が書き込まれるのでスタックが壊れる。最悪。
OSの保護が無ければ任意コード実行も狙えるバグになる。
良く解説したえらいなぁしかし%nはホントクソprintfが古すぎるのや
C++ で行儀悪いの分かっててもストリームじゃなくて printf 使っちゃうんですよね(ただのロートルなだけですが)ただ今時業務系だとロケール切替えのために引数の順序を指定できないと困るので、printf はデバッグトレース時ぐらいしか使わないかなー# そしてそのデバッグコードが本番に混ざるまでがお約束
> 引数の順序を指定できないと困る
標準ではありませんが、今時だとたいがいPOSIXの引数順指定 [wikipedia.org]が使えると思いますよ。
const char* fmt = "Invalid command %1$s at line %2$d.\n";const char* cmd = "hoge";const int lineNumber = 20;printf(fmt, cmd, lineNumber);とした場合、Invalid command hoge at line 20.と表示される。
ログは全部あれで出してるなprintfよりはましやと思うぞ
そこは、boost::format [github.io] の出番じゃないですかね。
cout << boost::format("writing %s, x=%s : %d-th step\n") % "toto" % 40.23 % 50;結果:"writing toto, x=40.230 : 50-th step\n"
といった感じ。% 演算子のオーバーロードによるパラメータ指定はboostの変態っぷりを象徴してそうですが
おお、C++20での新機能 [github.io]なんですね。順番指定が0オリジンなあたりにこだわりを感じる…
C言語もC++もなぜHello, Worldに初心者にはとてもおすすめできない言語機能を投入しまくるのか(可変長引数、ADL、演算子オーバーロード...)
プログラミング初心者を想定ユーザとしていないから、では?
もっとも、それら機能は非初心者が生むバグの原因にもなっている。避けがたい理由が無ければ、CもC++も使うべきではない、と言う事じゃないかな。初心者に限らず。
文字数なら戻り値があるのに、%nってどう使うんだろな。
全部じゃなくて、%nの位置までに出力した文字数ってとこに意味があるんやで。
空白区切り可変長のカラムヘッダを出力して、次の行にカラム毎の区切り線出したい時とか便利やろ?
便利かもしれんがprintfに入れる機能とは思えない・・・
マイクロソフトのドキュメントだと、セキュリティー的にあかんので%nはデフォルトでは無効になってるそうですが、まだ少数派なのかな。
いや解説する気なんかなかった(皆知ってるやろうと思って)ので悔しくなんかない当たり前のことをわざわざ書けるってのはすごいよ
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
日々是ハック也 -- あるハードコアバイナリアン
printf? (スコア:5, 参考になる)
printf(SSID)かsprintf(buffer, SSID)をやってると飛びそうな文字列だけど…。
まず知ってないとマズい話として、ユーザが入力した何が入ってるか分からん文字列を表示したい、という場合に、
printf(ユーザが入力した文字列とか);
は絶対にやっちゃダメな書き方なんだけど。
printf("%s", ユーザが入力した文字列とか);
とかputs()を使う必要あり。
%pはポインタのアドレスを表示なので引数が16進で表示される。
%sはポインタが指す先を文字列として表示
%nはそこまでに出力した文字数をポインタが指す先に格納
なので、もしその書き方をしてしまったというセキュリティホールなら、フォーマット文字列以降に引数は付いてないだろうから、その瞬間にスタックに積んであるデータが対象になってしまう。
%pは要らないデータを読み飛ばしてる? %sはスタックに積んであるポインタの先を文字列と見なして処理される。\0がなかなか出てこないとえらいことになる。%nはスタックに積んであるポインタの先に数値が書き込まれるのでスタックが壊れる。最悪。
OSの保護が無ければ任意コード実行も狙えるバグになる。
Re: (スコア:0)
良く解説したえらいなぁ
しかし%nはホントクソ
printfが古すぎるのや
Re: (スコア:0)
C++ で行儀悪いの分かっててもストリームじゃなくて printf 使っちゃうんですよね(ただのロートルなだけですが)
ただ今時業務系だとロケール切替えのために引数の順序を指定できないと困るので、printf はデバッグトレース時ぐらいしか使わないかなー
# そしてそのデバッグコードが本番に混ざるまでがお約束
Re:printf? (スコア:1)
> 引数の順序を指定できないと困る
標準ではありませんが、今時だとたいがいPOSIXの引数順指定 [wikipedia.org]が使えると思いますよ。
Re: (スコア:0)
Re: (スコア:0)
ログは全部あれで出してるな
printfよりはましやと思うぞ
Re:printf? (スコア:1)
そこは、boost::format [github.io] の出番じゃないですかね。
といった感じ。
% 演算子のオーバーロードによるパラメータ指定はboostの変態っぷりを象徴してそうですが
Re:printf? (スコア:1)
Re:printf? (スコア:1)
おお、C++20での新機能 [github.io]なんですね。
順番指定が0オリジンなあたりにこだわりを感じる…
Re: (スコア:0)
C言語もC++もなぜHello, Worldに初心者にはとてもおすすめできない言語機能を投入しまくるのか
(可変長引数、ADL、演算子オーバーロード...)
Re:printf? (スコア:1)
プログラミング初心者を想定ユーザとしていないから、では?
もっとも、それら機能は非初心者が生むバグの原因にもなっている。
避けがたい理由が無ければ、CもC++も使うべきではない、と言う事じゃないかな。
初心者に限らず。
Re: (スコア:0)
文字数なら戻り値があるのに、%nってどう使うんだろな。
Re:printf? (スコア:1)
全部じゃなくて、%nの位置までに出力した文字数ってとこに意味があるんやで。
空白区切り可変長のカラムヘッダを出力して、
次の行にカラム毎の区切り線出したい時とか便利やろ?
Re: (スコア:0)
便利かもしれんがprintfに入れる機能とは思えない・・・
Re: (スコア:0)
マイクロソフトのドキュメントだと、セキュリティー的にあかんので%nはデフォルトでは無効になってるそうですが、
まだ少数派なのかな。
Re: (スコア:0)
いや解説する気なんかなかった(皆知ってるやろうと思って)ので悔しくなんかない
当たり前のことをわざわざ書けるってのはすごいよ