diff --git a/rpm_test_helper.rb b/rpm_test_helper.rb new file mode 100644 index 0000000..671ca55 --- /dev/null +++ b/rpm_test_helper.rb @@ -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 diff --git a/ruby-2.1.0-Enable-configuration-of-archlibdir.patch b/ruby-2.1.0-Enable-configuration-of-archlibdir.patch index 4cd8dd1..5461f1d 100644 --- a/ruby-2.1.0-Enable-configuration-of-archlibdir.patch +++ b/ruby-2.1.0-Enable-configuration-of-archlibdir.patch @@ -11,7 +11,7 @@ diff --git a/configure.ac b/configure.ac index d261ea57b5..3c13076b82 100644 --- a/configure.ac +++ b/configure.ac -@@ -3482,6 +3482,11 @@ AS_IF([test ${multiarch+set}], [ +@@ -3480,6 +3480,11 @@ AS_IF([test ${multiarch+set}], [ ]) archlibdir='${libdir}/${arch}' diff --git a/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch b/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch index e6315c0..eeea8a0 100644 --- a/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch +++ b/ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch @@ -14,7 +14,7 @@ diff --git a/configure.ac b/configure.ac index c42436c23d..d261ea57b5 100644 --- a/configure.ac +++ b/configure.ac -@@ -4321,7 +4321,8 @@ AS_CASE(["$ruby_version_dir_name"], +@@ -4319,7 +4319,8 @@ AS_CASE(["$ruby_version_dir_name"], ruby_version_dir=/'${ruby_version_dir_name}' if test -z "${ruby_version_dir_name}"; then diff --git a/ruby-2.1.0-always-use-i386.patch b/ruby-2.1.0-always-use-i386.patch index 8e1b4fe..9d5fff4 100644 --- a/ruby-2.1.0-always-use-i386.patch +++ b/ruby-2.1.0-always-use-i386.patch @@ -11,7 +11,7 @@ diff --git a/configure.ac b/configure.ac index 3c13076b82..93af30321d 100644 --- a/configure.ac +++ b/configure.ac -@@ -4385,6 +4385,8 @@ AC_SUBST(vendorarchdir)dnl +@@ -4383,6 +4383,8 @@ AC_SUBST(vendorarchdir)dnl AC_SUBST(CONFIGURE, "`echo $0 | sed 's|.*/||'`")dnl AC_SUBST(configure_args, "`echo "${ac_configure_args}" | sed 's/\\$/$$/g'`")dnl diff --git a/ruby-2.1.0-custom-rubygems-location.patch b/ruby-2.1.0-custom-rubygems-location.patch index 7dc8eca..30292e9 100644 --- a/ruby-2.1.0-custom-rubygems-location.patch +++ b/ruby-2.1.0-custom-rubygems-location.patch @@ -15,7 +15,7 @@ diff --git a/configure.ac b/configure.ac index 93af30321d..bc13397e0e 100644 --- a/configure.ac +++ b/configure.ac -@@ -4357,6 +4357,10 @@ AC_ARG_WITH(vendorarchdir, +@@ -4355,6 +4355,10 @@ AC_ARG_WITH(vendorarchdir, [vendorarchdir=$withval], [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}]) @@ -26,7 +26,7 @@ index 93af30321d..bc13397e0e 100644 AS_IF([test "${LOAD_RELATIVE+set}"], [ AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) RUBY_EXEC_PREFIX='' -@@ -4381,6 +4385,7 @@ AC_SUBST(sitearchdir)dnl +@@ -4379,6 +4383,7 @@ AC_SUBST(sitearchdir)dnl AC_SUBST(vendordir)dnl AC_SUBST(vendorlibdir)dnl AC_SUBST(vendorarchdir)dnl diff --git a/ruby-2.3.0-ruby_version.patch b/ruby-2.3.0-ruby_version.patch index 50b4466..af424a8 100644 --- a/ruby-2.3.0-ruby_version.patch +++ b/ruby-2.3.0-ruby_version.patch @@ -20,7 +20,7 @@ diff --git a/configure.ac b/configure.ac index 80b137e380..63cd3b4f8b 100644 --- a/configure.ac +++ b/configure.ac -@@ -4271,9 +4271,6 @@ AS_CASE(["$target_os"], +@@ -4269,9 +4269,6 @@ AS_CASE(["$target_os"], rubyw_install_name='$(RUBYW_INSTALL_NAME)' ]) @@ -30,7 +30,7 @@ index 80b137e380..63cd3b4f8b 100644 rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'} AC_ARG_WITH(rubyarchprefix, AS_HELP_STRING([--with-rubyarchprefix=DIR], -@@ -4296,57 +4293,63 @@ AC_ARG_WITH(ridir, +@@ -4294,57 +4291,63 @@ AC_ARG_WITH(ridir, AC_SUBST(ridir) AC_SUBST(RI_BASE_NAME) @@ -122,7 +122,7 @@ index 80b137e380..63cd3b4f8b 100644 AS_IF([test "${LOAD_RELATIVE+set}"], [ AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) -@@ -4363,6 +4366,7 @@ AC_SUBST(sitearchincludedir)dnl +@@ -4361,6 +4364,7 @@ AC_SUBST(sitearchincludedir)dnl AC_SUBST(arch)dnl AC_SUBST(sitearch)dnl AC_SUBST(ruby_version)dnl @@ -227,7 +227,7 @@ diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index b25068405d..e9fef4a311 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb -@@ -1353,7 +1353,8 @@ def test_self_use_paths +@@ -1365,7 +1365,8 @@ def test_self_use_paths def test_self_user_dir parts = [@userhome, ".gem", Gem.ruby_engine] @@ -237,7 +237,7 @@ index b25068405d..e9fef4a311 100644 FileUtils.mkdir_p File.join(parts) -@@ -1429,7 +1430,7 @@ def test_self_vendor_dir +@@ -1441,7 +1442,7 @@ def test_self_vendor_dir vendordir(File.join(@tempdir, "vendor")) do expected = File.join RbConfig::CONFIG["vendordir"], "gems", diff --git a/ruby-2.7.0-Initialize-ABRT-hook.patch b/ruby-2.7.0-Initialize-ABRT-hook.patch index 309507f..0f32243 100644 --- a/ruby-2.7.0-Initialize-ABRT-hook.patch +++ b/ruby-2.7.0-Initialize-ABRT-hook.patch @@ -58,7 +58,7 @@ diff --git a/ruby.c b/ruby.c index 60c57d6259..1eec16f2c8 100644 --- a/ruby.c +++ b/ruby.c -@@ -1722,10 +1722,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) +@@ -1724,10 +1724,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) void Init_builtin_features(void); diff --git a/ruby-3.3.0-Disable-syntax-suggest-test-case.patch b/ruby-3.3.0-Disable-syntax-suggest-test-case.patch index 1119a59..cbfe623 100644 --- a/ruby-3.3.0-Disable-syntax-suggest-test-case.patch +++ b/ruby-3.3.0-Disable-syntax-suggest-test-case.patch @@ -12,7 +12,7 @@ diff --git a/common.mk b/common.mk index d55d1788aa..73755f6ccd 100644 --- a/common.mk +++ b/common.mk -@@ -1601,8 +1601,6 @@ yes-test-syntax-suggest: $(PREPARE_SYNTAX_SUGGEST) +@@ -1607,8 +1607,6 @@ yes-test-syntax-suggest: $(PREPARE_SYNTAX_SUGGEST) $(ACTIONS_ENDGROUP) no-test-syntax-suggest: diff --git a/ruby-3.4.0-Extract-hardening-CFLAGS-to-a-special-hardenflags-variable.patch b/ruby-3.4.0-Extract-hardening-CFLAGS-to-a-special-hardenflags-variable.patch index b811afd..f2bce8b 100644 --- a/ruby-3.4.0-Extract-hardening-CFLAGS-to-a-special-hardenflags-variable.patch +++ b/ruby-3.4.0-Extract-hardening-CFLAGS-to-a-special-hardenflags-variable.patch @@ -171,7 +171,7 @@ index f35fad6a362611..0da15772d36671 100644 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}"], [ +@@ -4213,12 +4270,13 @@ AS_IF([test "${ARCH_FLAG}"], [ rb_cv_warnflags=`echo "$rb_cv_warnflags" | sed 's/^ *//;s/ *$//'` warnflags="$rb_cv_warnflags" AC_SUBST(cppflags)dnl @@ -186,7 +186,7 @@ index f35fad6a362611..0da15772d36671 100644 AC_SUBST(XCFLAGS)dnl AC_SUBST(XLDFLAGS)dnl AC_SUBST(EXTLDFLAGS)dnl -@@ -4688,6 +4746,7 @@ config_summary "DLDFLAGS" "$DLDFLAGS" +@@ -4686,6 +4744,7 @@ config_summary "DLDFLAGS" "$DLDFLAGS" config_summary "optflags" "$optflags" config_summary "debugflags" "$debugflags" config_summary "warnflags" "$warnflags" @@ -255,7 +255,7 @@ 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@ +@@ -90,6 +90,7 @@ cflags = @cflags@ optflags = @optflags@ debugflags = @debugflags@ warnflags = @warnflags@ @strict_warnflags@ @@ -279,9 +279,9 @@ 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 -@@ -17,3 +17,20 @@ AC_DEFUN([RUBY_TRY_CFLAGS], [ - AC_MSG_RESULT(no)]) - ]) +@@ -22,3 +22,20 @@ AC_DEFUN([RUBY_TRY_CFLAGS], [ + AC_MSG_RESULT(no)], + [$4], [$5]) ])dnl + +AC_DEFUN([_RUBY_TRY_CFLAGS_PREPEND], [ diff --git a/ruby-3.4.0-openssl-respect-crypto-policies-tls-min.patch b/ruby-3.4.0-openssl-respect-crypto-policies-tls-min.patch new file mode 100644 index 0000000..6c7a4dd --- /dev/null +++ b/ruby-3.4.0-openssl-respect-crypto-policies-tls-min.patch @@ -0,0 +1,47 @@ +From ae215a47ae1a6527bb7b8566e5bcc9430652462f Mon Sep 17 00:00:00 2001 +From: Ewoud Kohl van Wijngaarden +Date: Fri, 5 Jan 2024 15:58:59 +0100 +Subject: [PATCH] Only set min_version on OpenSSL < 1.1.0 + +Both Red Hat and Debian-like systems configure the minimum TLS version +to be 1.2 by default, but allow users to change this via configs. + +On Red Hat and derivatives this happens via crypto-policies[1], which in +writes settings in /etc/crypto-policies/back-ends/opensslcnf.config. +Most notably, it sets TLS.MinProtocol there. For Debian there's +MinProtocol in /etc/ssl/openssl.cnf. Both default to TLSv1.2, which is +considered a secure default. + +In constrast, the SSLContext has a hard coded OpenSSL::SSL::TLS1_VERSION +for min_version. TLS 1.0 and 1.1 are considered insecure. By always +setting this in the default parameters, the system wide default can't be +respected, even if a developer wants to. + +This takes the approach that's also done for ciphers: it's only set for +OpenSSL < 1.1.0. + +[1]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening +--- + lib/openssl/ssl.rb | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb +index e557b8b48..83ecacafb 100644 +--- a/ext/openssl/lib/openssl/ssl.rb ++++ b/ext/openssl/lib/openssl/ssl.rb +@@ -22,7 +22,6 @@ module OpenSSL + module SSL + class SSLContext + DEFAULT_PARAMS = { # :nodoc: +- :min_version => OpenSSL::SSL::TLS1_VERSION, + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :verify_hostname => true, + :options => -> { +@@ -55,6 +54,7 @@ class SSLContext + if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") && + OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000) + DEFAULT_PARAMS.merge!( ++ min_version: OpenSSL::SSL::TLS1_VERSION, + ciphers: %w{ + ECDHE-ECDSA-AES128-GCM-SHA256 + ECDHE-RSA-AES128-GCM-SHA256 diff --git a/ruby.spec b/ruby.spec index f1bc591..5b838c8 100644 --- a/ruby.spec +++ b/ruby.spec @@ -1,6 +1,6 @@ %global major_version 3 %global minor_version 3 -%global teeny_version 4 +%global teeny_version 10 %global major_minor_version %{major_version}.%{minor_version} %global ruby_version %{major_minor_version}.%{teeny_version} @@ -10,7 +10,7 @@ #%%global milestone rc1 # Keep the revision enabled for pre-releases from GIT. -#%%global revision be1089c8ec +#%%global revision ef084cc8f4 %global ruby_archive %{name}-%{ruby_version} @@ -27,30 +27,32 @@ %global rubygems_dir %{_datadir}/rubygems # Bundled libraries versions -%global rubygems_version 3.5.11 +%global rubygems_version 3.5.22 %global rubygems_molinillo_version 0.8.0 -%global rubygems_net_http_version 0.4.0 +%global rubygems_net_http_version 0.4.1 %global rubygems_net_protocol_version 0.2.2 %global rubygems_optparse_version 0.4.0 -%global rubygems_resolv_version 0.3.0 +%global rubygems_resolv_version 0.4.0 +%global rubygems_securerandom_version 0.3.1 %global rubygems_timeout_version 0.4.1 %global rubygems_tsort_version 0.2.0 -%global rubygems_uri_version 0.13.0 +%global rubygems_uri_version 0.13.1 # Default gems. -%global bundler_version 2.5.11 +%global bundler_version 2.5.22 %global bundler_connection_pool_version 2.4.1 %global bundler_fileutils_version 1.7.2 -%global bundler_net_http_persistent_version 4.0.2 +%global bundler_net_http_persistent_version 4.0.4 %global bundler_pub_grub_version 0.5.0 +%global bundler_securerandom_version 0.3.1 %global bundler_thor_version 1.3.0 %global bundler_tsort_version 0.2.0 -%global bundler_uri_version 0.13.0 +%global bundler_uri_version 0.13.1 %global abbrev_version 0.1.2 %global base64_version 0.2.0 %global benchmark_version 0.3.0 -%global cgi_version 0.4.1 +%global cgi_version 0.4.2 %global csv_version 3.2.8 %global date_version 3.3.4 %global delegate_version 0.3.1 @@ -77,7 +79,7 @@ %global nkf_version 0.1.3 %global observer_version 0.1.2 %global open3_version 0.2.1 -%global openssl_version 3.2.0 +%global openssl_version 3.2.2 %global open_uri_version 0.4.1 %global optparse_version 0.4.0 %global ostruct_version 0.6.0 @@ -86,8 +88,8 @@ %global prettyprint_version 0.2.0 %global pstore_version 0.1.3 %global readline_version 0.0.4 -%global reline_version 0.5.7 -%global resolv_version 0.3.0 +%global reline_version 0.5.10 +%global resolv_version 0.3.1 %global resolv_replace_version 0.1.1 %global rinda_version 0.2.0 %global ruby2_keywords_version 0.0.5 @@ -97,7 +99,7 @@ %global singleton_version 0.2.0 %global stringio_version 3.1.1 %global strscan_version 3.0.9 -%global syntax_suggest_version 2.0.0 +%global syntax_suggest_version 2.0.1 %global syslog_version 0.1.2 %global tempfile_version 0.2.1 %global time_version 0.3.0 @@ -105,7 +107,7 @@ %global tmpdir_version 0.2.0 %global tsort_version 0.2.0 %global un_version 0.3.0 -%global uri_version 0.13.0 +%global uri_version 0.13.3 %global weakref_version 0.1.3 %global win32ole_version 1.8.10 %global yaml_version 0.3.0 @@ -116,16 +118,16 @@ %global bigdecimal_version 3.1.5 %global io_console_version 0.7.1 %global irb_version 1.13.1 -%global json_version 2.7.1 +%global json_version 2.7.2 %global psych_version 5.1.2 %global rdoc_version 6.6.3.1 # Bundled gems. -%global debug_version 1.9.1 +%global debug_version 1.9.2 %global net_ftp_version 0.3.4 -%global net_imap_version 0.4.9.1 +%global net_imap_version 0.4.21 %global net_pop_version 0.1.2 -%global net_smtp_version 0.4.0.1 +%global net_smtp_version 0.5.1 %global matrix_version 0.4.2 %global minitest_version 5.20.0 %global power_assert_version 2.0.3 @@ -133,8 +135,8 @@ %global racc_version 1.7.3 %global rake_version 13.1.0 %global rbs_version 3.4.0 -%global rexml_version 3.2.8 -%global rss_version 0.3.0 +%global rexml_version 3.4.4 +%global rss_version 0.3.1 %global test_unit_version 3.6.1 %global typeprof_version 0.21.9 @@ -171,7 +173,7 @@ Summary: An interpreter of object-oriented scripting language Name: ruby Version: %{ruby_version}%{?development_release} -Release: 14%{?dist} +Release: 21%{?dist} # Licenses, which are likely not included in binary RPMs: # Apache-2.0: # benchmark/gc/redblack.rb @@ -187,9 +189,10 @@ Release: 14%{?dist} # https://github.com/flori/json/issues/277 # https://github.com/flori/json/pull/567 # -# Licenses under review: +# IETF (this is not official SPDX identifier) # .bundle/gems/net-imap-0.4.9/LICENSE.txt -# https://gitlab.com/fedora/legal/fedora-license-data/-/issues/506 +# Licenses in this file covers fair use and don't need to be listed: +# https://gitlab.com/fedora/legal/fedora-license-data/-/issues/506 # # BSD-3-Clause: missing/{crypt,mt19937,setproctitle}.c, addr2line.c:2652 # CC0: ccan/{build_assert/build_assert.h,check_type/check_type.h, @@ -230,6 +233,11 @@ Source13: test_abrt.rb Source14: test_systemtap.rb # Ruby OpenSSL FIPS tests. Source15: test_openssl_fips.rb +# RPM gem Requires dependency generator tests. +Source16: rpm_test_helper.rb +Source17: test_rubygems_req.rb +Source18: test_rubygems_prov.rb +Source19: test_rubygems_con.rb # The load directive is supported since RPM 4.12, i.e. F21+. The build process # fails on older Fedoras. @@ -274,6 +282,10 @@ Patch9: ruby-3.3.0-Disable-syntax-suggest-test-case.patch # Make sure hardeding flags are correctly applied. # https://bugs.ruby-lang.org/issues/20520 Patch12: ruby-3.4.0-Extract-hardening-CFLAGS-to-a-special-hardenflags-variable.patch +# Fix Ruby OpenSSL to respect crypto-policies TLS minimal version. +# https://github.com/ruby/openssl/pull/710 +# https://github.com/ruby/ruby/commit/6213ab1a51387fd9cdcb5e87908722f3bbdf78cb +Patch13: ruby-3.4.0-openssl-respect-crypto-policies-tls-min.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} %{?with_rubypick:Suggests: rubypick} @@ -290,6 +302,7 @@ BuildRequires: libyaml-devel BuildRequires: openssl-devel BuildRequires: zlib-devel %{?with_gmp:BuildRequires: gmp-devel} +%{?with_systemtap:BuildRequires: %{_bindir}/dtrace} %{?with_systemtap:BuildRequires: systemtap-sdt-devel} %{?with_yjit:BuildRequires: %{_bindir}/rustc} @@ -402,6 +415,7 @@ Provides: bundled(rubygem-net-http) = %{rubygems_net_http_version} Provides: bundled(rubygem-net-protocol) = %{rubygems_net_protocol_version} Provides: bundled(rubygem-optparse) = %{rubygems_optparse_version} Provides: bundled(rubygem-resolv) = %{rubygems_resolv_version} +Provides: bundled(rubygem-securerandom) = %{rubygems_securerandom_version} Provides: bundled(rubygem-timeout) = %{rubygems_timeout_version} Provides: bundled(rubygem-tsort) = %{rubygems_tsort_version} @@ -574,6 +588,7 @@ Provides: bundled(rubygem-connection_pool) = %{bundler_connection_pool_version Provides: bundled(rubygem-fileutils) = %{bundler_fileutils_version} Provides: bundled(rubygem-net-http-persistent) = %{bundler_net_http_persistent_version} Provides: bundled(rubygem-pub_grub) = %{bundler_pub_grub_version} +Provides: bundled(rubygem-securerandom) = %{bundler_securerandom_version} Provides: bundled(rubygem-thor) = %{bundler_thor_version} Provides: bundled(rubygem-uri) = %{bundler_uri_version} BuildArch: noarch @@ -751,6 +766,7 @@ analysis result in RBS format, a standard type description format for Ruby %patch 6 -p1 %patch 9 -p1 %patch 12 -p1 +%patch 13 -p1 # Provide an example of usage of the tapset: cp -a %{SOURCE3} . @@ -958,6 +974,7 @@ sed -i 's/^/%lang(ja) /' .ruby-doc.ja %define fortification_aarch64 fortified="10" fortify-able="26" %define fortification_ppc64le fortified="7" fortify-able="24" %define fortification_s390x fortified="10" fortify-able="24" +%define fortification_riscv64 fortified="10" fortify-able="26" # https://unix.stackexchange.com/questions/366/convince-grep-to-output-all-lines-not-just-those-with-matches checksec --format=xml --file=%{_vpath_builddir}/libruby.so.%{ruby_version} | \ sed -r "s//\1/" | \ @@ -1014,6 +1031,15 @@ make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ exit 1 if Gem::Resolv::VERSION != '%{rubygems_resolv_version}'; \ \"" +# SecureRandom. +make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ + module Gem; module Random; end; end; \ + require 'rubygems/vendor/securerandom/lib/securerandom'; \ + puts '%%{rubygems_securerandom_version}: %{rubygems_securerandom_version}'; \ + puts %Q[Gem::SecureRandom::VERSION: #{Gem::SecureRandom::VERSION}]; \ + exit 1 if Gem::SecureRandom::VERSION != '%{rubygems_securerandom_version}'; \ +\"" + # Timeout. make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ module Gem; end; \ @@ -1080,6 +1106,15 @@ make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ exit 1 if Gem::Net::HTTP::Persistent::VERSION != '%{bundler_net_http_persistent_version}'; \ \"" +# SecureRandom. +make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ + module Bundler; module Random; end; end; \ + require 'bundler/vendor/securerandom/lib/securerandom'; \ + puts '%%{bundler_securerandom_version}: %{bundler_securerandom_version}'; \ + puts %Q[Bundler::SecureRandom::VERSION: #{Bundler::SecureRandom::VERSION}]; \ + exit 1 if Bundler::SecureRandom::VERSION != '%{bundler_securerandom_version}'; \ +\"" + # Thor. make -C %{_vpath_builddir} -s runruby TESTRUN_SCRIPT="-e \" \ module Bundler; end; \ @@ -1133,6 +1168,21 @@ ln -sfr probes.d %{_vpath_builddir}/ make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=%{SOURCE14} %endif +# Test dependency generators for RPM +GENERATOR_SCRIPT="%{SOURCE9}" \ +make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ + -I%{_builddir}/%{buildsubdir}/tool/lib -I%{_sourcedir} --enable-gems \ + %{SOURCE17} --verbose" +GENERATOR_SCRIPT="%{SOURCE10}" \ +make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ + -I%{_builddir}/%{buildsubdir}/tool/lib -I%{_sourcedir} --enable-gems \ + %{SOURCE18} --verbose" +GENERATOR_SCRIPT="%{SOURCE11}" \ +make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ + -I%{_builddir}/%{buildsubdir}/tool/lib -I%{_sourcedir} --enable-gems \ + %{SOURCE19} --verbose" + + DISABLE_TESTS="" MSPECOPTS="" @@ -1557,12 +1607,15 @@ make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ # net-imap %dir %{gem_instdir net-imap} %{gem_instdir net-imap}/Gemfile +%license %{gem_instdir net-imap}/BSDL +%license %{gem_instdir net-imap}/COPYING %license %{gem_instdir net-imap}/LICENSE.txt %doc %{gem_instdir net-imap}/README.md %{gem_instdir net-imap}/Rakefile %{gem_instdir net-imap}/docs %{gem_libdir net-imap} %{gem_instdir net-imap}/rakelib +%{gem_instdir net-imap}/sample %{gem_spec net-imap} # net-pop @@ -1712,8 +1765,37 @@ make -C %{_vpath_builddir} runruby TESTRUN_SCRIPT=" \ %changelog -* Thu Aug 01 2024 Jun Aruga - 3.3.4-14 -- Remove systemtap-sdt-dtrace dependency including dtrace command. +* Thu Oct 23 2025 Vít Ondruch - 3.3.10-21 +- Upgrade to Ruby 3.3.10. +- CVE-2025-58767 ruby: REXML denial of service. + Resolves: rhbz#2396203 + +* Tue Aug 19 2025 Jarek Prokop - 3.3.9-20 +- Upgrate to Ruby 3.3.9. + Resolves: rhbz#2386838 +- CVE-2025-24294: Possible Denial of Service in resolv gem + +* Thu Apr 10 2025 Vít Ondruch - 3.3.8-19 +- Upgrade to Ruby 3.3.8. +- CVE-2025-25186: Fix Net::IMAP vulnerable to possible DoS by memory exhaustion + Resolves: rhbz#2345557 +- CVE-2025-27219: Denial of Service in CGI::Cookie.parse + Resolves: rhbz#2357516 +- CVE-2025-27221: userinfo leakage in URI#join, URI#merge and URI#+ + +* Thu Jan 23 2025 Jun Aruga - 3.3.7-18 +- Upgrade to Ruby 3.3.7. +- Fix Ruby OpenSSL to respect crypto-policies TLS minimal version. + +* Wed Nov 20 2024 David Abdurachmanov - 3.3.6-17 +- Add riscv64 information for checksec + +* Mon Nov 11 2024 Vít Ondruch - 3.3.6-16 +- Upgrade to Ruby 3.3.6. + +* Tue Sep 03 2024 Vít Ondruch - 3.3.5-14 +- Upgrade to Ruby 3.3.5. + Resolves: rhbz#2309364 * Mon Jul 29 2024 Jun Aruga - 3.3.4-13 - Add systemtap-sdt-devel to build Ruby with systemtap sdt header files. diff --git a/rubygems.con b/rubygems.con index 1a99ed0..bcdeddc 100644 --- a/rubygems.con +++ b/rubygems.con @@ -19,7 +19,7 @@ module RubyGemsReq end # Report conflicting gem dependencies including their version. - def self.gem_depenencies(specification) + def self.gem_dependencies(specification) specification.runtime_dependencies.each do |dependency| conflict_strings = Helpers::requirement_versions_to_rpm(dependency.requirement).map do |requirement| requirement_string = "rubygem(#{dependency.name}) #{requirement}" @@ -39,7 +39,7 @@ module RubyGemsReq begin specification = Gem::Specification.load filename - gem_depenencies(specification) + gem_dependencies(specification) rescue => e # Ignore all errors. end diff --git a/rubygems.req b/rubygems.req index 38e4a9c..70aebd4 100644 --- a/rubygems.req +++ b/rubygems.req @@ -58,7 +58,7 @@ module RubyGemsReq end # Report all gem dependencies including their version. - def self.gem_depenencies(specification) + def self.gem_dependencies(specification) specification.runtime_dependencies.each do |dependency| dependency_name = "rubygem(#{dependency.name})" requirements = Helpers::requirement_versions_to_rpm(dependency.requirement) @@ -75,7 +75,7 @@ module RubyGemsReq specification = Gem::Specification.load filename rubygems_dependency(specification) - gem_depenencies(specification) + gem_dependencies(specification) rescue => e # Ignore all errors. end diff --git a/sources b/sources index 88156f2..816497d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (ruby-3.3.4.tar.xz) = b26461a13ff82a08a282f10108028bb2a2e4a28da6182a291062fc54089c6655d79c22cc69d59156f9b11cb10a17fe8c69d489343fbae123a45f03361b95c9eb +SHA512 (ruby-3.3.10.tar.xz) = 8b81cab7b98acb6ff7bdf864da5e97596ee1efa441e2a65991e12a7e3f3ad3d83b1b5c65ae108484252ec8f6d85db60eb381a174c759023beb202b5a0d20818a diff --git a/test_rubygems_con.rb b/test_rubygems_con.rb new file mode 100644 index 0000000..e124a49 --- /dev/null +++ b/test_rubygems_con.rb @@ -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 diff --git a/test_rubygems_prov.rb b/test_rubygems_prov.rb new file mode 100644 index 0000000..b660ff6 --- /dev/null +++ b/test_rubygems_prov.rb @@ -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 diff --git a/test_rubygems_req.rb b/test_rubygems_req.rb new file mode 100644 index 0000000..490923e --- /dev/null +++ b/test_rubygems_req.rb @@ -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