<前の日記(2005-12-27) 次の日記(2006-01-01)> 最新

おおいわのこめんと (2005-12-29)


2005-12-29

[Comp] [Security] 自動quoteつきERBの実験

高木さんの日記で、

そうすると、「h」付きと「h」無しを逆にしたらよかったのにと思えてくる。

ということだったので、ERB を改造してサクッと作ってみた。 rerb

とりあえず、h の意味を逆転させてしまうと(hを流用してしまうと)それはそれで 混乱すると思ってそれは避けたのだが、高木さんは「hの逆」を命名してくれなかったので、 とりあえず "raw html" ということで r を使った。何かいいアイディアはないものか。

ついでに、rerb-cgi という名前で起動された場合は CGI モジュールを内包して、 ローカル変数 cgi, header 経由で引数や出力ヘッダにアクセスできるようにしてみた。 そういうわけで、test.ehtml は (rerb-cgi という実行ファイルを用意すれば) 単独でcgiとして動作して ……/test.cgi?q=%3c%3d%3e%3f&p=2nd+param とか起動しても ちゃんと quote が行われるような例になっている。

内部的には、Ogawaさん

で、やっぱり思ったのは、PHPにしろPerlにしろSQLにしろ、String Processingの範疇にあるプログラムは、ほとんど常に処理中の文字列が指し示す「型」を意識しなければ作れないにも関わらず、最もベーシックな型である「文字列型」だけを使って実装されていることに、一番の問題があるのではないか、ということです。

とか、この「こめんと」その他でも何度となく「HTML と String は違う型だと思え」とは主張してきたわけですが、 それをちょっとだけ踏まえて HTML 文字列型は RERB::Rerb_html という型で実装されていたりします。 (というか, r 埋め込みを実装するには今の ERB/Ruby を前提にするとそうせざるを得ない)

実際に作ってみると、本当はもっと強く型を意識して言語から設計しないといけない気もしてきたり するのですが、それはおいおい研究ネタにでもすることにして、quick hack としては 結構面白いものができたかな、と思ってみたり。あ、header 部分の RHS 対策とか、 attribute を single quote で括ったときの処理とか、 「これを使えば万全」になるような細工は全然してないので気をつけてね :-)

ちなみにライセンスですが、元のERBと同じ Ruby ライセンス(GPLと独自のdual)にしておきます。 逆にする部分のアイディアを除けば実装は結構な部分が ERB の切り貼りですし。継承で何とかなるかな……と思ってたのだが 実際はかなりの部分をコピーアンドモディファイにする羽目になってしまった。

[Comp] 平民的プログラミングのススメ

高木さんの日記『「サニタイズ言うなキャンペーン」とは何か』から、セキュリティと(直接)関係ない*1方向に派生。

いまどき、そんな貧民的プログラミング思考をするのはプログラム職人として恥ずかしいことだ。

……それはその通りなんだけどね。実際、高木さんの書いている通り、 あの日記中の例で「id と postdate は HTML のメタ文字が含まれないから、 htmlspecialchars を通すのは勿体ない」、みたいな感覚は、いまどきの コンピューティング環境を考えたらみっともない。 実際 htmlspecialchars 通したところで1ms *2 も処理時間変わらないだろうしね。 そういう意味で、貧民的プログラミングはやめよう、というのは正しい。

しかし、個人的に最近気になってることとしては、 一方でやたらと富豪的プログラミングが度を過ぎていて、 プログラムが機能として破綻していることもよく見掛ける気がするのだ。 破産的プログラミングとでも呼ぼうか。

例えば、こういうところで例に出すのは申し訳ないのだが、 tDiary のアクセス回数やアクセス元の記録処理。単純に月単位のDBを PStore や (索引構造のない単純な) テキスト形式で 書き出しているので、アクセス回数 n に対してトータルで少なくとも n2 以上のオーダの IO処理がかかっている。実際、 アクセス数が5桁になるとカウンタ周りは破綻し始めるようだ。 *3 で、本質的に中でやってることは何かというと、当該アクセスに関係ない部分のデータを毎回毎回コピーするという なんか穴を掘っては埋めているような処理。確かにこの手の (PStore のような) 機能、使うとすごくプログラムが楽に書けるのだけどね……。

追記 (1/2)

アクセス回数 (PStore) とアクセス元URL (独自形式テキスト) が混乱しそうな文章になってたので修正。 もっとも、アクセス元記録も O(n2) の重〜い処理になっていることは変わりない。

そういうわけで、僕は「富豪的プログラミング」という言葉は (↑のような誤解に基づくプログラミングを招くので) あまり好きではない。 やっぱり緻密な計算量評価に基づいた最適な処理が物を言うことは多いと思うのだ。

僕の基本的な考え方は、「一番性能に影響する入力サイズ n」というものを考えて、 最適な実装をしたときの計算量から定数倍(1桁)または O(log n) 程度しか変わらないなら、 奢ったプログラミングを許容する、という感じ。一方で入力サイズが小さいと判っているものに関しては、 徹底的に楽で綺麗なプログラミングを奢る、というような感じかな。

例えば tDiary のようなシステムを自分で作ることを考えるなら、日記の更新は高々月100回程度(推敲含む)だし、 サイズも高々月数十エントリ、100kB〜1MB程度であることが想定されるので、 その辺の更新処理に関しては、特に最適化はしない。 *4 今の td2 ファイルみたいに、そこそこ扱いやすい形式で月単位でまとまっていたほうが 利便性が高いと思う。(読込のことはちゃんと考えたほうがいい気もするけど、 まだソースちゃんと読んでないのでパス。) 一方で、読者がアクセスしてくる回数は性能上かなり効いてくる箇所なので、 一回のアクセスにかかる処理量がアクセス回数 n の1乗以上にならないように設計する *5と思う。 実際、Referer の記録やアクセスカウンタの処理は、適切なDB構造を使えば 1回当たり O(log n) の計算量で抑えられる*6(つまり、全体では O(n log n) になる)はずなのだから。

