【发布时间】:2018-12-16 22:31:58
【问题描述】:
有一天我的应用程序宣布所有密码都无效。
经过繁琐的搜索后,问题被发现:密码初始化向量(只是一堆随机位)通过 ENV 提供给应用程序。 Rails 决定将此字符串(任意二进制数据)转换为 UTF-8。
在服务器启动之前,我基本上是这样做的:
ENV["RAILS_ACC_VEC"] = "\xB3n%-\x9E^\xE1\x93 \x17\xEER\x1B\n\x84S"
Rack::Server.start( ...
以后
if Rails.env != "production"
salt = "dummy"
else
salt = ENV["RAILS_ACC_VEC"]
end
位串应为 128 位长。但它恰好是 176 位长并且包含有效的 UTF-8。 (显然,密码程序确实完全失败了。)
应用程序目前在 Rails 4.2.8 和 ruby 2.4 上运行,并使用默认编码。
可以找到问题的原因:通常应用程序是从服务器启动或从部署启动的,环境中没有语言环境。这次它是从控制台启动的,而该控制台恰好设置为 ISO 8859。
结果也很清楚:需要注意应用程序始终以 ENV 中的明确语言环境启动 - LC_CTYPE=C(相当于无语言环境),或者 - 可能更好 - UTF-8(以防万一该应用程序具有默认的config.encoding)。
我现在想弄清楚的是,ruby/rails 何时以及为什么会做这些事情? 我知道转码可能会发生在 IO 对象上,但是可以在打开时指定预期的字符集。
如果系统似乎以 ISO 8859 运行,并且 rails 本身以 UTF-8 运行,那么 ENV 在从外部移动到内部时可能需要转码,这可能是有道理的。但这仅适用于语言,并非所有 ENV 内容都可能是语言。
那么,ENV是如何以二进制方式打开的呢?
那么更野心的问题是,编码功能是否还有更多类似的邪恶危险?
【问题讨论】:
标签: ruby-on-rails ruby utf-8