トップ «前の日(12-14) 最新 次の日(12-16)» 追記   RSS 1.0 FEED  

Journal InTime


2003-12-15 (Mon)

_ XP

またXPがはじまってしまった。メールが読む暇が…。

_ Rubyコーディング規約

社内プロジェクトのためにRubyコーディング規約 を書いてみた。


2004-12-15 (Wed)

_ [物欲] suonoのCLIE用ケース

suonoのCLIE用ケース

今さら遅いような気もしたけど、CLIE用のケースを購入。

ところどころハンドメイド感が漂う(斜めになっているところがあったり)が、なかなか気に入った。 ケースから完全に取り出さないと何にもできないので、実用性を気にする人にはおすすめしません。 まあ、そもそもCLIE自体にあんまり実用性を求めてないけど。


2014-12-15 (Mon)

_ [Ingress] Intel mapからポータル名をコピーする

Intel map上でポータル名をコピーしようとするとドラッグ操作になってしまってポータル名を選択できない*1ので、HTML5のclipboard APIを使って簡単なブックマークレットを書いてみた。

使い方

  1. 以下のリンクをブックマークバーにドラッグ&ドロックして登録する
  2. Intel mapを開く
  3. ブックマークバーから1で登録したブックマークレットを実行する
  4. ポータルをクリックする
  5. Ctrl+Cを押す

一度3を実行すれば、4〜5は繰り返し実行できる。

*1  IITCならできるかもしれないけど使ってない。


2017-12-15 (Fri)

_ [Ruby] ファイルオープンの罠

僕が書いたNet::FTPのコードに脆弱性報告があり、修正版がリリースされた。関係者のみなさん、ありがとうございました。

問題があったのは以下のようなコードだった。

def getbinaryfile(remotefile, localfile = File.basename(remotefile),
                  blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data
  f = nil
  result = nil
  if localfile
    if @resume
      rest_offset = File.size?(localfile)
      f = open(localfile, "a")
    else
      rest_offset = nil
      f = open(localfile, "w")

ここでKernel#openを使っていたのが問題で、localfile|で始まる文字列だと外部コマンドが実行されてしまう。 しかも、まずいことにlocalfileのデフォルト値はFile.basename(remotefile)なので、悪意のあるFTP上に|で始まる名前のファイルがあって、ディレクトリ内のファイルをすべてダウンロードするようなプログラムを書いていると、クライアント側でコマンドが実行されてしまう。パイプ以外ではopen-uriをrequireしているようなケースでも何かまずいことができてしまうかもしれない。

普段書き捨てのコード以外ではFile.openの方を使うのだけど、確認したところ1997年8月13日リリースのruby-1.1a0のころからKernel#openを使っていたようだ。

ちなみにopen以外にも罠があって、例えば

p File.read("|echo hello") #=> "hello"

のようにしてもコマンドが実行されてしまう。

これは、Fileクラスには実はreadは定義されておらず、IO.readが呼び出されるため。 他には、binread, write, binwrite, foreach, readlinesなども同様の罠がある。 わざわざFile.と書いてパイプをオープンしている意図的なコードはそうそうないと思うので、Fileクラスにパイプをオープンしないバージョンを追加してオーバーライドした方がよいのではないかと思うが、今さら2.5には間に合わないだろう。

当面は引数をFile.expand_pathでフルパスに展開するとか、先にFile.statするなどすれば、上記のような罠を回避することができると思う。