Ruby 2.7.2 使用 2.7.0 库

Ruby 2.7.2 uses 2.7.0 libraries

我使用 rbenv 安装了 Ruby 2.7.2,但是当我 运行 以下代码时:

require 'webrick'

WEBrick::VERSION
=> "1.6.0"
WEBrick::HTTPUtils.method(:mime_type).source_location
=> ["/Users/my_user/.rbenv/versions/2.7.2/lib/ruby/2.7.0/webrick/httputils.rb", 133]

我有 webrick 1.6 版,其中有一个 security issue which was patched in ruby 2.7.2

这也发生在我们的 dev/prod 环境中,因为我们使用 docker 图像和 ruby 2.7.2,所以,我认为这不是 rbenv 问题。

我想知道的是,为什么我的 ruby 解释器使用的是 2.7.0 版本的库?

What I want to know is, why my ruby interpreter is using libraries from version 2.7.0?

/Users/my_user/.rbenv/versions/2.7.2/lib/ruby/2.7.0/webrick/httputils.rb

这是一个常见的混淆来源。这就是 ruby 的工作原理。

  • 如果你往里看,例如.rbenv/versions/2.6.3 你会发现 2.6.3/lib/ruby/2.6.0.
  • 如果你往里看,例如.rbenv/versions/3.0.2 你会发现 2.6.3/lib/ruby/3.0.0.

这个目录结构已经存在很长时间了,至少从 1.9.3 开始,也许更早。

lib 目录中的版本化目录,即您示例中的 2.6.0 并不表示确切的 Ruby 库文件所属,而是“库兼容版本”。

在过去,即使是次要版本也大不相同,您在那里有诸如 1.8.61.8.7 之类的目录,因为这些 Ruby 版本彼此之间相当不同.然而,他们的补丁版本足够兼容,安装的 gem 应该在该版本范围内兼容。

在 Ruby1.9.x 版本中,这是一个混合包。 Ruby 1.9.0 和 1.9.1 都有各自的版本目录。 Ruby 1.9.2 和 1.9.3 声称与 Ruby 1.9.1 兼容,因此继续使用 1.9.1 目录。 Ruby 1.9.2

the release announcement 中的常见问题解答对此进行了解释

随着Ruby2.x,这个方案被进一步细化。除非有严格的重大更改(目前还没有),否则所有次要版本都使用其第一个小版本的库版本。所有 Ruby 2.1.x 版本因此使用 2.1.0,所有 Ruby 2.7.x 版本使用 2.7.0 等等。

因此,虽然您绝对不应该混合使用多个 ruby 版本的标准库,但 lib 目录中的库版本号在不同的小版本中保持不变。例如,这允许在更新 Ruby 版本时为某个次要版本保留已安装的 gem。

您的 webrick 库的版本就是您想要的版本。在 Ruby 版本中,Ruby 团队刚刚 backported 修复了 webrick 库,而不是修改 while 库。

根据已接受的答案,read the vulnerability notes carefully

Please update the webrick gem to version 1.6.1 or later. You can use gem update webrick to update it. If you are using bundler, please add gem "webrick", ">= 1.6.1" to your Gemfile.

Affected versions

  • webrick gem 1.6.0 or prior
  • bundled versions of webrick in ruby 2.7.1 or prior

没有使用 webrick gem。您正在使用 捆绑版本

您机器上的 Gem 将位于:

/Users/my_user/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/...

但是您的 webrick 图书馆位于:

/Users/my_user/.rbenv/versions/2.7.2/lib/ruby/2.7.0/...

安全修复 was applied to the ruby 2.7.2 bundled version