Rubyに複数の脆弱性

Rubyに複数の脆弱性が発見されました。最新バージョンへのアップグレードを推奨します。

ということで、EC2で使ってるRubyをruby 1.8.7 (2008-08-08 patchlevel 71) [i686-linux]にアップデートしました。

よろしくお願いします。

posted by Png genki on Fri 8 Aug 2008 at 16:28 with 1 comment

Redmineで2203年の予定を立てようとしたところ、エラーが出たので原因を調べていました。 どうやら、Railsのdistance_of_time_in_wordsでエラーが出ているようです。

   1  def distance_of_time_in_words(
   2      from_time, to_time = 0, include_seconds = false)
   3    from_time = from_time.to_time if
   4      from_time.respond_to?(:to_time)
   5    to_time = to_time.to_time if
   6      to_time.respond_to?(:to_time)
   7    distance_in_minutes =
   8      (((to_time - from_time).abs)/60).round
   9    distance_in_seconds =
  10      ((to_time - from_time).abs).round

8行目あたりの減算でエラーが出ているようです。 実際、以下のような減算をしようとするとエラーが出ます。

   1  Time.now - Date.parse("Mon, 01 Aug 2203").to_time
   2  #=> RangeError: time - 7371010800.000000 out of Time range

ということで、あまりにも長い時間である場合には、 以下のような例外処理で対処するようにしました。

   1  module ActionView
   2    module Helpers
   3      module DateHelper
   4        def distance_of_time_in_words_with_limit(
   5          from_time, to_time = 0, include_seconds = false
   6        )
   7          distance_of_time_in_words_without_limit(
   8            from_time, to_time, include_seconds)
   9        rescue
  10          'a long time'
  11        end
  12        alias_method_chain :distance_of_time_in_words, :limit
  13      end
  14    end
  15  end

これで23世紀の予定も思いのままです。

posted by Png genki on Fri 8 Aug 2008 at 07:10

セキュリティ強化のために、管理画面のURLを若干変更いたしました。 管理画面での各種操作については、 特にこれまでと変わりなく利用できます。

ブラウザ上で管理画面を開いた状態にしている場合は、 お手数ですが一度開きなおしていただけますようお願いいたします。

posted by Png genki on Wed 6 Aug 2008 at 16:37

secondlifeさんのご指摘の通り、 この方法ではうまくいかない事がわかりました。

代案を探してみたところ、 とりあえず以下のようにすることで目的を果たせるようです。

  1. 空ディレクトリとしたいディレクトリ(例えばtmp/)の中に.gitignoreファイルを置く
  2. tmp/をROOTの.gitignoreファイルの中でignoreする
       1  tmp
    
  3. git add tmp/.gitignoreをする。

.gitignoreファイル自体は含まれてしまいますが、 実用上は問題なさそうですね。 しかし、完全な方法は無いものか・・・。

See Also


log/tmp/ディレクトリの中身はignoreしたいけれど、ディレクトリそのものの存在はリポジトリに含めたい場合は、以下のように.gitignoreを書けば良いみたいです。

.gitignore

   1  log/**/*
   2  tmp/**/*

