[前][次][番号順一覧][スレッド一覧]

ruby-changes:73026

From: David <ko1@a...>
Date: Tue, 23 Aug 2022 05:50:39 +0900 (JST)
Subject: [ruby-changes:73026] 9819283044 (master): [rubygems/rubygems] Handle non-gnu libc on linux platforms in RubyGems

https://git.ruby-lang.org/ruby.git/commit/?id=9819283044

From 9819283044b6955f4e3b464e6a99196e84ed107a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...>
Date: Thu, 4 Aug 2022 13:02:18 +0200
Subject: [rubygems/rubygems] Handle non-gnu libc on linux platforms in
 RubyGems

Attempting to install a gem published as both *-linux and *-linux-musl
results in the incorrect gem being picked up, causing build failures due
to binary incompatibility. This is caused by the `nil` wildcard
swallowing the libc information upon version comparison.

Handle the linux case by performing only non-wildcard equality on the
version and asserting 'gnu' and nil equivalence, while preserving the
current behaviour for other OSes.

https://github.com/rubygems/rubygems/commit/9eead86abc

Co-authored-by: Loic Nageleisen <loic.nageleisen@g...>
---
 lib/rubygems/platform.rb           | 15 +++++++++++++--
 test/rubygems/test_gem_platform.rb | 30 ++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index 0c0520e1db..1f699c23e0 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -151,10 +151,17 @@ class Gem::Platform https://github.com/ruby/ruby/blob/trunk/lib/rubygems/platform.rb#L151
   ##
   # Does +other+ match this platform?  Two platforms match if they have the
   # same CPU, or either has a CPU of 'universal', they have the same OS, and
-  # they have the same version, or either has no version.
+  # they have the same version, or either one has no version
   #
   # Additionally, the platform will match if the local CPU is 'arm' and the
   # other CPU starts with "arm" (for generic ARM family support).
+  #
+  # Of note, this method is not commutative. Indeed the OS 'linux' has a
+  # special case: the version is the libc name, yet while "no version" stands
+  # as a wildcard for a binary gem platform (as for other OSes), for the
+  # runtime platform "no version" stands for 'gnu'. To be able to disinguish
+  # these, the method receiver is the gem platform, while the argument is
+  # the runtime platform.
 
   def ===(other)
     return nil unless Gem::Platform === other
@@ -171,7 +178,11 @@ class Gem::Platform https://github.com/ruby/ruby/blob/trunk/lib/rubygems/platform.rb#L178
       @os == other.os &&
 
       # version
-      (@version.nil? || other.version.nil? || @version == other.version)
+      (
+        (@os != "linux" && (@version.nil? || other.version.nil?)) ||
+        (@os == "linux" && (@version.nil? && !other.version.nil?)) ||
+        @version == other.version
+      )
   end
 
   ##
diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb
index 831079acb2..197f19e53c 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -135,7 +135,9 @@ class TestGemPlatform < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_platform.rb#L135
       "i386-solaris2.8"        => ["x86",       "solaris",   "2.8"],
       "mswin32"                => ["x86",       "mswin32",   nil],
       "x86_64-linux"           => ["x86_64",    "linux",     nil],
+      "x86_64-linux-gnu"       => ["x86_64",    "linux",     nil],
       "x86_64-linux-musl"      => ["x86_64",    "linux",     "musl"],
+      "x86_64-linux-uclibc"    => ["x86_64",    "linux",     "uclibc"],
       "x86_64-openbsd3.9"      => ["x86_64",    "openbsd",   "3.9"],
       "x86_64-openbsd4.0"      => ["x86_64",    "openbsd",   "4.0"],
       "x86_64-openbsd"         => ["x86_64",    "openbsd",   nil],
@@ -263,6 +265,34 @@ class TestGemPlatform < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_platform.rb#L265
     assert((with_x86_arch === with_nil_arch), "x86 =~ nil")
   end
 
+  def test_nil_version_is_treated_as_any_version
+    x86_darwin_8 = Gem::Platform.new "i686-darwin8.0"
+    x86_darwin_nil = Gem::Platform.new "i686-darwin"
+
+    assert((x86_darwin_8 === x86_darwin_nil), "8.0 =~ nil")
+    assert((x86_darwin_nil === x86_darwin_8), "nil =~ 8.0")
+  end
+
+  def test_nil_version_is_stricter_for_linux_os
+    x86_linux = Gem::Platform.new "i686-linux"
+    x86_linux_gnu = Gem::Platform.new "i686-linux-gnu"
+    x86_linux_musl = Gem::Platform.new "i686-linux-musl"
+    x86_linux_uclibc = Gem::Platform.new "i686-linux-uclibc"
+
+    # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime
+    assert(x86_linux === x86_linux_gnu, "linux =~ linux-gnu")
+    assert(x86_linux_gnu === x86_linux, "linux-gnu =~ linux")
+
+    # explicit libc differ
+    refute(x86_linux_uclibc === x86_linux_musl, "linux-uclibc =~ linux-musl")
+    refute(x86_linux_musl === x86_linux_uclibc, "linux-musl =~ linux-uclibc")
+
+    # musl host runtime accepts libc-generic or statically linked gems...
+    assert(x86_linux === x86_linux_musl, "linux =~ linux-musl")
+    # ...but implicit gnu runtime generally does not accept musl-specific gems
+    refute(x86_linux_musl === x86_linux, "linux-musl =~ linux")
+  end
+
   def test_equals3_cpu_arm
     arm   = Gem::Platform.new "arm-linux"
     armv5 = Gem::Platform.new "armv5-linux"
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]