この手の「奢るべきでない場所をちゃんと考えるプログラミング」こそが本来の富豪的 *7 プログラミングだと思うのだが、言葉の響きに「抑制的」なものがないのがよろしくないのだろうか。というわけで、 「無駄に金は使わないけど、奢るべきところでケチケチして後ろ指さされたりはしない、 ごく普通のマットウな社会人としての生き方」と対比させて 表題の「平民的プログラミング」となるわけだが、いいネーミングは何か無いかな。

*1 厳密に言えば、Denial of Service 対策などと絡むので、全く関係ないわけではない。

*2 追記 (2006-01-02): とりあえず、手元の php4-cgi で、実際に10文字程度の文字列を htmlspecialchars にかける時間を測定してみた。 ……約 1us と出ました。全く省略する意義ないですねぇ ;-)

*3 ちょっと直そうかとソースを見たのだが、結構構造を大きく変えないと直らなさそうなので、 tDiary 本家の開発と同期しないと怖くて直せなかった。dbi-io での猛烈なSQLアクセスとも関連してそうなんだけどね。

*4 ちなみにこの日記、通常表示は FastCGI 化してあるが、更新側は通常CGIの update.rb のまま。 更新処理で1回当たり0.5〜1.0sec 程度を削っても全く意味がないので、こうなっている。

*5 実際問題として、日記表示側はマシンによっては定数項が重要になったりする……。 この日記程度のアクセス数でも、FastCGI 化による定数時間削減の効果はある。

*6 但し、リンク元の種類数が アクセス数に比例して増えたりはしない場合に限る。

*7 よくよく考えたら社会的に立派な富豪の方々って、別に何でもかんでも無条件に財布が緩いわけじゃないよねぇ。

本日のツッコミ(全7件) [メッセージを送る]
eto (2006-01-04 01:01)

こんにちは。
http://jp.rubyist.net/magazine/?0012-qwikWeb#l8
わびさび方式はいかがでしょうか。

おおいわ (2006-01-04 02:32)

XMLを木構造のデータとして扱うことは、HTMLのquote問題のアプローチとしては(若干 heavyweight ですが)正しい手法ですし、利点がいろいろあると思います。「わびさび方式」のようなS式エンコードはかなり便利だと思いますし(記事を見て「あー、Ruby なら S 式でいいんじゃない、なるほど」とは思いました)、またXMLデータ処理に特化した言語も色々研究されていますね。

おおいわ (2006-01-04 02:37)

一方で、昔他人に「ASPって何が嬉しいの?」と聞いたところ、「<% %> をタグとしてみたときに、HTMLそのものなんだよ」という返事が返ってきたことがあります。デザイナが書いたHTMLにタグを埋め込んで、さらにそれをそのまま <% %> を認識するHTMLエディタに読み込んでデザイナが編集する、という用途があるそうで。今回のは、ASP/ERB 記法という枠の中で何ができるか、という方向で作ってみたものです。こういうツールは適材適所だと思うので、色々な方向から解決してみるのがいいんじゃないかな。

おおいわ (admin mode) (2006-01-04 02:37)

ちなみに、元々のツッコミのメッセージのURLに間違いがあったので、修正させて頂きました。
ああ、テキスト形式ってこういうときには楽(笑)。

(2006-01-06 22:17)

ERBはHTMLじゃないところでも使うものなのだけど、HTMLに依存したモードがあったらうれしいのかしら。かっこいい仕様はどういうのかなー。

おおいわ (2006-01-07 00:20)

> ERBはHTMLじゃないところでも使うものなのだけど、

一応それは承知しています(笑)。ただ、HTML 出力前提の埋め込み言語を作るという文脈でも、スクリプト部分の言語として php や VisualBasic よりは ruby や Perl の方が好きなので、ERB ベースなのです :-)。
# 手頃に改造できた、という面もあるけどね。

で、実際これでCGI書いてみたら先頭部分のリクエスト解析処理とかヘッダ出力とかが発生してあまり嬉しくなかったので、じゃぁいっそ CGI.pm の処理を内包てもっと web 用言語っぽくしちゃうか、というのが cgi mode をつけた理由だったり。

(2006-01-10 23:35)

DivやRailsなどERBをライブラリとして使うものの多くはフレームワーク(?)が生成したHTML片を挿入することが多いのですよね。tDiaryもそうなんじゃないかと想像してます。
bin/erbで単純なrhtmlを処理して返す、っていうのは本意じゃない使われ方なんすよねー。

そすると、使いやすい仕様ってどの辺りに落ち着くのかなあ。

それはそれとして、私も自動的にquoteするやつを書きました。
むう。rerbとほとんど同じ作戦の実装だなあ。
# 元のerb.rbがああなっていたら、もうそうするしかないか‥

[TrackBack URL: http://www.oiwa.jp/~yutaka/tdiary/trackback.rb/20051229 (note: TrackBacks are moderated: spams will not be shown.) ]

大岩 寛 (おおいわ ゆたか) <yutaka@oiwa.jp.nospam ... remove .nospam> .

Copyright © 2005-2014 Yutaka OIWA. All rights reserved.
Posted comments and trackbacks are copyrighted by their respective posters.

記事の内容について (Disclaimer / Terms and Conditions)