Zshで特定のディレクトリ以下のrbファイルを全部開きたい時などに、

   1  vim **/*.rb

などとやりますが、そんな感じですね。

posted by Png genki on Wed 6 Aug 2008 at 09:37 with 2 comments

このところ、named_scope関係のバグの原因と対処法を調べるために ActiveRecordのEager Loadingの実装を調べていました。 ActiveRecordのEager Loadingは、 Rails2.1から、若干生成するSQLが変化しています。

Rails 2.1 Eager Loading

上記サイトでも紹介されているように、 今まではLEFT OUTER JOINを使って、 一回のクエリで全て読み込むようなSQLを生成していたのですが、 Rails2.1からは、複数回のクエリに分割するようになりました。

ということで、Eager Loadingを実際にやっているコードを調べてみたのですが、自分で好きなタイミングでEager Loadingを行う方法を見つけたので紹介します。

ActiveRecord::BaseクラスのprotectedメソッドActiveRecord.preload_associationsを利用します。

   1  articles = Article.all(:limit => 5)
   2  Article.send :preload_associations, articles, [:user => :face]

1行目は普通にEager LoadingせずにArticleリストを取得していますが、 二行目を実行することで、各ArticleのアソシエイションがEager Load されます。あとは、

   1  articles.first.user.face

などを実行してもSQLクエリは発行されません。 実質的に発行されるSQLは通常の:include を指定した場合と同じになるので、好きなタイミングでEager Load を実行できるようになったといえます。

posted by Png genki on Mon 4 Aug 2008 at 21:10

SQLのログを見ていて気がついたのですが、 最近のActiveRecordは以下のようにEagerLoadingしようとすると、 こんな感じのSQLを発行します。

   1  ?> Article.find(:all, :include => [:user => :face]);1
   2  => 1
   3  >>   Article Load (0.005234)   SELECT * FROM `articles`
   4    User Load (0.000645)   SELECT * FROM `users` WHERE (`users`.id IN ('13','9','37','17','1','3'))
   5    Face Load (0.002931)   SELECT `faces`.* FROM `faces` WHERE (`faces`.user_id IN (1,3,9,13,17,37))

以前のようにJOINを使わずに、3回に分けるようになっているのですね。

しかしながら、条件が複雑になってくると、 :limitオプションとの相性が悪いケースがあるようで、 まだ若干バグがあるようです。 そんな時は手で:joinsを書いています。

posted by Png genki on Sun 3 Aug 2008 at 22:18

いくつか要望をいただいていた、 コピー&ペーストする時に行番号は邪魔になるという問題を解決するために、 コピー&ペーストモードを実装いたしました。 ソース部分をクリックすると、行番号が隠れるようになります。 ソース部分の外をクリックすると元に戻ります。

以下テスト用。

   1  class User < ActiveRecord::Base
   2    has_many :comments
   3  end

  • インデント対応テスト
       1  def foo
       2    puts "foo"
       3  end
    

一行テスト。

   1  Hash.new({})

posted by Png genki on Sun 3 Aug 2008 at 11:49

iPhoneやiPodTouchでホームのボタンに登録する時に利用される、 AppleTouchIconとして、登録された画像を利用できるようにしました。

iPhone/iPodTouchをお持ちの方は、ぜひお試しください。

posted by Png genki on Fri 1 Aug 2008 at 22:18

named_scopeは大変素晴らしいRailsの新しい機能ですが、 おなじみのwith_scopeのように、 スコープつきのブロックを伴った利用ができないという問題がありました。 例えばこんな感じに利用しようとしてもうまくいきません。

   1  User.active do
   2    User.count # => Not run
   3  end
   4  
   5  User.active.with_scope do
   6    User.count #=> Not scoped
   7  end

そこで、昔ながらのwith_scopeと同じようにnamed_scopeを使えるようにする Gemプラグインを作りました。

with_named_scope

これを使うと、以下のように期待通りに動きます。

   1  User.active.with do
   2    User.count #=> User.active.count
   3  end

なかなか便利だと思うので、Rails本家にパッチを送っておきました。

Improved named_scope to be used like as with_scope

posted by Png genki on Fri 1 Aug 2008 at 21:16

以下の記事は、調査の結果現状のRuby on Rails では期待通りに動かないことがわかりました。


Rails-2.1の新機能であるnamed_scopeを使うと、従来のwith_scope では綺麗にかけなかったスコープの選択を簡潔に記述することができます。

   1  def gadgets_on_sidebar(place = 'index')
   2    case place.to_s
   3    when 'index'; Gadget.on_index
   4    when 'show'; Gadget.on_show
   5    else Gadget.all
   6    end.with_scope{active_gadgets + Gadget.mandatories}
   7  end

各スコープメソッドは、ActiveRecord::NamedScope::Scope オブジェクトを返すので、 これを条件にしたがって選択し、最後に.with_scope を呼んでスコープを適用します。


そこで、 with_named_scope というGemプラグインをつくり、 上述のように処理できるようにしました。 以下のようになります。

   1  def gadgets_on_sidebar(place = 'index')
   2    case place.to_s
   3    when 'index'; Gadget.on_index
   4    when 'show'; Gadget.on_show
   5    else Gadget.all
   6    end.with{active_gadgets + Gadget.mandatories}
   7  end

ということで、Rails本家にもpatchを送っておきました。

posted by Png genki on Fri 1 Aug 2008 at 13:52 with 3 comments
Contents
Ruby-1.8.7 p71にアップデート
23世紀の予定を立てる方法
管理画面のURLを変更しました
[間違いを訂正].gitignoreでディレクトリの中身だけをignoreする書き方
自分でEager Loadingが行われるタイミングを決める方法
最近のActiveRecordとEagerLoading
ソースコードのコピー&ペーストモードを実装しました
AppleTouchIconを設定するようにしました
with_named_scope: named_scopeを古き良きwith_scope風味に利用する
[更新]named_scopeでスコープの選択を綺麗に記述する方法
Comments
瀧内元気: MacOS版は以下にあります * [genki/ViMouse](https://githu... '23-1
dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これ... '13-1
瀧内元気: おお、チェックしてみます。thx! '11-12
overisland: Reeder for iPhone もこの UI を実装していますね。 '11-12
瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 ... '11-12
Services from s21g
twpro(ツイプロ)
Twitterプロフィールを快適検索
地価2009
土地の値段を調べてみよう
MyRestaurant
自分だけのレストラン手帳
Formula
ブログに数式を埋め込める数式コミュニティ