ActiveModel::Type::Boolean.new.castに注意

2023-01-30

rails

とあるプロジェクトで ActiveModel::Type::Boolean.new.cast を多用していました。
しかしユーザーの自由入力(コマンドライン引数)で使用していたので危険だなと思ってメモ。

ActiveModel::Type::Boolean.new.cast とは?

1
2
3
def cast(value)
  cast_value(value) unless value.nil?
end

ふむふむ。nilならnil返して終わり。
cast_value(value)てなんだ?

1
2
3
4
5
6
7
def cast_value(value)
  if value == ""
    nil
  else
    !FALSE_VALUES.include?(value)
  end
end

空文字もnilなのか。FALSE_VALUES にマッチする値だけがfalseになるんだな
FALSE_VALUES はなんだ?

1
2
> ActiveModel::Type::Boolean::FALSE_VALUES
=> #<Set: {false, 0, "0", :"0", "f", :f, "F", :F, "false", :false, "FALSE", :FALSE, "off", :off, "OFF", :OFF}>

こやつら以外は全部trueになっちゃう。
手入力の値を判定させるには危なすぎますね。

プロジェクトでは true | false | nil 以外をエラーにしたいねって話しました

こんな感じでいいんじゃない?

1
2
3
4
5
6
7
def true?(value)
  return nil if value.nil?
  return true if value.to_s.downcase == "true"
  return false if value.to_s.downcase == "false"

  raise ArgumentError.new("曲者!")
end

コメント

投稿する

投稿したコメントはご自身で削除できません

不適切なコメントと判断した場合は管理側で削除することがあります