著作一覧 |
文字列がイミュータブルなことは良いことに思える。
しかし、 むとぽんさんが出会った『怖い話』とか、富士通は『Java講座の第1回目』で何を教えようとしたか(追記:答えは、だから富士通が売っている開発規約違反検出ツール買えということだったりするわけだが、FindBugsとかCheckStyleとかもあるでよ)とか、『Sunの毒消し』(やり過ぎてもだめだし、それ強調しないでおくれよ、っていう感じ――追記。思い出しけど、こないだ確かに見たよ。文字列定数をappendしまくるおばかなコード。どうして因果律を考えも知ろうともせずにバカの一つ覚えで済まそうとするのか?)とか、なぜあるのか、と言えばあるんですな、これが。
String encode(String s) { String ret = ""; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '&') { ret += "&"; } else ... { ret += s.charAt(i); } } return ret; }
とか、書く人が。さすがに見たことはないけどこんな処理をjavax.servlet.Filterでやられたらガクブル。
人のせいにするのは簡単だが、VBでは(イディオムじゃないな)
Dim s As String ... s = s & "....."
だったりするし、ミュータブルなC++のbasic_stringも+=はそういう動作じゃなかったっけ(こっちは、メモリー再アロケーションのオーバーヘッドで僕が自分で死んだことがあったり)? というわけで文字列=イミュータブルという考えが無いとこうなるし、企業教育とかだと元ネタのソースがこれらの言語だったりすることもあるから、ありそうな話だ。というか、多分に直観的な記述なのではないかという疑いもある。で、こういう処理が多いのだな、実務アプリケーションだと。したがって、そこら中でStringオブジェクトが作られてはGCが動く。
上のはミュータブルな文字列バッファを使うのが正しい(これは上記の富士通やSunのページ参照。だからここには1.5で書いておく)。
String encode(String s) { StringBuilder ret = new StringBuilder(s.length() * 1.5); // 追記:1.5って何これ? for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '&') { ret.append("&"); } else ... { ret.append(s.charAt(i)); } } return ret.toString(); // 1.5からはこうしたほうがプラグマティックには効率的だし、 // CharSequence#toStringと考えると筋は通っていると思う。 }
ソフトウエアはまずいところが有れば直せばいいんだから、開発者は殺伐と思いついたものを黙々と実装すればいいんじゃないかな、と開き直りつつある今日この頃
――てくのーと
その通りだと思う。
だから水だけ差すことにするけど(これはかんさん個人に対してじゃない、開発者というかんさんや僕やここ読んでる人全員のことだ)、だからこそ開発者は、最低限、既存の脆弱性のパターンとそれに対する回避方法についての実装知識(もちろん知ってるだけじゃだめでそれを使って実装すること)は抑えておく必要がある。それは32ビット整数に収まる演算――たとえばループカウンターとか――で済めばintを使うというのと同じレベルの当たり前なことで、利用者の善意とか悪意とかと無関係に、そうするのが当然、というレベルのことだ。
早い話が、『セキュリティエンジニアリング』はデフォルト。っていうか、情報処理技術者試験の1番ちょろいやつってここからガンガン出題してるんだろうか? すべきだろうな。
VBA Emacs(Visual Basic Emacsっていう表記はちょっと違う気がする)。
C-uがちょっと愉快な実装みたいだが。
ついに、MacではWordを本格的に利用するつもりになったので発見。
ジェズイットを見習え |