i9c-stream-3.3
changed/i9c-stream-3.3/ruby-3.3.5-3.module+el9.4.0+22273+463af10f
parent
8d1367a426
commit
e121d65026
@ -1 +1 @@
|
|||||||
SOURCES/ruby-3.3.1.tar.xz
|
SOURCES/ruby-3.3.5.tar.xz
|
||||||
|
@ -1 +1 @@
|
|||||||
88ef585faece4ed76f4330bce52903664d4fbfe0 SOURCES/ruby-3.3.1.tar.xz
|
692bc3188bdb9ec30b8672543961b011d699590a SOURCES/ruby-3.3.5.tar.xz
|
||||||
|
@ -0,0 +1,166 @@
|
|||||||
|
require 'tmpdir'
|
||||||
|
require 'tempfile'
|
||||||
|
require 'fileutils'
|
||||||
|
# Available in Ruby upstream sources under tool/lib/envutil.rb
|
||||||
|
# Required for finding and setting up the built ruby binary.
|
||||||
|
require 'envutil'
|
||||||
|
|
||||||
|
module RPMTestHelper
|
||||||
|
def setup
|
||||||
|
@tmpdir = Dir.mktmpdir
|
||||||
|
@tempfiles = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
@tempfiles.each do |file|
|
||||||
|
file.close
|
||||||
|
file.unlink
|
||||||
|
end
|
||||||
|
|
||||||
|
FileUtils.rmtree(@tmpdir)
|
||||||
|
end
|
||||||
|
|
||||||
|
GENERATOR_SCRIPT = ENV['GENERATOR_SCRIPT'].clone.freeze
|
||||||
|
if GENERATOR_SCRIPT.nil? || GENERATOR_SCRIPT == ''
|
||||||
|
raise "GENERATOR_SCRIPT is not specified." \
|
||||||
|
"Specify the ENV variable with absolute path to the generator."
|
||||||
|
end
|
||||||
|
|
||||||
|
Dependency = Struct.new('Dependency', :name, :requirements) do
|
||||||
|
def to_rpm_str
|
||||||
|
"rubygem(#{self.name})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_gemspec(gem_info)
|
||||||
|
file = Tempfile.new('req_gemspec', @tmpdir)
|
||||||
|
# Fake gemspec with enough to pass most checks
|
||||||
|
# Rubygems uses to validate the format.
|
||||||
|
gemspec_contents = <<~EOF
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
# stub: #{gem_info.name} #{gem_info.version} ruby lib
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = "#{gem_info.name}".freeze
|
||||||
|
s.version = "#{gem_info.version}"
|
||||||
|
|
||||||
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
||||||
|
s.require_paths = ["lib".freeze]
|
||||||
|
s.authors = ["John Doe".freeze]
|
||||||
|
s.bindir = "bin".freeze
|
||||||
|
s.date = "2023-12-15"
|
||||||
|
s.description = "Fake gemspec helper for testing Rubygem Generators".freeze
|
||||||
|
s.email = ["example@example.com".freeze]
|
||||||
|
s.files = ["LICENSE.txt".freeze, "lib/#{gem_info.name}.rb".freeze, "#{gem_info.name}.gemspec".freeze]
|
||||||
|
s.homepage = "https://pkgs.fedoraproject.org/rpms/ruby".freeze
|
||||||
|
s.licenses = ["MIT".freeze]
|
||||||
|
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0".freeze)
|
||||||
|
s.rubygems_version = "3.3.5".freeze
|
||||||
|
s.summary = "Fake gemspec for testing Rubygem Generators".freeze
|
||||||
|
|
||||||
|
if s.respond_to? :specification_version then
|
||||||
|
s.specification_version = 4
|
||||||
|
end
|
||||||
|
|
||||||
|
if s.respond_to? :add_runtime_dependency then
|
||||||
|
#{gem_info.gemspec_runtime_dep_str}
|
||||||
|
else
|
||||||
|
#{gem_info.gemspec_dep_str}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
EOF
|
||||||
|
|
||||||
|
file.write gemspec_contents
|
||||||
|
file.rewind
|
||||||
|
@tempfiles << file
|
||||||
|
file
|
||||||
|
end
|
||||||
|
|
||||||
|
# Caller is expected to close subprocess stdin via #close_write
|
||||||
|
# in order to let subprocess proceed if the process is reading
|
||||||
|
# from STDIN in a loop.
|
||||||
|
def rb_subprocess(*args)
|
||||||
|
args = [GENERATOR_SCRIPT] if args.empty?
|
||||||
|
ruby = EnvUtil.rubybin
|
||||||
|
f = IO.popen([ruby] + args, 'r+') #, external_encoding: external_encoding)
|
||||||
|
yield(f)
|
||||||
|
ensure
|
||||||
|
f.close unless !f || f.closed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_generator_single_file(gem_info)
|
||||||
|
lines = []
|
||||||
|
gemspec_f = make_gemspec(gem_info)
|
||||||
|
|
||||||
|
rb_subprocess do |io|
|
||||||
|
io.write gemspec_f.path
|
||||||
|
io.close_write
|
||||||
|
lines = io.readlines
|
||||||
|
end
|
||||||
|
|
||||||
|
lines
|
||||||
|
end
|
||||||
|
|
||||||
|
def helper_rubygems_dependency
|
||||||
|
"ruby(rubygems)"
|
||||||
|
end
|
||||||
|
|
||||||
|
class GemInfo
|
||||||
|
attr_accessor :name, :version, :dependencies
|
||||||
|
|
||||||
|
def initialize(name: 'foo', version: '1.2.3', dependencies: [])
|
||||||
|
@name = name
|
||||||
|
@version = version
|
||||||
|
@dependencies = dependencies
|
||||||
|
end
|
||||||
|
|
||||||
|
def dependencies=(other)
|
||||||
|
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Expected array of `Dependency' elements" \
|
||||||
|
unless other.is_a?(Array) && other.all? { |elem| elem.respond_to?(:name) && elem.respond_to?(:requirements) }
|
||||||
|
|
||||||
|
@dependencies = other
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_rpm_str
|
||||||
|
"rubygem(#{self.name})"
|
||||||
|
end
|
||||||
|
|
||||||
|
def gemspec_dep_str
|
||||||
|
return '' if self.dependencies.nil? || self.dependencies.empty?
|
||||||
|
@dependencies.inject("") do |memo, dep|
|
||||||
|
memo += if dep.requirements && !dep.requirements.empty?
|
||||||
|
%Q|s.add_dependency(%q<#{dep.name}>.freeze, #{handle_dep_requirements(dep.requirements)})|
|
||||||
|
else
|
||||||
|
%Q|s.add_dependency(%q<#{dep.name}>.freeze)|
|
||||||
|
end
|
||||||
|
|
||||||
|
memo += "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def gemspec_runtime_dep_str
|
||||||
|
return '' if self.dependencies.nil? || self.dependencies.empty?
|
||||||
|
|
||||||
|
@dependencies.inject("") do |memo, dep|
|
||||||
|
memo += if dep.requirements && !dep.requirements.empty?
|
||||||
|
%Q|s.add_runtime_dependency(%q<#{dep.name}>.freeze, #{handle_dep_requirements(dep.requirements)})|
|
||||||
|
else
|
||||||
|
%Q|s.add_runtime_dependency(%q<#{dep.name}>.freeze)|
|
||||||
|
end
|
||||||
|
|
||||||
|
memo += "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def handle_dep_requirements(reqs)
|
||||||
|
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Reqs must be an array." \
|
||||||
|
unless reqs.is_a? Array
|
||||||
|
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Reqs must not be empty for this method." \
|
||||||
|
if reqs.empty?
|
||||||
|
|
||||||
|
'[ "' + reqs.join('", "') + '" ]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,92 +0,0 @@
|
|||||||
From 8944a064d0fd7947b8c2b6c761be3e3a0c9073af Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
|
|
||||||
Date: Fri, 22 Dec 2023 14:16:48 +0100
|
|
||||||
Subject: [PATCH 1/2] Revert "compare_by_identity: remove alloc for non-empty
|
|
||||||
Hash"
|
|
||||||
|
|
||||||
This reverts commit 11fa76b1b521072c200c78ea023960221ff426d6.
|
|
||||||
---
|
|
||||||
hash.c | 13 ++++---------
|
|
||||||
1 file changed, 4 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hash.c b/hash.c
|
|
||||||
index 78e9d9a2d6..f6525ba4a5 100644
|
|
||||||
--- a/hash.c
|
|
||||||
+++ b/hash.c
|
|
||||||
@@ -4385,16 +4385,13 @@ rb_hash_compare_by_id(VALUE hash)
|
|
||||||
if (hash_iterating_p(hash)) {
|
|
||||||
rb_raise(rb_eRuntimeError, "compare_by_identity during iteration");
|
|
||||||
}
|
|
||||||
+ ar_force_convert_table(hash, __FILE__, __LINE__);
|
|
||||||
+ HASH_ASSERT(RHASH_ST_TABLE_P(hash));
|
|
||||||
|
|
||||||
if (RHASH_TABLE_EMPTY_P(hash)) {
|
|
||||||
// Fast path: There's nothing to rehash, so we don't need a `tmp` table.
|
|
||||||
- // We're most likely an AR table, so this will need an allocation.
|
|
||||||
- ar_force_convert_table(hash, __FILE__, __LINE__);
|
|
||||||
- HASH_ASSERT(RHASH_ST_TABLE_P(hash));
|
|
||||||
-
|
|
||||||
RHASH_ST_TABLE(hash)->type = &identhash;
|
|
||||||
- }
|
|
||||||
- else {
|
|
||||||
+ } else {
|
|
||||||
// Slow path: Need to rehash the members of `self` into a new
|
|
||||||
// `tmp` table using the new `identhash` compare/hash functions.
|
|
||||||
tmp = hash_alloc(0);
|
|
||||||
@@ -4402,10 +4399,8 @@ rb_hash_compare_by_id(VALUE hash)
|
|
||||||
identtable = RHASH_ST_TABLE(tmp);
|
|
||||||
|
|
||||||
rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
|
|
||||||
- rb_hash_free(hash);
|
|
||||||
|
|
||||||
- // We know for sure `identtable` is an st table,
|
|
||||||
- // so we can skip `ar_force_convert_table` here.
|
|
||||||
+ rb_hash_free(hash);
|
|
||||||
RHASH_ST_TABLE_SET(hash, identtable);
|
|
||||||
RHASH_ST_CLEAR(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
From f5c415300ffe63e41e46c6b88b8634a3bad0c7c2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
|
|
||||||
Date: Fri, 22 Dec 2023 14:17:14 +0100
|
|
||||||
Subject: [PATCH 2/2] Revert "compare_by_identity: remove alloc for empty Hash"
|
|
||||||
|
|
||||||
This reverts commit b5c6c0122f5b010cb5f43e7a236c4ba2b1d56a2a.
|
|
||||||
---
|
|
||||||
hash.c | 21 +++++++--------------
|
|
||||||
1 file changed, 7 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hash.c b/hash.c
|
|
||||||
index f6525ba4a5..cf83675c70 100644
|
|
||||||
--- a/hash.c
|
|
||||||
+++ b/hash.c
|
|
||||||
@@ -4388,22 +4388,15 @@ rb_hash_compare_by_id(VALUE hash)
|
|
||||||
ar_force_convert_table(hash, __FILE__, __LINE__);
|
|
||||||
HASH_ASSERT(RHASH_ST_TABLE_P(hash));
|
|
||||||
|
|
||||||
- if (RHASH_TABLE_EMPTY_P(hash)) {
|
|
||||||
- // Fast path: There's nothing to rehash, so we don't need a `tmp` table.
|
|
||||||
- RHASH_ST_TABLE(hash)->type = &identhash;
|
|
||||||
- } else {
|
|
||||||
- // Slow path: Need to rehash the members of `self` into a new
|
|
||||||
- // `tmp` table using the new `identhash` compare/hash functions.
|
|
||||||
- tmp = hash_alloc(0);
|
|
||||||
- hash_st_table_init(tmp, &identhash, RHASH_SIZE(hash));
|
|
||||||
- identtable = RHASH_ST_TABLE(tmp);
|
|
||||||
+ tmp = hash_alloc(0);
|
|
||||||
+ hash_st_table_init(tmp, &identhash, RHASH_SIZE(hash));
|
|
||||||
+ identtable = RHASH_ST_TABLE(tmp);
|
|
||||||
|
|
||||||
- rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
|
|
||||||
+ rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
|
|
||||||
|
|
||||||
- rb_hash_free(hash);
|
|
||||||
- RHASH_ST_TABLE_SET(hash, identtable);
|
|
||||||
- RHASH_ST_CLEAR(tmp);
|
|
||||||
- }
|
|
||||||
+ rb_hash_free(hash);
|
|
||||||
+ RHASH_ST_TABLE_SET(hash, identtable);
|
|
||||||
+ RHASH_ST_CLEAR(tmp);
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
@ -0,0 +1,302 @@
|
|||||||
|
From 3d405634f43d39079ee93cdc59ed7fc0a5e8917a Mon Sep 17 00:00:00 2001
|
||||||
|
From: KJ Tsanaktsidis <kj@kjtsanaktsidis.id.au>
|
||||||
|
Date: Sun, 9 Jun 2024 21:15:39 +1000
|
||||||
|
Subject: [PATCH] Extract hardening CFLAGS to a special $hardenflags variable
|
||||||
|
|
||||||
|
This changes the automatic detection of -fstack-protector,
|
||||||
|
-D_FORTIFY_SOURCE, and -mbranch-protection to write to $hardenflags
|
||||||
|
instead of $XCFLAGS. The definition of $cflags is changed to
|
||||||
|
"$hardenflags $orig_cflags $optflags $debugflags $warnflags" to match.
|
||||||
|
|
||||||
|
Furthermore, these flags are _prepended_ to $hardenflags, rather than
|
||||||
|
appended.
|
||||||
|
|
||||||
|
The implications of doing this are as follows:
|
||||||
|
|
||||||
|
* If a CRuby builder specifies cflags="-mbranch-protection=foobar" at
|
||||||
|
the ./configure script, and the configure script detects that
|
||||||
|
-mbranch-protection=pac-ret is accepted, then GCC will be invoked as
|
||||||
|
"gcc -mbranch-protection=pac-ret -mbranch-protection=foobar". Since
|
||||||
|
the last flags take precedence, that means that user-supplied values
|
||||||
|
of these flags in $cflags will take priority.
|
||||||
|
* Likewise, if a CRuby builder explicitly specifies
|
||||||
|
"hardenflags=-mbranch-protection=foobar", because we _prepend_ to
|
||||||
|
$hardenflags in our autoconf script, we will still invoke GCC as
|
||||||
|
"gcc -mbranch-protection=pac-ret -mbranch-protection=foobar".
|
||||||
|
* If a CRuby builder specifies CFLAGS="..." at the configure line,
|
||||||
|
automatic detection of hardening flags is ignored as before.
|
||||||
|
* C extensions will _also_ be built with hardening flags now as well
|
||||||
|
(this was not the case by default before because the detected flags
|
||||||
|
went into $XCFLAGS).
|
||||||
|
|
||||||
|
Additionally, as part of this work, I changed how the detection of
|
||||||
|
PAC/BTI in Context.S works. Rather than appending the autodetected
|
||||||
|
option to ASFLAGS, we simply compile a set of test programs with the
|
||||||
|
actual CFLAGS in use to determine what PAC/BTI settings were actually
|
||||||
|
chosen by the builder. Context.S is made aware of these choices through
|
||||||
|
some custom macros.
|
||||||
|
|
||||||
|
The result of this work is that:
|
||||||
|
|
||||||
|
* Ruby will continue to choose some sensible defaults for hardening
|
||||||
|
options for the C compiler
|
||||||
|
* Distributors are able to specify CFLAGS that are consistent with their
|
||||||
|
distribution and override these defaults
|
||||||
|
* Context.S will react to whatever -mbranch-protection is actually in
|
||||||
|
use, not what was autodetected
|
||||||
|
* Extensions get built with hardening flags too.
|
||||||
|
|
||||||
|
[Bug #20154]
|
||||||
|
[Bug #20520]
|
||||||
|
---
|
||||||
|
configure.ac | 81 ++++++++++++++++++++++++++++++-----
|
||||||
|
coroutine/arm64/Context.S | 14 +++---
|
||||||
|
template/Makefile.in | 1 +
|
||||||
|
tool/m4/ruby_append_option.m4 | 4 ++
|
||||||
|
tool/m4/ruby_try_cflags.m4 | 17 ++++++++
|
||||||
|
5 files changed, 100 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index f35fad6a362611..0da15772d36671 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -354,7 +354,7 @@ test -z "$warnflags" ||
|
||||||
|
AS_IF([test -z "${CFLAGS+set}"], [
|
||||||
|
cflags=`echo " $cflags " | sed "$cflagspat;s/^ *//;s/ *$//"`
|
||||||
|
orig_cflags="$cflags"
|
||||||
|
- cflags="$cflags "'${optflags} ${debugflags} ${warnflags}'
|
||||||
|
+ cflags='${hardenflags} '"$cflags "'${optflags} ${debugflags} ${warnflags}'
|
||||||
|
])
|
||||||
|
dnl AS_IF([test -z "${CXXFLAGS+set}"], [
|
||||||
|
dnl cxxflags=`echo " $cxxflags " | sed "$cflagspat;s/^ *//;s/ *$//"`
|
||||||
|
@@ -802,7 +802,7 @@ AS_IF([test "$GCC" = yes], [
|
||||||
|
[fortify_source=$enableval])
|
||||||
|
AS_IF([test "x$fortify_source" != xno], [
|
||||||
|
RUBY_TRY_CFLAGS([$optflags -D_FORTIFY_SOURCE=2],
|
||||||
|
- [RUBY_APPEND_OPTION(XCFLAGS, -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2)], [],
|
||||||
|
+ [RUBY_PREPEND_OPTION(hardenflags, -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2)], [],
|
||||||
|
[@%:@include <stdio.h>])
|
||||||
|
])
|
||||||
|
|
||||||
|
@@ -823,20 +823,24 @@ AS_IF([test "$GCC" = yes], [
|
||||||
|
AC_MSG_CHECKING([for -fstack-protector])
|
||||||
|
AC_MSG_RESULT(["$stack_protector"])
|
||||||
|
AS_CASE(["$stack_protector"], [-*], [
|
||||||
|
- RUBY_APPEND_OPTION(XCFLAGS, $stack_protector)
|
||||||
|
- RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector)
|
||||||
|
- RUBY_APPEND_OPTION(LDFLAGS, $stack_protector)
|
||||||
|
+ RUBY_PREPEND_OPTION(hardenflags, $stack_protector)
|
||||||
|
+ RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector)
|
||||||
|
+ RUBY_APPEND_OPTION(LDFLAGS, $stack_protector)
|
||||||
|
])
|
||||||
|
|
||||||
|
# aarch64 branch protection
|
||||||
|
AS_CASE(["$target_cpu"], [aarch64], [
|
||||||
|
AS_FOR(option, opt, [-mbranch-protection=pac-ret -msign-return-address=all], [
|
||||||
|
- RUBY_TRY_CFLAGS(option, [branch_protection=yes], [branch_protection=no])
|
||||||
|
+ # Try these flags in the _prepended_ position - i.e. we want to try building a program
|
||||||
|
+ # with CFLAGS="-mbranch-protection=pac-ret $CFLAGS". If the builder has provided different
|
||||||
|
+ # branch protection flags in CFLAGS, we don't want to overwrite those. We just want to
|
||||||
|
+ # find some branch protection flags which work if none were provided.
|
||||||
|
+ RUBY_TRY_CFLAGS_PREPEND(option, [branch_protection=yes], [branch_protection=no])
|
||||||
|
AS_IF([test "x$branch_protection" = xyes], [
|
||||||
|
- # C compiler and assembler must be consistent for -mbranch-protection
|
||||||
|
- # since they both check `__ARM_FEATURE_PAC_DEFAULT` definition.
|
||||||
|
- RUBY_APPEND_OPTION(XCFLAGS, option)
|
||||||
|
- RUBY_APPEND_OPTION(ASFLAGS, option)
|
||||||
|
+ # _prepend_ the options to CFLAGS, so that user-provided flags will overwrite them.
|
||||||
|
+ # These CFLAGS are used during the configure script to compile further test programs;
|
||||||
|
+ # however, $harden_flags is prepended separately to CFLAGS at the end of the script.
|
||||||
|
+ RUBY_PREPEND_OPTION(hardenflags, $opt)
|
||||||
|
break
|
||||||
|
])
|
||||||
|
])
|
||||||
|
@@ -985,6 +989,59 @@ test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $
|
||||||
|
test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\""
|
||||||
|
}
|
||||||
|
|
||||||
|
+# The lines above expand out the $cflags/$optflags/$debugflags/$hardenflags variables into the
|
||||||
|
+# CFLAGS variable. So, at this point, we have a $CFLAGS var with the actual compiler flags we're
|
||||||
|
+# going to use.
|
||||||
|
+# That means this is the right time to check what branch protection flags are going to be in use
|
||||||
|
+# and define appropriate macros for use in Context.S based on this
|
||||||
|
+AS_CASE(["$target_cpu"], [aarch64], [
|
||||||
|
+ AC_CACHE_CHECK([whether __ARM_FEATURE_BTI_DEFAULT is defined],
|
||||||
|
+ rb_cv_aarch64_bti_enabled,
|
||||||
|
+ AC_COMPILE_IFELSE(
|
||||||
|
+ [AC_LANG_PROGRAM([[
|
||||||
|
+ @%:@ifndef __ARM_FEATURE_BTI_DEFAULT
|
||||||
|
+ @%:@error "__ARM_FEATURE_BTI_DEFAULT not defined"
|
||||||
|
+ @%:@endif
|
||||||
|
+ ]])],
|
||||||
|
+ [rb_cv_aarch64_bti_enabled=yes],
|
||||||
|
+ [rb_cv_aarch64_bti_enabled=no])
|
||||||
|
+ )
|
||||||
|
+ AS_IF([test "$rb_cv_aarch64_bti_enabled" = yes],
|
||||||
|
+ AC_DEFINE(RUBY_AARCH64_BTI_ENABLED, 1))
|
||||||
|
+ AC_CACHE_CHECK([whether __ARM_FEATURE_PAC_DEFAULT is defined],
|
||||||
|
+ rb_cv_aarch64_pac_enabled,
|
||||||
|
+ AC_COMPILE_IFELSE(
|
||||||
|
+ [AC_LANG_PROGRAM([[
|
||||||
|
+ @%:@ifndef __ARM_FEATURE_PAC_DEFAULT
|
||||||
|
+ @%:@error "__ARM_FEATURE_PAC_DEFAULT not defined"
|
||||||
|
+ @%:@endif
|
||||||
|
+ ]])],
|
||||||
|
+ [rb_cv_aarch64_pac_enabled=yes],
|
||||||
|
+ [rb_cv_aarch64_pac_enabled=no])
|
||||||
|
+ )
|
||||||
|
+ AS_IF([test "$rb_cv_aarch64_pac_enabled" = yes],
|
||||||
|
+ AC_DEFINE(RUBY_AARCH64_PAC_ENABLED, 1))
|
||||||
|
+ # Context.S will only ever sign its return address with the A-key; it doesn't support
|
||||||
|
+ # the B-key at the moment.
|
||||||
|
+ AS_IF([test "$rb_cv_aarch64_pac_enabled" = yes], [
|
||||||
|
+ AC_CACHE_CHECK([whether __ARM_FEATURE_PAC_DEFAULT specifies the b-key bit 0x02],
|
||||||
|
+ rb_cv_aarch64_pac_b_key,
|
||||||
|
+ AC_COMPILE_IFELSE(
|
||||||
|
+ [AC_LANG_PROGRAM([[
|
||||||
|
+ @%:@ifdef __ARM_FEATURE_PAC_DEFAULT
|
||||||
|
+ @%:@if __ARM_FEATURE_PAC_DEFAULT & 0x02
|
||||||
|
+ @%:@error "__ARM_FEATURE_PAC_DEFAULT specifies B key"
|
||||||
|
+ @%:@endif
|
||||||
|
+ @%:@endif
|
||||||
|
+ ]])],
|
||||||
|
+ [rb_cv_aarch64_pac_b_key=no],
|
||||||
|
+ [rb_cv_aarch64_pac_b_key=yes])
|
||||||
|
+ )
|
||||||
|
+ AS_IF([test "$rb_cv_aarch64_pac_b_key" = yes],
|
||||||
|
+ AC_MSG_ERROR(-mbranch-protection flag specified b-key but Ruby's Context.S does not support this yet.))
|
||||||
|
+ ])
|
||||||
|
+])
|
||||||
|
+
|
||||||
|
AC_CACHE_CHECK([whether compiler has statement and declarations in expressions],
|
||||||
|
rb_cv_have_stmt_and_decl_in_expr,
|
||||||
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[ __extension__ ({ int a = 0; a; }); ]])],
|
||||||
|
@@ -4215,12 +4272,13 @@ AS_IF([test "${ARCH_FLAG}"], [
|
||||||
|
rb_cv_warnflags=`echo "$rb_cv_warnflags" | sed 's/^ *//;s/ *$//'`
|
||||||
|
warnflags="$rb_cv_warnflags"
|
||||||
|
AC_SUBST(cppflags)dnl
|
||||||
|
-AC_SUBST(cflags, ["${orig_cflags:+$orig_cflags }"'${optflags} ${debugflags} ${warnflags}'])dnl
|
||||||
|
+AC_SUBST(cflags, ['${hardenflags} '"${orig_cflags:+$orig_cflags }"' ${optflags} ${debugflags} ${warnflags}'])dnl
|
||||||
|
AC_SUBST(cxxflags)dnl
|
||||||
|
AC_SUBST(optflags)dnl
|
||||||
|
AC_SUBST(debugflags)dnl
|
||||||
|
AC_SUBST(warnflags)dnl
|
||||||
|
AC_SUBST(strict_warnflags)dnl
|
||||||
|
+AC_SUBST(hardenflags)dnl
|
||||||
|
AC_SUBST(XCFLAGS)dnl
|
||||||
|
AC_SUBST(XLDFLAGS)dnl
|
||||||
|
AC_SUBST(EXTLDFLAGS)dnl
|
||||||
|
@@ -4688,6 +4746,7 @@ config_summary "DLDFLAGS" "$DLDFLAGS"
|
||||||
|
config_summary "optflags" "$optflags"
|
||||||
|
config_summary "debugflags" "$debugflags"
|
||||||
|
config_summary "warnflags" "$warnflags"
|
||||||
|
+config_summary "hardenflags" "$hardenflags"
|
||||||
|
config_summary "strip command" "$STRIP"
|
||||||
|
config_summary "install doc" "$DOCTARGETS"
|
||||||
|
config_summary "YJIT support" "$YJIT_SUPPORT"
|
||||||
|
diff --git a/coroutine/arm64/Context.S b/coroutine/arm64/Context.S
|
||||||
|
index 5251ab214df1f0..54611a247e2f66 100644
|
||||||
|
--- a/coroutine/arm64/Context.S
|
||||||
|
+++ b/coroutine/arm64/Context.S
|
||||||
|
@@ -5,6 +5,8 @@
|
||||||
|
## Copyright, 2018, by Samuel Williams.
|
||||||
|
##
|
||||||
|
|
||||||
|
+#include "ruby/config.h"
|
||||||
|
+
|
||||||
|
#define TOKEN_PASTE(x,y) x##y
|
||||||
|
#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
|
||||||
|
|
||||||
|
@@ -27,10 +29,10 @@
|
||||||
|
.global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
|
||||||
|
PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
|
||||||
|
|
||||||
|
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0)
|
||||||
|
+#if defined(RUBY_AARCH64_PAC_ENABLED)
|
||||||
|
# paciasp (it also acts as BTI landing pad, so no need to insert BTI also)
|
||||||
|
hint #25
|
||||||
|
-#elif defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT != 0)
|
||||||
|
+#elif defined(RUBY_AARCH64_BTI_ENABLED)
|
||||||
|
# For the the case PAC is not enabled but BTI is.
|
||||||
|
# bti c
|
||||||
|
hint #34
|
||||||
|
@@ -73,7 +75,7 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
|
||||||
|
# Pop stack frame
|
||||||
|
add sp, sp, 0xa0
|
||||||
|
|
||||||
|
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0)
|
||||||
|
+#if defined(RUBY_AARCH64_PAC_ENABLED)
|
||||||
|
# autiasp: Authenticate x30 (LR) with SP and key A
|
||||||
|
hint #29
|
||||||
|
#endif
|
||||||
|
@@ -85,18 +87,18 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
|
||||||
|
.section .note.GNU-stack,"",%progbits
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if __ARM_FEATURE_BTI_DEFAULT != 0 || __ARM_FEATURE_PAC_DEFAULT != 0
|
||||||
|
+#if defined(RUBY_AARCH64_BTI_ENABLED) || defined(RUBY_AARCH64_PAC_ENABLED)
|
||||||
|
/* See "ELF for the Arm 64-bit Architecture (AArch64)"
|
||||||
|
https://github.com/ARM-software/abi-aa/blob/2023Q3/aaelf64/aaelf64.rst#program-property */
|
||||||
|
# define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1<<0)
|
||||||
|
# define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1<<1)
|
||||||
|
|
||||||
|
-# if __ARM_FEATURE_BTI_DEFAULT != 0
|
||||||
|
+# if defined(RUBY_AARCH64_BTI_ENABLED)
|
||||||
|
# define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI
|
||||||
|
# else
|
||||||
|
# define BTI_FLAG 0
|
||||||
|
# endif
|
||||||
|
-# if __ARM_FEATURE_PAC_DEFAULT != 0
|
||||||
|
+# if defined(RUBY_AARCH64_PAC_ENABLED)
|
||||||
|
# define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC
|
||||||
|
# else
|
||||||
|
# define PAC_FLAG 0
|
||||||
|
diff --git a/template/Makefile.in b/template/Makefile.in
|
||||||
|
index 033ac56cb38886..abb4469777ce8a 100644
|
||||||
|
--- a/template/Makefile.in
|
||||||
|
+++ b/template/Makefile.in
|
||||||
|
@@ -89,6 +89,7 @@ cflags = @cflags@
|
||||||
|
optflags = @optflags@
|
||||||
|
debugflags = @debugflags@
|
||||||
|
warnflags = @warnflags@ @strict_warnflags@
|
||||||
|
+hardenflags = @hardenflags@
|
||||||
|
cppflags = @cppflags@
|
||||||
|
incflags = @incflags@
|
||||||
|
RUBY_DEVEL = @RUBY_DEVEL@ # "yes" or empty
|
||||||
|
diff --git a/tool/m4/ruby_append_option.m4 b/tool/m4/ruby_append_option.m4
|
||||||
|
index ff828d2162c22f..98359fa1f95f52 100644
|
||||||
|
--- a/tool/m4/ruby_append_option.m4
|
||||||
|
+++ b/tool/m4/ruby_append_option.m4
|
||||||
|
@@ -3,3 +3,7 @@ AC_DEFUN([RUBY_APPEND_OPTION],
|
||||||
|
[# RUBY_APPEND_OPTION($1)
|
||||||
|
AS_CASE([" [$]{$1-} "],
|
||||||
|
[*" $2 "*], [], [' '], [ $1="$2"], [ $1="[$]$1 $2"])])dnl
|
||||||
|
+AC_DEFUN([RUBY_PREPEND_OPTION],
|
||||||
|
+ [# RUBY_APPEND_OPTION($1)
|
||||||
|
+ AS_CASE([" [$]{$1-} "],
|
||||||
|
+ [*" $2 "*], [], [' '], [ $1="$2"], [ $1="$2 [$]$1"])])dnl
|
||||||
|
diff --git a/tool/m4/ruby_try_cflags.m4 b/tool/m4/ruby_try_cflags.m4
|
||||||
|
index b74718fe5e1cef..b397642aad9ca2 100644
|
||||||
|
--- a/tool/m4/ruby_try_cflags.m4
|
||||||
|
+++ b/tool/m4/ruby_try_cflags.m4
|
||||||
|
@@ -22,3 +22,20 @@ AC_DEFUN([RUBY_TRY_CFLAGS], [
|
||||||
|
AC_MSG_RESULT(no)],
|
||||||
|
[$4], [$5])
|
||||||
|
])dnl
|
||||||
|
+
|
||||||
|
+AC_DEFUN([_RUBY_TRY_CFLAGS_PREPEND], [
|
||||||
|
+ RUBY_WERROR_FLAG([
|
||||||
|
+ CFLAGS="$1 [$]CFLAGS"
|
||||||
|
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$4]], [[$5]])],
|
||||||
|
+ [$2], [$3])
|
||||||
|
+ ])dnl
|
||||||
|
+])dnl
|
||||||
|
+AC_DEFUN([RUBY_TRY_CFLAGS_PREPEND], [
|
||||||
|
+ AC_MSG_CHECKING([whether ]$1[ is accepted as CFLAGS])dnl
|
||||||
|
+ _RUBY_TRY_CFLAGS_PREPEND([$1],
|
||||||
|
+ [$2
|
||||||
|
+ AC_MSG_RESULT(yes)],
|
||||||
|
+ [$3
|
||||||
|
+ AC_MSG_RESULT(no)],
|
||||||
|
+ [$4], [$5])
|
||||||
|
+])dnl
|
@ -1,24 +0,0 @@
|
|||||||
From 055613fd868a8c94e43893f8c58a00cdd2a81f6d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|
||||||
Date: Fri, 22 Mar 2024 18:18:35 +0900
|
|
||||||
Subject: [PATCH] Fix pointer incompatiblity
|
|
||||||
|
|
||||||
Since the subsecond part is discarded, WIDEVAL to VALUE conversion is
|
|
||||||
needed.
|
|
||||||
---
|
|
||||||
time.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/time.c b/time.c
|
|
||||||
index 6179b081c02fc9..3304b2f4f4856a 100644
|
|
||||||
--- a/time.c
|
|
||||||
+++ b/time.c
|
|
||||||
@@ -2342,7 +2342,7 @@ zone_timelocal(VALUE zone, VALUE time)
|
|
||||||
struct time_object *tobj = RTYPEDDATA_GET_DATA(time);
|
|
||||||
wideval_t t, s;
|
|
||||||
|
|
||||||
- split_second(tobj->timew, &t, &s);
|
|
||||||
+ wdivmod(tobj->timew, WINT2FIXWV(TIME_SCALE), &t, &s);
|
|
||||||
tm = tm_from_time(rb_cTimeTM, time);
|
|
||||||
utc = rb_check_funcall(zone, id_local_to_utc, 1, &tm);
|
|
||||||
if (UNDEF_P(utc)) return 0;
|
|
@ -1,24 +0,0 @@
|
|||||||
From db4ba95bf12f9303e38a9a78979cd363cb9a19fb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jarek Prokop <jprokop@redhat.com>
|
|
||||||
Date: Fri, 12 Jan 2024 18:33:34 +0100
|
|
||||||
Subject: [PATCH] aarch64: Prepend -mbranch-protection=standard option when
|
|
||||||
checking branch protection.
|
|
||||||
|
|
||||||
Related Upstream issue: https://bugs.ruby-lang.org/issues/20154
|
|
||||||
---
|
|
||||||
configure.ac | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index 18b4247991..5ea8ada8f7 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -827,7 +827,7 @@ AS_IF([test "$GCC" = yes], [
|
|
||||||
|
|
||||||
# aarch64 branch protection
|
|
||||||
AS_CASE(["$target_cpu"], [aarch64], [
|
|
||||||
- AS_FOR(option, opt, [-mbranch-protection=pac-ret -msign-return-address=all], [
|
|
||||||
+ AS_FOR(option, opt, [-mbranch-protection=standard -mbranch-protection=pac-ret -msign-return-address=all], [
|
|
||||||
RUBY_TRY_CFLAGS(option, [branch_protection=yes], [branch_protection=no])
|
|
||||||
AS_IF([test "x$branch_protection" = xyes], [
|
|
||||||
# C compiler and assembler must be consistent for -mbranch-protection
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 2daad257bee7a500e18ebe553e79487b267fb140 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
Date: Mon, 12 Aug 2024 20:18:34 +0900
|
||||||
|
Subject: [PATCH] Avoid another race condition of open mode
|
||||||
|
|
||||||
|
Instead, just open in CREATE and APPEND mode.
|
||||||
|
Also, move the workaround for old Solaris as fallback to retry.
|
||||||
|
---
|
||||||
|
lib/rubygems.rb | 14 +++++---------
|
||||||
|
1 file changed, 5 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
|
||||||
|
index 2b52cde0a749..c51ba69203cb 100644
|
||||||
|
--- a/lib/rubygems.rb
|
||||||
|
+++ b/lib/rubygems.rb
|
||||||
|
@@ -778,24 +778,20 @@ def self.open_file(path, flags, &block)
|
||||||
|
File.open(path, flags, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
+ MODE_TO_FLOCK = IO::RDONLY | IO::APPEND | IO::CREAT # :nodoc:
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# Open a file with given flags, and protect access with flock
|
||||||
|
|
||||||
|
def self.open_file_with_flock(path, &block)
|
||||||
|
- flags = File.exist?(path) ? "r+" : "a+"
|
||||||
|
-
|
||||||
|
- File.open(path, flags) do |io|
|
||||||
|
+ File.open(path, MODE_TO_FLOCK) do |io|
|
||||||
|
begin
|
||||||
|
io.flock(File::LOCK_EX)
|
||||||
|
rescue Errno::ENOSYS, Errno::ENOTSUP
|
||||||
|
+ rescue Errno::ENOLCK # NFS
|
||||||
|
+ raise unless Thread.main == Thread.current
|
||||||
|
end
|
||||||
|
yield io
|
||||||
|
- rescue Errno::ENOLCK # NFS
|
||||||
|
- if Thread.main != Thread.current
|
||||||
|
- raise
|
||||||
|
- else
|
||||||
|
- open_file(path, flags, &block)
|
||||||
|
- end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,183 @@
|
|||||||
|
From ace303c2d7bc0d98407e5e8b1ca77de07aa0eb75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
Date: Tue, 13 Aug 2024 17:19:41 +0900
|
||||||
|
Subject: [PATCH 1/3] Remove the lock file for binstubs
|
||||||
|
|
||||||
|
https://github.com/rubygems/rubygems/pull/7806#issuecomment-2241662488
|
||||||
|
---
|
||||||
|
lib/rubygems.rb | 2 +-
|
||||||
|
lib/rubygems/installer.rb | 3 ++-
|
||||||
|
test/rubygems/test_gem_installer.rb | 10 ++++++++++
|
||||||
|
3 files changed, 13 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
|
||||||
|
index bd9f240e2091..7626ccfdf0d6 100644
|
||||||
|
--- a/lib/rubygems.rb
|
||||||
|
+++ b/lib/rubygems.rb
|
||||||
|
@@ -778,7 +778,7 @@ def self.open_file(path, flags, &block)
|
||||||
|
File.open(path, flags, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
- MODE_TO_FLOCK = IO::RDONLY | IO::APPEND | IO::CREAT # :nodoc:
|
||||||
|
+ MODE_TO_FLOCK = IO::RDONLY | IO::APPEND | IO::CREAT | IO::SHARE_DELETE | IO::BINARY # :nodoc:
|
||||||
|
|
||||||
|
##
|
||||||
|
# Open a file with given flags, and protect access with flock
|
||||||
|
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
|
||||||
|
index d558c0be2bfa..8f95bab733f8 100644
|
||||||
|
--- a/lib/rubygems/installer.rb
|
||||||
|
+++ b/lib/rubygems/installer.rb
|
||||||
|
@@ -538,7 +538,7 @@ def generate_plugins # :nodoc:
|
||||||
|
def generate_bin_script(filename, bindir)
|
||||||
|
bin_script_path = File.join bindir, formatted_program_filename(filename)
|
||||||
|
|
||||||
|
- Gem.open_file_with_flock("#{bin_script_path}.lock") do
|
||||||
|
+ Gem.open_file_with_flock("#{bin_script_path}.lock") do |lock|
|
||||||
|
require "fileutils"
|
||||||
|
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
|
||||||
|
|
||||||
|
@@ -546,6 +546,7 @@ def generate_bin_script(filename, bindir)
|
||||||
|
file.write app_script_text(filename)
|
||||||
|
file.chmod(options[:prog_mode] || 0o755)
|
||||||
|
end
|
||||||
|
+ File.unlink(lock.path)
|
||||||
|
end
|
||||||
|
|
||||||
|
verbose bin_script_path
|
||||||
|
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
|
||||||
|
index a61d1b6fff28..2f4ff7349db4 100644
|
||||||
|
--- a/test/rubygems/test_gem_installer.rb
|
||||||
|
+++ b/test/rubygems/test_gem_installer.rb
|
||||||
|
@@ -1083,6 +1083,8 @@ def test_install_creates_working_binstub
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match(/ran executable/, e.message)
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_conflicting_binstubs
|
||||||
|
@@ -1131,6 +1133,8 @@ def test_conflicting_binstubs
|
||||||
|
# We expect the bin stub to activate the version that actually contains
|
||||||
|
# the binstub.
|
||||||
|
assert_match("I have an executable", e.message)
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_creates_binstub_that_understand_version
|
||||||
|
@@ -1160,6 +1164,8 @@ def test_install_creates_binstub_that_understand_version
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_includes(e.message, "can't find gem a (= 3.0)")
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_creates_binstub_that_prefers_user_installed_gem_to_default
|
||||||
|
@@ -1192,6 +1198,8 @@ def test_install_creates_binstub_that_prefers_user_installed_gem_to_default
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal(e.message, "ran executable")
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_creates_binstub_that_dont_trust_encoding
|
||||||
|
@@ -1222,6 +1230,8 @@ def test_install_creates_binstub_that_dont_trust_encoding
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match(/ran executable/, e.message)
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_with_no_prior_files
|
||||||
|
|
||||||
|
From fa0700e0f52827ae05da59a331a2917a12c09b8a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
Date: Thu, 15 Aug 2024 16:20:46 +0900
|
||||||
|
Subject: [PATCH 2/3] Workaround for TruffleRuby
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/rubygems.rb | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
|
||||||
|
index 7626ccfdf0d6..9d40fcc2f77a 100644
|
||||||
|
--- a/lib/rubygems.rb
|
||||||
|
+++ b/lib/rubygems.rb
|
||||||
|
@@ -778,7 +778,9 @@ def self.open_file(path, flags, &block)
|
||||||
|
File.open(path, flags, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
- MODE_TO_FLOCK = IO::RDONLY | IO::APPEND | IO::CREAT | IO::SHARE_DELETE | IO::BINARY # :nodoc:
|
||||||
|
+ mode = IO::RDONLY | IO::APPEND | IO::CREAT | IO::BINARY
|
||||||
|
+ mode |= IO::SHARE_DELETE if IO.const_defined?(:SHARE_DELETE)
|
||||||
|
+ MODE_TO_FLOCK = mode # :nodoc:
|
||||||
|
|
||||||
|
##
|
||||||
|
# Open a file with given flags, and protect access with flock
|
||||||
|
|
||||||
|
From 6548e7aa17186687d0a8b99571885f148363016d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
Date: Fri, 16 Aug 2024 20:19:22 +0900
|
||||||
|
Subject: [PATCH 3/3] Ensure that the lock file will be removed
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/rubygems/installer.rb | 3 ++-
|
||||||
|
test/rubygems/test_gem_installer.rb | 27 +++++++++++++++++++++++++++
|
||||||
|
2 files changed, 29 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
|
||||||
|
index 8f95bab733f8..1085f73fca53 100644
|
||||||
|
--- a/lib/rubygems/installer.rb
|
||||||
|
+++ b/lib/rubygems/installer.rb
|
||||||
|
@@ -546,7 +546,8 @@ def generate_bin_script(filename, bindir)
|
||||||
|
file.write app_script_text(filename)
|
||||||
|
file.chmod(options[:prog_mode] || 0o755)
|
||||||
|
end
|
||||||
|
- File.unlink(lock.path)
|
||||||
|
+ ensure
|
||||||
|
+ FileUtils.rm_f lock.path
|
||||||
|
end
|
||||||
|
|
||||||
|
verbose bin_script_path
|
||||||
|
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
|
||||||
|
index 2f4ff7349db4..ad5b1a244e80 100644
|
||||||
|
--- a/test/rubygems/test_gem_installer.rb
|
||||||
|
+++ b/test/rubygems/test_gem_installer.rb
|
||||||
|
@@ -1234,6 +1234,33 @@ def test_install_creates_binstub_that_dont_trust_encoding
|
||||||
|
assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
end
|
||||||
|
|
||||||
|
+ def test_install_does_not_leave_lockfile_for_binstub
|
||||||
|
+ installer = util_setup_installer
|
||||||
|
+
|
||||||
|
+ installer.wrappers = true
|
||||||
|
+
|
||||||
|
+ File.class_eval do
|
||||||
|
+ alias_method :original_chmod, :chmod
|
||||||
|
+ define_method(:chmod) do |mode|
|
||||||
|
+ original_chmod(mode)
|
||||||
|
+ raise Gem::Ext::BuildError if path.end_with?("/executable")
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ assert_raise(Gem::Ext::BuildError) do
|
||||||
|
+ installer.install
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ assert_path_not_exist(File.join(installer.bin_dir, "executable.lock"))
|
||||||
|
+ # assert_path_not_exist(File.join(installer.bin_dir, "executable"))
|
||||||
|
+ ensure
|
||||||
|
+ File.class_eval do
|
||||||
|
+ remove_method :chmod
|
||||||
|
+ alias_method :chmod, :original_chmod
|
||||||
|
+ remove_method :original_chmod
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def test_install_with_no_prior_files
|
||||||
|
installer = util_setup_installer
|
||||||
|
|
@ -0,0 +1,124 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rpm_test_helper'
|
||||||
|
|
||||||
|
class TestRubyGemsCon < Test::Unit::TestCase
|
||||||
|
include RPMTestHelper
|
||||||
|
|
||||||
|
def test_filter_out_regular_requirements
|
||||||
|
gem_i = GemInfo.new
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(0, lines.size)
|
||||||
|
|
||||||
|
deps = [ Dependency.new('bar') ]
|
||||||
|
gem_i.dependencies = deps
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(0, lines.size)
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
Dependency.new('bar'),
|
||||||
|
Dependency.new('baq'),
|
||||||
|
Dependency.new('quz')
|
||||||
|
]
|
||||||
|
|
||||||
|
gem_i.dependencies = deps
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(0, lines.size)
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
Dependency.new('bar', ['>= 4.1']),
|
||||||
|
Dependency.new('baz', ['~> 3.2']),
|
||||||
|
Dependency.new('quz', ['>= 5.6'])
|
||||||
|
]
|
||||||
|
|
||||||
|
gem_i.dependencies = deps
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(0, lines.size)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_single_gem_single_version_conflict
|
||||||
|
con = Dependency.new('bar', ['!= 0.4.4'])
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [ con ])
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{con.to_rpm_str} = 0.4.4\n", lines.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multiple_gems_with_single_conflict
|
||||||
|
cons = [
|
||||||
|
Dependency.new('bar', ['!= 1.1']),
|
||||||
|
Dependency.new('baq', ['!= 1.2.2']),
|
||||||
|
Dependency.new('quz', ['!= 1.3'])
|
||||||
|
]
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: cons)
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(3, lines.size)
|
||||||
|
|
||||||
|
assert_equal("#{cons[0].to_rpm_str} = 1.1\n" , lines[0])
|
||||||
|
assert_equal("#{cons[1].to_rpm_str} = 1.2.2\n", lines[1])
|
||||||
|
assert_equal("#{cons[2].to_rpm_str} = 1.3\n" , lines[2])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multiple_conflicts_on_single_gem
|
||||||
|
con = Dependency.new('bar', ['!= 2.3', '!= 2.4'])
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [con])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
rpm_name = con.to_rpm_str
|
||||||
|
left_rpm_constraint = "(#{rpm_name} = 2.3 with "
|
||||||
|
right_rpm_constraint = "#{rpm_name} = 2.4)\n"
|
||||||
|
assert_equal((left_rpm_constraint + right_rpm_constraint), lines[0])
|
||||||
|
|
||||||
|
con = Dependency.new('bar', ['!= 2.3', '!= 2.4', '!= 4.5'])
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [ con ])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
|
||||||
|
rpm_name = con.to_rpm_str
|
||||||
|
left_rpm_constraint = "(#{rpm_name} = 2.3 with "
|
||||||
|
middle_rpm_constraint = "#{rpm_name} = 2.4 with "
|
||||||
|
right_rpm_constraint = "#{rpm_name} = 4.5)\n"
|
||||||
|
|
||||||
|
assert_equal((left_rpm_constraint + middle_rpm_constraint + right_rpm_constraint), lines[0])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_generates_conflicts_while_ignoring_regular_requirements
|
||||||
|
deps = [
|
||||||
|
Dependency.new('bar', ['>= 2.3', '!= 2.4.2']),
|
||||||
|
Dependency.new('quz', ['~> 3.0', '!= 3.2'])
|
||||||
|
]
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: deps)
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
|
||||||
|
rpm_name = deps[0].to_rpm_str
|
||||||
|
rpm_constraint = "#{rpm_name} = 2.4.2\n"
|
||||||
|
assert_equal(rpm_constraint, lines[0])
|
||||||
|
|
||||||
|
rpm_name = deps[1].to_rpm_str
|
||||||
|
rpm_constraint = "#{rpm_name} = 3.2\n"
|
||||||
|
assert_equal(rpm_constraint, lines[1])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,52 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rpm_test_helper'
|
||||||
|
|
||||||
|
class TestRubyGemsProv < Test::Unit::TestCase
|
||||||
|
include RPMTestHelper
|
||||||
|
|
||||||
|
def test_provides_the_gem_version
|
||||||
|
gem_i = GemInfo.new(version: '1.2')
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{gem_i.to_rpm_str} = #{gem_i.version}\n", lines.first)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(name: 'somegem_foo', version: '4.5.6')
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{gem_i.to_rpm_str} = #{gem_i.version}\n", lines.first)
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
Dependency.new('bar'),
|
||||||
|
Dependency.new('baq', [">= 1.2"]),
|
||||||
|
Dependency.new('quz', ["!= 3.2"])
|
||||||
|
]
|
||||||
|
gem_i = GemInfo.new(dependencies: deps)
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{gem_i.to_rpm_str} = #{gem_i.version}\n", lines.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_translates_prelease_version_provides_from_rubygems_to_rpm
|
||||||
|
gem_i = GemInfo.new(version: '1.2.3.dev')
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{gem_i.to_rpm_str} = 1.2.3~dev\n", lines.first)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(name: 'foo2', version: '1.2.3.dev.2')
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{gem_i.to_rpm_str} = 1.2.3~dev.2\n", lines.first)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,205 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
require 'rpm_test_helper'
|
||||||
|
|
||||||
|
class TestRubyGemsReq < Test::Unit::TestCase
|
||||||
|
include RPMTestHelper
|
||||||
|
|
||||||
|
def test_depends_on_rubygems
|
||||||
|
gem_i = GemInfo.new
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(1, lines.size)
|
||||||
|
assert_equal("#{helper_rubygems_dependency}\n", lines.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_requires_rubygems_and_dependency
|
||||||
|
dep = Dependency.new('bar')
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{helper_rubygems_dependency}\n", lines.first)
|
||||||
|
assert_equal("#{dep.to_rpm_str}\n", lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_requires_multiple_dependencies_with_constraint
|
||||||
|
constraints = [
|
||||||
|
'>= 3.0',
|
||||||
|
'>= 3.0.0',
|
||||||
|
'>= 3',
|
||||||
|
'= 1.0.2',
|
||||||
|
'= 3.0',
|
||||||
|
'< 3.2',
|
||||||
|
'<= 3.4'
|
||||||
|
]
|
||||||
|
|
||||||
|
dependencies = []
|
||||||
|
constraints.each_with_index do |constraint, idx|
|
||||||
|
dependencies << Dependency.new("bar#{idx}", [constraint])
|
||||||
|
end
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: dependencies)
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
# + 1 for the rubygems dependency
|
||||||
|
assert_equal(constraints.size + 1, lines.size)
|
||||||
|
dependencies.each_with_index do |dep, idx|
|
||||||
|
rpm_dep_name = dep.to_rpm_str
|
||||||
|
# Start indexing lines at 1, to jump over rubygems dependency
|
||||||
|
assert_equal("#{rpm_dep_name} #{constraints[idx]}\n", lines[idx + 1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_expands_pessimistic_constraint_for_rpm
|
||||||
|
dep = Dependency.new('bar', ['~> 1.2'])
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
|
||||||
|
rpm_dep_name = dep.to_rpm_str
|
||||||
|
left_constraint = "#{rpm_dep_name} >= 1.2"
|
||||||
|
right_constraint = "#{rpm_dep_name} < 2"
|
||||||
|
expected_constraint = "(#{left_constraint} with #{right_constraint})\n"
|
||||||
|
assert_equal(expected_constraint, lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multiple_pessimistically_constrained_dependencies
|
||||||
|
dependencies = []
|
||||||
|
dep_map = [
|
||||||
|
{
|
||||||
|
constraint: '~> 1.2.3',
|
||||||
|
expanded_left: '>= 1.2.3',
|
||||||
|
expanded_rigth: '< 1.3',
|
||||||
|
gem_name: 'bar1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constraint: '~> 1.2',
|
||||||
|
expanded_left: '>= 1.2',
|
||||||
|
expanded_rigth: '< 2',
|
||||||
|
gem_name: 'bar2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constraint: '~> 3',
|
||||||
|
expanded_left: '>= 3',
|
||||||
|
expanded_rigth: '< 4',
|
||||||
|
gem_name: 'bar3'
|
||||||
|
}
|
||||||
|
].each do |deps|
|
||||||
|
dependencies << Dependency.new(deps[:gem_name], [deps[:constraint]])
|
||||||
|
end
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: dependencies)
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(dep_map.size + 1, lines.size)
|
||||||
|
|
||||||
|
dep_map.each_with_index do |hash, idx|
|
||||||
|
rpm_dep_name = dependencies[idx].to_rpm_str
|
||||||
|
left_constraint = rpm_dep_name + ' ' + hash[:expanded_left]
|
||||||
|
right_constraint = rpm_dep_name + ' ' + hash[:expanded_rigth]
|
||||||
|
expected_constraint = "(#{left_constraint} with #{right_constraint})\n"
|
||||||
|
assert_equal(expected_constraint, lines[idx + 1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multiple_constraints_on_one_dependency_composes_constraints_for_RPM
|
||||||
|
# The quoting here depends on how the constraint is expanded in the helpers.
|
||||||
|
# right now the form is `["#{constraint}"]`, therefore we have to not specify
|
||||||
|
# left and right quotes.
|
||||||
|
constraints = ['>= 0.2.3', '<= 0.2.5']
|
||||||
|
dep = Dependency.new('baz', constraints)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
rpm_dep_name = dep.to_rpm_str
|
||||||
|
assert_equal("(#{rpm_dep_name} >= 0.2.3 with #{rpm_dep_name} <= 0.2.5)\n", lines[1])
|
||||||
|
|
||||||
|
# Not sure who would compose a dependency like this, but it's possible
|
||||||
|
# to do with the current generator
|
||||||
|
constraints = ['> 0.4.5', '< 0.6.4', '>= 2.3', '<= 2.5.3']
|
||||||
|
dep = Dependency.new('qux', constraints)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
rpm_dep = dep.to_rpm_str
|
||||||
|
expected_str = "(#{rpm_dep} > 0.4.5 with #{rpm_dep} < 0.6.4 with " \
|
||||||
|
"#{rpm_dep} >= 2.3 with #{rpm_dep} <= 2.5.3)\n"
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal(expected_str, lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1561487
|
||||||
|
def test_depends_on_gem_with_version_conflict
|
||||||
|
dep = Dependency.new('baz', ['!= 0.4'])
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{dep.to_rpm_str}\n", lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_filters_conflict_from_regular_version_constraints
|
||||||
|
constraint = ['> 1.2.4', '!= 1.2.7']
|
||||||
|
dep = Dependency.new('baq', constraint)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{dep.to_rpm_str} > 1.2.4\n", lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_filtering_conflicts_is_not_depending_on_contraint_ordering
|
||||||
|
constraints = ['!= 1.2.7', '> 1.2.4']
|
||||||
|
dep = Dependency.new('baq', constraints)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{dep.to_rpm_str} > 1.2.4\n", lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_filters_multiple_conflicts_from_dependency
|
||||||
|
omit "Case not yet supported."
|
||||||
|
constraints = ['!= 1.2.4', '!= 1.2.5', '!= 2.3', '!= 4.8']
|
||||||
|
dep = Dependency.new('baf', constraints)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{dep.to_rpm_str}\n", lines[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_filters_multiple_conflicts_from_dependency_but_keeps_regular_constraint
|
||||||
|
constraints = ['!= 1.2.4', '!= 1.2.5', '!= 2.3', '<= 4.8']
|
||||||
|
dep = Dependency.new('bam', constraints)
|
||||||
|
|
||||||
|
gem_i = GemInfo.new(dependencies: [dep])
|
||||||
|
|
||||||
|
lines = run_generator_single_file(gem_i)
|
||||||
|
|
||||||
|
assert_equal(2, lines.size)
|
||||||
|
assert_equal("#{dep.to_rpm_str} <= 4.8\n", lines[1])
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in new issue