Compare commits
	
		
			1 Commits
		
	
	
		
			c8-stream-
			...
			c10-beta
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0ee2544e13 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | ||||
| SOURCES/ruby-2.5.9.tar.xz | ||||
| ruby-3.3.1.tar.xz | ||||
|  | ||||
| @ -1 +0,0 @@ | ||||
| 7be8dc2e6e534eb36bfdf9f017af512996ec99a6 SOURCES/ruby-2.5.9.tar.xz | ||||
| @ -1,8 +0,0 @@ | ||||
| if defined?(Gem) | ||||
|   require 'rubygems.rb' | ||||
| 
 | ||||
|   begin | ||||
|     require 'abrt' | ||||
|   rescue LoadError | ||||
|   end | ||||
| end | ||||
| @ -1,25 +0,0 @@ | ||||
| From 28cc0749d6729aa2444661ee7b411e183fe220b0 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Mon, 19 Nov 2012 15:14:51 +0100 | ||||
| Subject: [PATCH] Verbose mkmf. | ||||
| 
 | ||||
| ---
 | ||||
|  lib/mkmf.rb | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/lib/mkmf.rb b/lib/mkmf.rb
 | ||||
| index 682eb46..e6b1445 100644
 | ||||
| --- a/lib/mkmf.rb
 | ||||
| +++ b/lib/mkmf.rb
 | ||||
| @@ -1900,7 +1900,7 @@ def configuration(srcdir)
 | ||||
|  SHELL = /bin/sh | ||||
|   | ||||
|  # V=0 quiet, V=1 verbose.  other values don't work. | ||||
| -V = 0
 | ||||
| +V = 1
 | ||||
|  Q1 = $(V:1=) | ||||
|  Q = $(Q1:0=@) | ||||
|  ECHO1 = $(V:1=@ #{CONFIG['NULLCMD']}) | ||||
| -- 
 | ||||
| 1.8.3.1 | ||||
| 
 | ||||
| @ -1,58 +0,0 @@ | ||||
| From 996012f6abe0ce4d68a2de9f249935c6d5b467bc Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Fri, 4 Oct 2013 22:13:11 +0200 | ||||
| Subject: [PATCH] Allow to specify addition preludes by configuration option. | ||||
| 
 | ||||
| ---
 | ||||
|  Makefile.in  | 2 ++ | ||||
|  common.mk    | 2 +- | ||||
|  configure.ac | 7 +++++++ | ||||
|  3 files changed, 10 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/Makefile.in b/Makefile.in
 | ||||
| index 7e8ed82..7916993 100644
 | ||||
| --- a/Makefile.in
 | ||||
| +++ b/Makefile.in
 | ||||
| @@ -119,6 +119,8 @@ XRUBY_RUBYLIBDIR = @XRUBY_RUBYLIBDIR@
 | ||||
|  XRUBY_RUBYHDRDIR = @XRUBY_RUBYHDRDIR@ | ||||
|  BOOTSTRAPRUBY = @BOOTSTRAPRUBY@ | ||||
|   | ||||
| +OPTIONAL_PRELUDES = @OPTIONAL_PRELUDES@
 | ||||
| +
 | ||||
|  #### End of system configuration section. #### | ||||
|   | ||||
|  MAJOR=	@MAJOR@ | ||||
| diff --git a/common.mk b/common.mk
 | ||||
| index 5cfbc3d..3f0a82e 100644
 | ||||
| --- a/common.mk
 | ||||
| +++ b/common.mk
 | ||||
| @@ -147,7 +147,7 @@ ALLOBJS       = $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(INITOBJS)
 | ||||
|  GOLFOBJS      = goruby.$(OBJEXT) golf_prelude.$(OBJEXT) | ||||
|   | ||||
|  DEFAULT_PRELUDES = $(GEM_PRELUDE) | ||||
| -PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(DEFAULT_PRELUDES)
 | ||||
| +PRELUDE_SCRIPTS = $(srcdir)/prelude.rb $(DEFAULT_PRELUDES) $(OPTIONAL_PRELUDES)
 | ||||
|  GEM_PRELUDE   = $(srcdir)/gem_prelude.rb | ||||
|  PRELUDES      = {$(srcdir)}prelude.c {$(srcdir)}miniprelude.c | ||||
|  GOLFPRELUDES  = {$(srcdir)}golf_prelude.c | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 028ef7ca3e..cdeff87871 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4397,6 +4397,13 @@ AC_SUBST(rubyarchhdrdir)dnl
 | ||||
|  AC_SUBST(sitearchhdrdir)dnl | ||||
|  AC_SUBST(vendorarchhdrdir)dnl | ||||
|   | ||||
| +AC_ARG_WITH(prelude,
 | ||||
| +		AS_HELP_STRING([--with-prelude=FILE-LIST], [specify additional preludes separated by space]),
 | ||||
| +		[prelude=$withval])
 | ||||
| +if test "$prelude" != ""; then
 | ||||
| +    AC_SUBST(OPTIONAL_PRELUDES, $prelude)
 | ||||
| +fi
 | ||||
| +
 | ||||
|  AC_ARG_WITH(mantype, | ||||
|  	AS_HELP_STRING([--with-mantype=TYPE], [specify man page type; TYPE is one of man and doc]), | ||||
|  		[ | ||||
| -- 
 | ||||
| 1.8.3.1 | ||||
| 
 | ||||
| @ -1,28 +0,0 @@ | ||||
| From 07eb5f5e775dec01a92a8b13910eaced9e8ee0cd Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Tue, 2 Dec 2014 10:56:58 +0100 | ||||
| Subject: [PATCH] Generate preludes using miniruby. | ||||
| 
 | ||||
| ---
 | ||||
|  common.mk | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/common.mk b/common.mk
 | ||||
| index 168dc52..20c218a 100644
 | ||||
| --- a/common.mk
 | ||||
| +++ b/common.mk
 | ||||
| @@ -962,9 +962,9 @@ $(MINIPRELUDE_C): $(COMPILE_PRELUDE)
 | ||||
|  		$(srcdir)/template/prelude.c.tmpl | ||||
|   | ||||
|  $(PRELUDE_C): $(COMPILE_PRELUDE) \ | ||||
| -	   $(PRELUDE_SCRIPTS)
 | ||||
| +	   $(PRELUDE_SCRIPTS) $(PREP)
 | ||||
|  	$(ECHO) generating $@ | ||||
| -	$(Q) $(BASERUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
 | ||||
| +	$(Q) $(MINIRUBY) $(srcdir)/tool/generic_erb.rb -I$(srcdir) -c -o $@ \
 | ||||
|  		$(srcdir)/template/prelude.c.tmpl $(PRELUDE_SCRIPTS) | ||||
|   | ||||
|  {$(VPATH)}golf_prelude.c: $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb | ||||
| -- 
 | ||||
| 2.6.3 | ||||
| 
 | ||||
| @ -1,80 +0,0 @@ | ||||
| From 60eb961c25f801ee43ca1be9393ab2f0a0546677 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Tue, 19 Dec 2017 14:00:20 +0100 | ||||
| Subject: [PATCH] Add Gem.operating_system_defaults to allow packagers to | ||||
|  override defaults. | ||||
| 
 | ||||
| This change allows Ruby packagers to override defaults and lazily query | ||||
| them. | ||||
| 
 | ||||
| This is very much the same change as #1644 to treat the | ||||
| operating_system defaults the same way as platform defaults. | ||||
| ---
 | ||||
|  lib/rubygems/config_file.rb |  2 +- | ||||
|  lib/rubygems/defaults.rb    | 21 ++++++++++++++++++++- | ||||
|  test/rubygems/test_gem.rb   |  7 +++++++ | ||||
|  3 files changed, 28 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
 | ||||
| index a4efed0f5a..deee38e6d9 100644
 | ||||
| --- a/lib/rubygems/config_file.rb
 | ||||
| +++ b/lib/rubygems/config_file.rb
 | ||||
| @@ -48,7 +48,7 @@ class Gem::ConfigFile
 | ||||
|    # For Ruby packagers to set configuration defaults.  Set in | ||||
|    # rubygems/defaults/operating_system.rb | ||||
|   | ||||
| -  OPERATING_SYSTEM_DEFAULTS = {}
 | ||||
| +  OPERATING_SYSTEM_DEFAULTS = Gem.operating_system_defaults
 | ||||
|   | ||||
|    ## | ||||
|    # For Ruby implementers to set configuration defaults.  Set in | ||||
| diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
 | ||||
| index 43d57fc808..b8222877ae 100644
 | ||||
| --- a/lib/rubygems/defaults.rb
 | ||||
| +++ b/lib/rubygems/defaults.rb
 | ||||
| @@ -177,7 +177,26 @@ def self.vendor_dir # :nodoc:
 | ||||
|    end | ||||
|   | ||||
|    ## | ||||
| -  # Default options for gem commands.
 | ||||
| +  # Default options for gem commands for Ruby packagers.
 | ||||
| +  #
 | ||||
| +  # The options here should be structured as an array of string "gem"
 | ||||
| +  # command names as keys and a string of the default options as values.
 | ||||
| +  #
 | ||||
| +  # Example:
 | ||||
| +  #
 | ||||
| +  # def self.operating_system_defaults
 | ||||
| +  #   {
 | ||||
| +  #       'install' => '--no-rdoc --no-ri --env-shebang',
 | ||||
| +  #       'update' => '--no-rdoc --no-ri --env-shebang'
 | ||||
| +  #   }
 | ||||
| +  # end
 | ||||
| +
 | ||||
| +  def self.operating_system_defaults
 | ||||
| +    {}
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  ##
 | ||||
| +  # Default options for gem commands for Ruby implementers.
 | ||||
|    # | ||||
|    # The options here should be structured as an array of string "gem" | ||||
|    # command names as keys and a string of the default options as values. | ||||
| diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
 | ||||
| index 3225a05c6b..62b80c4945 100644
 | ||||
| --- a/test/rubygems/test_gem.rb
 | ||||
| +++ b/test/rubygems/test_gem.rb
 | ||||
| @@ -1837,6 +1837,13 @@ def test_use_gemdeps_specific
 | ||||
|      ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps | ||||
|    end | ||||
|   | ||||
| +  def test_operating_system_defaults
 | ||||
| +    operating_system_defaults = Gem.operating_system_defaults
 | ||||
| +
 | ||||
| +    assert operating_system_defaults != nil
 | ||||
| +    assert operating_system_defaults.is_a? Hash
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_platform_defaults | ||||
|      platform_defaults = Gem.platform_defaults | ||||
|   | ||||
| @ -1,35 +0,0 @@ | ||||
| From 51e2c91412a511196e58efea5b87c460b4fa6a20 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Thu, 26 Jul 2018 13:17:52 +0200 | ||||
| Subject: [PATCH] Avoid need of C++ compiler to pass the test suite. | ||||
| 
 | ||||
| The test suite fails when C++ compiler is not available on the system: | ||||
| 
 | ||||
| ~~~ | ||||
| TestGemExtCmakeBuilder#test_self_build: | ||||
| Gem::InstallError: cmake failed, exit code 1 | ||||
|     /builddir/build/BUILD/ruby-2.5.1/lib/rubygems/ext/builder.rb:92:in `run' | ||||
|     /builddir/build/BUILD/ruby-2.5.1/lib/rubygems/ext/cmake_builder.rb:10:in `build' | ||||
|     /builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:37:in `block in test_self_build' | ||||
|     /builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:36:in `chdir' | ||||
|     /builddir/build/BUILD/ruby-2.5.1/test/rubygems/test_gem_ext_cmake_builder.rb:36:in `test_self_build' | ||||
| ~~~ | ||||
| 
 | ||||
| But there is nothing which would realy required C++. It is just CMake | ||||
| default to check for C++. | ||||
| ---
 | ||||
|  test/rubygems/test_gem_ext_cmake_builder.rb | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
| 
 | ||||
| diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb
 | ||||
| index 76d3cb2afe..2d449fc2fd 100644
 | ||||
| --- a/test/rubygems/test_gem_ext_cmake_builder.rb
 | ||||
| +++ b/test/rubygems/test_gem_ext_cmake_builder.rb
 | ||||
| @@ -25,6 +25,7 @@ def test_self_build
 | ||||
|      File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists| | ||||
|        cmakelists.write <<-eo_cmake | ||||
|  cmake_minimum_required(VERSION 2.6) | ||||
| +project(self_build LANGUAGES NONE)
 | ||||
|  install (FILES test.txt DESTINATION bin) | ||||
|        eo_cmake | ||||
|      end | ||||
| @ -1,46 +0,0 @@ | ||||
| From 93e6364a848f00b34647b13063dceb854dfaa11e Mon Sep 17 00:00:00 2001 | ||||
| From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Wed, 28 Oct 2020 13:12:06 +0000 | ||||
| Subject: [PATCH] merge revision(s): 07786ed | ||||
| 
 | ||||
| 	* test/net/http/test_https.rb: Stop the error due to openssl 1.1.1h | ||||
| 
 | ||||
| 	On some environments that uses OpenSSL 1.1.1h, the two tests now fail. | ||||
| 
 | ||||
| 	http://rubyci.s3.amazonaws.com/android29-x86_64/ruby-master/log/20200924T062352Z.fail.html.gz | ||||
| 	https://github.com/ruby/ruby/runs/1159288773?check_suite_focus=true | ||||
| 
 | ||||
| 	``` | ||||
| 	  1) Failure: | ||||
| 	TestNetHTTPS#test_get [/data/data/com.termux/files/home/cb/tmp/build/202	00924T062352Z/ruby/test/net/http/test_https.rb:47]: | ||||
| 	<"0\x82\x03\xED0\x82\x02\xD5\xA0\x03..."> expected but was | ||||
| 	<"0\x82\x03\xE30\x82\x02\xCB\xA0\x03...">. | ||||
| 	``` | ||||
| 
 | ||||
| 	Not sure why, but verify_callback now seems to receive only SERVER_CERT | ||||
| 	but not CA_CERT. | ||||
| 	It would be good to investigate the issue furthermore, but tentatively, | ||||
| 	I want to stop the failures. | ||||
| 
 | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  test/net/http/test_https.rb | 6 ++++-- | ||||
| 
 | ||||
| diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
 | ||||
| index c1d486470ae2..3a2341024121 100644
 | ||||
| --- a/test/net/http/test_https.rb
 | ||||
| +++ b/test/net/http/test_https.rb
 | ||||
| @@ -44,8 +44,10 @@ def test_get
 | ||||
|      http.request_get("/") {|res| | ||||
|        assert_equal($test_net_http_data, res.body) | ||||
|      } | ||||
| -    assert_equal(CA_CERT.to_der, certs[0].to_der)
 | ||||
| -    assert_equal(SERVER_CERT.to_der, certs[1].to_der)
 | ||||
| +    # TODO: OpenSSL 1.1.1h seems to yield only SERVER_CERT; need to check the incompatibility
 | ||||
| +    certs.zip([SERVER_CERT, CA_CERT]) do |actual, expected|
 | ||||
| +      assert_equal(expected.to_der, actual.to_der)
 | ||||
| +    end
 | ||||
|    rescue SystemCallError | ||||
|      skip $! | ||||
|    end | ||||
| @ -1,78 +0,0 @@ | ||||
| From 893949167bdb911c7db9fd59de85f288c09741e1 Mon Sep 17 00:00:00 2001 | ||||
| From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Sat, 15 Sep 2018 09:59:14 +0000 | ||||
| Subject: [PATCH] Fix issues detected by code analysis tool (mainly Coverity). | ||||
| 
 | ||||
| * Fix leaked storage in addr2line.c. | ||||
| * Fix for "top_root" leaking the resource. | ||||
| 
 | ||||
| [Fix GH-1956] | ||||
| 
 | ||||
| From: Jun Aruga <jaruga@redhat.com> | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64750 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  addr2line.c | 8 ++++++-- | ||||
|  regcomp.c   | 3 +++ | ||||
|  2 files changed, 9 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/addr2line.c b/addr2line.c
 | ||||
| index 2c422cc1697a..b266e44d5d4b 100644
 | ||||
| --- a/addr2line.c
 | ||||
| +++ b/addr2line.c
 | ||||
| @@ -593,11 +593,12 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
 | ||||
|  		h = dlopen(NULL, RTLD_NOW|RTLD_LOCAL); | ||||
|  		if (!h) continue; | ||||
|  		s = dlsym(h, strtab + sym->st_name); | ||||
| -		if (!s) continue;
 | ||||
| -		if (dladdr(s, &info)) {
 | ||||
| +		if (s && dladdr(s, &info)) {
 | ||||
|  		    dladdr_fbase = (uintptr_t)info.dli_fbase; | ||||
| +                    dlclose(h);
 | ||||
|  		    break; | ||||
|  		} | ||||
| +                dlclose(h);
 | ||||
|  	    } | ||||
|  	    if (ehdr->e_type == ET_EXEC) { | ||||
|  		obj->base_addr = 0; | ||||
| @@ -655,6 +656,9 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
 | ||||
|  finish: | ||||
|      return dladdr_fbase; | ||||
|  fail: | ||||
| +    if (file != NULL) {
 | ||||
| +        munmap(file, (size_t)filesize);
 | ||||
| +    }
 | ||||
|      return (uintptr_t)-1; | ||||
|  } | ||||
|   | ||||
| diff --git a/regcomp.c b/regcomp.c
 | ||||
| index 0f6bee60d576..df7f73bac501 100644
 | ||||
| --- a/regcomp.c
 | ||||
| +++ b/regcomp.c
 | ||||
| @@ -3596,6 +3596,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
 | ||||
|      if (n == 0 || varlen == 0) { | ||||
|        if (IS_NULL(snode)) { | ||||
|  	if (IS_NULL(root) && IS_NOT_NULL(prev_node)) { | ||||
| +          onig_node_free(top_root);
 | ||||
|  	  top_root = root = onig_node_list_add(NULL_NODE, prev_node); | ||||
|  	  if (IS_NULL(root)) { | ||||
|  	    onig_node_free(prev_node); | ||||
| @@ -3627,6 +3628,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
 | ||||
|  	} | ||||
|        } | ||||
|        if (IS_NULL(root) && IS_NOT_NULL(prev_node)) { | ||||
| +        onig_node_free(top_root);
 | ||||
|  	top_root = root = onig_node_list_add(NULL_NODE, prev_node); | ||||
|  	if (IS_NULL(root)) { | ||||
|  	  onig_node_free(prev_node); | ||||
| @@ -3677,6 +3679,7 @@ expand_case_fold_string(Node* node, regex_t* reg)
 | ||||
|      if (r != 0) goto mem_err; | ||||
|   | ||||
|      if (IS_NOT_NULL(prev_node) && IS_NULL(root)) { | ||||
| +      onig_node_free(top_root);
 | ||||
|        top_root = root = onig_node_list_add(NULL_NODE, prev_node); | ||||
|        if (IS_NULL(root)) { | ||||
|  	onig_node_free(srem); | ||||
| -- 
 | ||||
| 2.21.0 | ||||
| 
 | ||||
| @ -1,182 +0,0 @@ | ||||
| From f46bac1f3e8634e24c747d06b28e11b874f1e488 Mon Sep 17 00:00:00 2001 | ||||
| From: Kazuki Yamaguchi <k@rhe.jp> | ||||
| Date: Thu, 16 Aug 2018 19:40:48 +0900 | ||||
| Subject: [PATCH] config: support .include directive | ||||
| 
 | ||||
| OpenSSL 1.1.1 introduces a new '.include' directive. Update our config | ||||
| parser to support that. | ||||
| 
 | ||||
| As mentioned in the referenced GitHub issue, we should use the OpenSSL | ||||
| API instead of implementing the parsing logic ourselves, but it will | ||||
| need backwards-incompatible changes which we can't backport to stable | ||||
| versions. So continue to use the Ruby implementation for now. | ||||
| 
 | ||||
| Reference: https://github.com/ruby/openssl/issues/208 | ||||
| ---
 | ||||
|  ext/openssl/lib/openssl/config.rb | 54 ++++++++++++++++++++++++++++--------------- | ||||
|  test/openssl/test_config.rb   | 54 +++++++++++++++++++++++++++++++++++++++++++ | ||||
|  2 files changed, 90 insertions(+), 18 deletions(-) | ||||
| 
 | ||||
| diff --git a/ext/openssl/lib/openssl/config.rb b/ext/openssl/lib/openssl/config.rb
 | ||||
| index 88225451..ba3a54c8 100644
 | ||||
| --- a/ext/openssl/lib/openssl/config.rb
 | ||||
| +++ b/ext/openssl/lib/openssl/config.rb
 | ||||
| @@ -77,29 +77,44 @@ def get_key_string(data, section, key) # :nodoc:
 | ||||
|        def parse_config_lines(io) | ||||
|          section = 'default' | ||||
|          data = {section => {}} | ||||
| -        while definition = get_definition(io)
 | ||||
| +        io_stack = [io]
 | ||||
| +        while definition = get_definition(io_stack)
 | ||||
|            definition = clear_comments(definition) | ||||
|            next if definition.empty? | ||||
| -          if definition[0] == ?[
 | ||||
| +          case definition
 | ||||
| +          when /\A\[/
 | ||||
|              if /\[([^\]]*)\]/ =~ definition | ||||
|                section = $1.strip | ||||
|                data[section] ||= {} | ||||
|              else | ||||
|                raise ConfigError, "missing close square bracket" | ||||
|              end | ||||
| -          else
 | ||||
| -            if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
 | ||||
| -              if $2
 | ||||
| -                section = $1
 | ||||
| -                key = $2
 | ||||
| -              else
 | ||||
| -                key = $1
 | ||||
| +          when /\A\.include (.+)\z/
 | ||||
| +            path = $1
 | ||||
| +            if File.directory?(path)
 | ||||
| +              files = Dir.glob(File.join(path, "*.{cnf,conf}"), File::FNM_EXTGLOB)
 | ||||
| +            else
 | ||||
| +              files = [path]
 | ||||
| +            end
 | ||||
| +
 | ||||
| +            files.each do |filename|
 | ||||
| +              begin
 | ||||
| +                io_stack << StringIO.new(File.read(filename))
 | ||||
| +              rescue
 | ||||
| +                raise ConfigError, "could not include file '%s'" % filename
 | ||||
|                end | ||||
| -              value = unescape_value(data, section, $3)
 | ||||
| -              (data[section] ||= {})[key] = value.strip
 | ||||
| +            end
 | ||||
| +          when /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/
 | ||||
| +            if $2
 | ||||
| +              section = $1
 | ||||
| +              key = $2
 | ||||
|              else | ||||
| -              raise ConfigError, "missing equal sign"
 | ||||
| +              key = $1
 | ||||
|              end | ||||
| +            value = unescape_value(data, section, $3)
 | ||||
| +            (data[section] ||= {})[key] = value.strip
 | ||||
| +          else
 | ||||
| +            raise ConfigError, "missing equal sign"
 | ||||
|            end | ||||
|          end | ||||
|          data | ||||
| @@ -212,10 +227,10 @@ def clear_comments(line)
 | ||||
|          scanned.join | ||||
|        end | ||||
|   | ||||
| -      def get_definition(io)
 | ||||
| -        if line = get_line(io)
 | ||||
| +      def get_definition(io_stack)
 | ||||
| +        if line = get_line(io_stack)
 | ||||
|            while /[^\\]\\\z/ =~ line | ||||
| -            if extra = get_line(io)
 | ||||
| +            if extra = get_line(io_stack)
 | ||||
|                line += extra | ||||
|              else | ||||
|                break | ||||
| @@ -225,9 +240,12 @@ def get_definition(io)
 | ||||
|          end | ||||
|        end | ||||
|   | ||||
| -      def get_line(io)
 | ||||
| -        if line = io.gets
 | ||||
| -          line.gsub(/[\r\n]*/, '')
 | ||||
| +      def get_line(io_stack)
 | ||||
| +        while io = io_stack.last
 | ||||
| +          if line = io.gets
 | ||||
| +            return line.gsub(/[\r\n]*/, '')
 | ||||
| +          end
 | ||||
| +          io_stack.pop
 | ||||
|          end | ||||
|        end | ||||
|      end | ||||
| diff --git a/test/openssl/test_config.rb b/test/openssl/test_config.rb
 | ||||
| index 99dcc497..5653b5d0 100644
 | ||||
| --- a/test/openssl/test_config.rb
 | ||||
| +++ b/test/openssl/test_config.rb
 | ||||
| @@ -120,6 +120,49 @@ def test_s_parse_format
 | ||||
|      assert_equal("error in line 7: missing close square bracket", excn.message) | ||||
|    end | ||||
|   | ||||
| +  def test_s_parse_include
 | ||||
| +    in_tmpdir("ossl-config-include-test") do |dir|
 | ||||
| +      Dir.mkdir("child")
 | ||||
| +      File.write("child/a.conf", <<~__EOC__)
 | ||||
| +        [default]
 | ||||
| +        file-a = a.conf
 | ||||
| +        [sec-a]
 | ||||
| +        a = 123
 | ||||
| +      __EOC__
 | ||||
| +      File.write("child/b.cnf", <<~__EOC__)
 | ||||
| +        [default]
 | ||||
| +        file-b = b.cnf
 | ||||
| +        [sec-b]
 | ||||
| +        b = 123
 | ||||
| +      __EOC__
 | ||||
| +      File.write("include-child.conf", <<~__EOC__)
 | ||||
| +        key_outside_section = value_a
 | ||||
| +        .include child
 | ||||
| +      __EOC__
 | ||||
| +
 | ||||
| +      include_file = <<~__EOC__
 | ||||
| +        [default]
 | ||||
| +        file-main = unnamed
 | ||||
| +        [sec-main]
 | ||||
| +        main = 123
 | ||||
| +        .include include-child.conf
 | ||||
| +      __EOC__
 | ||||
| +
 | ||||
| +      # Include a file by relative path
 | ||||
| +      c1 = OpenSSL::Config.parse(include_file)
 | ||||
| +      assert_equal(["default", "sec-a", "sec-b", "sec-main"], c1.sections.sort)
 | ||||
| +      assert_equal(["file-main", "file-a", "file-b"], c1["default"].keys)
 | ||||
| +      assert_equal({"a" => "123"}, c1["sec-a"])
 | ||||
| +      assert_equal({"b" => "123"}, c1["sec-b"])
 | ||||
| +      assert_equal({"main" => "123", "key_outside_section" => "value_a"}, c1["sec-main"])
 | ||||
| +
 | ||||
| +      # Relative paths are from the working directory
 | ||||
| +      assert_raise(OpenSSL::ConfigError) do
 | ||||
| +        Dir.chdir("child") { OpenSSL::Config.parse(include_file) }
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_s_load | ||||
|      # alias of new | ||||
|      c = OpenSSL::Config.load | ||||
| @@ -299,6 +342,17 @@ def test_clone
 | ||||
|      @it['newsection'] = {'a' => 'b'} | ||||
|      assert_not_equal(@it.sections.sort, c.sections.sort) | ||||
|    end | ||||
| +
 | ||||
| +  private
 | ||||
| +
 | ||||
| +  def in_tmpdir(*args)
 | ||||
| +    Dir.mktmpdir(*args) do |dir|
 | ||||
| +      dir = File.realpath(dir)
 | ||||
| +      Dir.chdir(dir) do
 | ||||
| +        yield dir
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +  end
 | ||||
|  end | ||||
|   | ||||
|  end | ||||
| @ -1,43 +0,0 @@ | ||||
| From c8ccdbfe1e45cb3b832109d644296c0a3b3e0b59 Mon Sep 17 00:00:00 2001 | ||||
| From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Sun, 2 Sep 2018 03:49:31 +0000 | ||||
| Subject: [PATCH] configure.ac: -fstack-protector-strong | ||||
| 
 | ||||
| * configure.ac: use -fstack-protector-strong if available instead of | ||||
|   -fstack-protector conditionally.  [ruby-core:88788] [Misc #15053] | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  configure.ac | 17 ++++++++++------- | ||||
|  1 file changed, 10 insertions(+), 7 deletions(-) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 9328fa532de0..b8ee57239215 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -837,15 +837,18 @@ AS_IF([test "$GCC" = yes], [
 | ||||
|  	stack_protector=no | ||||
|      ]) | ||||
|      AS_IF([test -z "${stack_protector+set}"], [ | ||||
| -	RUBY_TRY_CFLAGS(-fstack-protector, [stack_protector=yes], [stack_protector=no])
 | ||||
| -	AS_IF([test "x$stack_protector" = xyes], [
 | ||||
| -	    RUBY_TRY_LDFLAGS(-fstack-protector, [], [stack_protector=broken])
 | ||||
| +	AS_FOR(option, opt, [-fstack-protector-strong -fstack-protector], [
 | ||||
| +	    RUBY_TRY_CFLAGS(option, [stack_protector=yes])
 | ||||
| +	    AS_IF([test "x$stack_protector" = xyes], [
 | ||||
| +		RUBY_TRY_LDFLAGS(option, [], [stack_protector=])
 | ||||
| +	    ])
 | ||||
| +	    AS_IF([test "x$stack_protector" = xyes], [stack_protector=option; break])
 | ||||
|  	]) | ||||
|      ]) | ||||
| -    AS_IF([test "x$stack_protector" = xyes], [
 | ||||
| -	RUBY_APPEND_OPTION(XCFLAGS, -fstack-protector)
 | ||||
| -	RUBY_APPEND_OPTION(XLDFLAGS, -fstack-protector)
 | ||||
| -	RUBY_APPEND_OPTION(LDFLAGS, -fstack-protector)
 | ||||
| +    AS_CASE(["$stack_protector"], [-*], [
 | ||||
| +	RUBY_APPEND_OPTION(XCFLAGS, $stack_protector)
 | ||||
| +	RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector)
 | ||||
| +	RUBY_APPEND_OPTION(LDFLAGS, $stack_protector)
 | ||||
|      ]) | ||||
|   | ||||
|      AS_CASE("${compress_debug_sections:-zlib}", | ||||
| @ -1,177 +0,0 @@ | ||||
| From bb3db69e2a0c210cc3a63940622db96a97eb7947 Mon Sep 17 00:00:00 2001 | ||||
| From: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Fri, 2 Mar 2018 01:37:53 +0000 | ||||
| Subject: [PATCH] configure.ac: library options to MAINLIBS | ||||
| 
 | ||||
| * configure.ac (MAINLIBS): moved library options for main program | ||||
|   and static libruby, and append MAINLIBS to LIBRUBYARG_STATIC, as | ||||
|   these libraries are not needed for linking to shared libruby. | ||||
|   [ruby-core:85882] [Bug #14422] | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  configure.ac        | 33 +++++++++++++++------------------ | ||||
|  template/ruby.pc.in |  1 + | ||||
|  win32/Makefile.sub  |  6 ++++-- | ||||
|  3 files changed, 20 insertions(+), 20 deletions(-) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index aebbae1969a5..733a0c992fd7 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -10,6 +10,7 @@ AC_DISABLE_OPTION_CHECKING
 | ||||
|  AC_ARG_VAR([cflags], [additional CFLAGS]) | ||||
|  AC_ARG_VAR([cppflags], [additional CPPFLAGS]) | ||||
|  AC_ARG_VAR([cxxflags], [additional CXXFLAGS]) | ||||
| +ORIG_LIBS=$LIBS
 | ||||
|   | ||||
|  AC_DEFUN([RUBY_RM_RECURSIVE], [ | ||||
|  m4_version_prereq([2.70], [-1], [ | ||||
| @@ -2939,13 +2940,11 @@ AS_IF([test x"$enable_pthread" = xyes], [
 | ||||
|  	AC_DEFINE(_THREAD_SAFE) | ||||
|  	AC_DEFINE(HAVE_LIBPTHREAD) | ||||
|  	AC_CHECK_HEADERS(pthread_np.h, [], [], [@%:@include <pthread.h>]) | ||||
| -	AS_CASE([$pthread_lib],
 | ||||
| -	[c],    [],
 | ||||
| -	[root], [],
 | ||||
| -	[c_r],  [MAINLIBS="-pthread $MAINLIBS"],
 | ||||
| -	        [AS_CASE(["$target_os"],
 | ||||
| -		    [openbsd*|mirbsd*], [LIBS="-pthread $LIBS"],
 | ||||
| -		    [LIBS="-l$pthread_lib $LIBS"])])
 | ||||
| +	AS_CASE(["$pthread_lib:$target_os"],
 | ||||
| +		[c:*], [],
 | ||||
| +		[root:*], [],
 | ||||
| +		[c_r:*|*:openbsd*|*:mirbsd*],  [LIBS="-pthread $LIBS"],
 | ||||
| +		[LIBS="-l$pthread_lib $LIBS"])
 | ||||
|      ], [ | ||||
|  	AC_MSG_WARN("Don't know how to find pthread library on your system -- thread support disabled") | ||||
|      ]) | ||||
| @@ -3624,7 +3623,7 @@ LIBRUBY_A='lib$(RUBY_SO_NAME)-static.a'
 | ||||
|  LIBRUBY='$(LIBRUBY_A)' | ||||
|  LIBRUBYARG_STATIC='-l$(RUBY_SO_NAME)-static' | ||||
|  LIBRUBYARG='$(LIBRUBYARG_STATIC)' | ||||
| -SOLIBS=
 | ||||
| +SOLIBS='$(MAINLIBS)'
 | ||||
|   | ||||
|  AS_CASE(["$target_os"], | ||||
|    [cygwin*|mingw*|haiku*|darwin*], [ | ||||
| @@ -3690,9 +3689,6 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|    LIBRUBY_RELATIVE=no | ||||
|    test -z "$CCDLFLAGS" || CFLAGS="$CFLAGS $CCDLFLAGS" | ||||
|    ENABLE_SHARED=yes | ||||
| -  AS_IF([test "$rb_cv_binary_elf" = yes], [
 | ||||
| -    SOLIBS='$(LIBS)'
 | ||||
| -  ])
 | ||||
|   | ||||
|    # libdir can be overridden in config.site file (on OpenSUSE at least). | ||||
|    libdir_basename=lib | ||||
| @@ -3727,7 +3723,6 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|  	]) | ||||
|  	], | ||||
|      [freebsd*|dragonfly*], [ | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)' | ||||
|  	LIBRUBY_SONAME='$(LIBRUBY_SO)' | ||||
|  	AS_IF([test "$rb_cv_binary_elf" != "yes" ], [ | ||||
| @@ -3736,7 +3731,6 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|  	]) | ||||
|  	], | ||||
|      [netbsd*], [ | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)$(MINOR)' | ||||
|  	LIBRUBY_SO="${LIBRUBY_SONAME}"'.$(TEENY)' | ||||
|  	RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"]) | ||||
| @@ -3747,11 +3741,9 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|  	]) | ||||
|  	], | ||||
|      [openbsd*|mirbsd*], [ | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR).'`expr ${MINOR} \* 10 + ${TEENY}` | ||||
|  	], | ||||
|      [solaris*], [ | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)' | ||||
|  	LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_PROGRAM_VERSION)' | ||||
|  	LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' | ||||
| @@ -3769,7 +3761,7 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|      [aix*], [ | ||||
|  	RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-bnoentry" "$XLDFLAGS" "$LDFLAGS_OPTDIR"]) | ||||
|  	LIBRUBYARG_SHARED='-L${libdir} -l${RUBY_SO_NAME}' | ||||
| -	SOLIBS='-lm -lc'
 | ||||
| +	LIBS="$LIBS -lm -lc"
 | ||||
|  	], | ||||
|      [darwin*], [ | ||||
|  	LIBRUBY_LDSHARED='$(CC) -dynamiclib' | ||||
| @@ -3789,7 +3781,6 @@ AS_CASE("$enable_shared", [yes], [
 | ||||
|  	LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT)' | ||||
|  	LIBRUBY_SONAME='lib$(RUBY_BASE_NAME).$(RUBY_API_VERSION).$(SOEXT)' | ||||
|  	LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_INSTALL_NAME).$(SOEXT)' | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	], | ||||
|      [interix*], [ | ||||
|  	LIBRUBYARG_SHARED='-L. -L${libdir} -l$(RUBY_SO_NAME)' | ||||
| @@ -4032,7 +4023,6 @@ AS_CASE(["$target_os"],
 | ||||
|  	    ]) | ||||
|  	LIBRUBY_ALIASES='' | ||||
|  	FIRSTMAKEFILE=GNUmakefile:cygwin/GNUmakefile.in | ||||
| -	SOLIBS='$(LIBS)'
 | ||||
|  	AS_IF([test x"$enable_shared" = xyes], [ | ||||
|  	    LIBRUBY='lib$(RUBY_SO_NAME).dll.a' | ||||
|  	], [ | ||||
| @@ -4132,6 +4122,13 @@ AS_IF([test "${universal_binary-no}" = yes ], [
 | ||||
|  		[rb_cv_architecture_available=yes], [rb_cv_architecture_available=no])) | ||||
|  ]) | ||||
|   | ||||
| +MAINLIBS="$LIBS"
 | ||||
| +LIBS=$ORIG_LIBS
 | ||||
| +AS_IF([test -n "${LIBS}"], [
 | ||||
| +    libspat=`echo "${LIBS}" | sed 's/[[][|.*$^]]/\\&/g;s/^  */ /;s/^  *$/ /'`
 | ||||
| +    MAINFLAGS=`echo " $MAINLIBS " | sed "s|$libspat"'||;s/^ *//;s/ *$//'`
 | ||||
| +])
 | ||||
| +LIBRUBYARG_STATIC="${LIBRUBYARG_STATIC} \$(MAINLIBS)"
 | ||||
|  CPPFLAGS="$CPPFLAGS "'$(DEFS)' | ||||
|  test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}' | ||||
|  AS_IF([test -n "${cflags+set}"], [ | ||||
| diff --git a/template/ruby.pc.in b/template/ruby.pc.in
 | ||||
| index d874f92c3b20..7ce4461c05df 100644
 | ||||
| --- a/template/ruby.pc.in
 | ||||
| +++ b/template/ruby.pc.in
 | ||||
| @@ -39,6 +39,7 @@ sitehdrdir=@sitehdrdir@
 | ||||
|  rubyarchhdrdir=@rubyarchhdrdir@ | ||||
|  vendorarchhdrdir=@vendorarchhdrdir@ | ||||
|  sitearchhdrdir=@sitearchhdrdir@ | ||||
| +MAINLIBS=@MAINLIBS@
 | ||||
|  SOEXT=@SOEXT@ | ||||
|  LIBPATH=@LIBPATH@ | ||||
|  LIBRUBY_A=@LIBRUBY_A@ | ||||
| diff --git a/win32/Makefile.sub b/win32/Makefile.sub
 | ||||
| index 8673c121641e..f8316cccb68e 100644
 | ||||
| --- a/win32/Makefile.sub
 | ||||
| +++ b/win32/Makefile.sub
 | ||||
| @@ -279,6 +279,7 @@ MJIT_DEBUGFLAGS = $(DEBUGFLAGS)
 | ||||
|  CPPFLAGS = $(DEFS) $(ARCHDEFS) $(CPPFLAGS) | ||||
|   | ||||
|  DLDFLAGS = $(LDFLAGS) -dll | ||||
| +MAINLIBS = $(LIBS)
 | ||||
|  SOLIBS = | ||||
|  RCFILES = $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(RUBY_SO_NAME).rc | ||||
|  !ifndef RCFLAGS | ||||
| @@ -821,7 +822,8 @@ s,@CPPFLAGS@,$(CPPFLAGS),;t t
 | ||||
|  s,@CXXFLAGS@,$(CXXFLAGS),;t t | ||||
|  s,@FFLAGS@,$(FFLAGS),;t t | ||||
|  s,@LDFLAGS@,$(LDFLAGS),;t t | ||||
| -s,@LIBS@,$(LIBS),;t t
 | ||||
| +s,@LIBS@,,;t t
 | ||||
| +s,@MAINLIBS@,$(MAINLIBS),;t t
 | ||||
|  s,@exec_prefix@,$${prefix},;t t | ||||
|  s,@prefix@,$(prefix),;t t | ||||
|  s,@program_transform_name@,s,.*,$(PROGRAM_PREFIX)&$(PROGRAM_SUFFIX),,;t t | ||||
| @@ -909,7 +911,7 @@ s,@LIBRUBY_SO@,$$(RUBY_SO_NAME).dll,;t t
 | ||||
|  s,@LIBRUBY_ALIASES@,$(LIBRUBY_ALIASES),;t t | ||||
|  s,@LIBRUBY@,$$(RUBY_SO_NAME).lib,;t t | ||||
|  s,@LIBRUBYARG@,$$(LIBRUBYARG_SHARED),;t t | ||||
| -s,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A),;t t
 | ||||
| +s,@LIBRUBYARG_STATIC@,$$(LIBRUBY_A) $$(MAINLIBS),;t t
 | ||||
|  s,@LIBRUBYARG_SHARED@,$$(LIBRUBY),;t t | ||||
|  s,@SOLIBS@,$(SOLIBS),;t t | ||||
|  s,@DLDLIBS@,$(DLDLIBS),;t t | ||||
| @ -1,69 +0,0 @@ | ||||
| From 9d98bfe7f1abdeda5aedf9404588104980ee7a86 Mon Sep 17 00:00:00 2001 | ||||
| From: aycabta <aycabta@gmail.com> | ||||
| Date: Mon, 15 Jan 2018 22:32:56 +0900 | ||||
| Subject: [PATCH] Check nil text token | ||||
| 
 | ||||
| Sometimes :on_ignored_nl token has nil text. This commit checks and | ||||
| bypasses the token. | ||||
| ---
 | ||||
|  lib/rdoc/parser/ripper_state_lex.rb |  4 +++- | ||||
|  test/test_rdoc_parser_ruby.rb       | 30 +++++++++++++++++++++++++++++ | ||||
|  2 files changed, 33 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/parser/ripper_state_lex.rb b/lib/rdoc/parser/ripper_state_lex.rb
 | ||||
| index 2a285b97a4..c56cef46ee 100644
 | ||||
| --- a/lib/rdoc/parser/ripper_state_lex.rb
 | ||||
| +++ b/lib/rdoc/parser/ripper_state_lex.rb
 | ||||
| @@ -330,8 +330,10 @@ class RDoc::RipperStateLex
 | ||||
|        @heredoc_queue << retrieve_heredoc_info(tk) | ||||
|        @inner_lex.lex_state = EXPR_END unless RIPPER_HAS_LEX_STATE | ||||
|      when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then | ||||
| -      unless @heredoc_queue.empty?
 | ||||
| +      if !@heredoc_queue.empty?
 | ||||
|          get_heredoc_tk(*@heredoc_queue.shift) | ||||
| +      elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil
 | ||||
| +        tk[:text] = ''
 | ||||
|        end | ||||
|      when :on_words_beg then | ||||
|        tk = get_words_tk(tk) | ||||
| diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb
 | ||||
| index 833ed2cc74..c9d57021ce 100644
 | ||||
| --- a/test/rdoc/test_rdoc_parser_ruby.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_parser_ruby.rb
 | ||||
| @@ -306,6 +306,36 @@ def sum(n)
 | ||||
|      assert_equal @top_level, sum.file | ||||
|    end | ||||
| 
 | ||||
| +  def test_parse_on_ignored_nl_with_nil_text
 | ||||
| +    util_parser <<ruby
 | ||||
| +class Foo
 | ||||
| +  def meth
 | ||||
| +    variable # comment
 | ||||
| +      .chain
 | ||||
| +  end
 | ||||
| +end
 | ||||
| +ruby
 | ||||
| +
 | ||||
| +    expected = <<EXPECTED
 | ||||
| +<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">meth</span>
 | ||||
| +  <span class="ruby-identifier">variable</span> <span class="ruby-comment"># comment</span>
 | ||||
| +    .<span class="ruby-identifier">chain</span>
 | ||||
| +<span class="ruby-keyword">end</span>
 | ||||
| +EXPECTED
 | ||||
| +    expected = expected.rstrip
 | ||||
| +
 | ||||
| +    @parser.scan
 | ||||
| +
 | ||||
| +    foo = @store.find_class_named 'Foo'
 | ||||
| +    meth = foo.method_list.first
 | ||||
| +
 | ||||
| +    assert_equal 'meth',     meth.name
 | ||||
| +    assert_equal @top_level, meth.file
 | ||||
| +
 | ||||
| +    markup_code = meth.markup_code.sub(/^.*\n/, '')
 | ||||
| +    assert_equal expected, markup_code
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_parse_alias | ||||
|      klass = RDoc::NormalClass.new 'Foo' | ||||
|      klass.parent = @top_level | ||||
| @ -1,214 +0,0 @@ | ||||
| From 091459248d3ce814e10d50cc4421f0c0454ef61f Mon Sep 17 00:00:00 2001 | ||||
| From: "Bernhard M. Wiedemann" <bwiedemann@suse.de> | ||||
| Date: Sun, 30 Apr 2017 22:47:40 +0200 | ||||
| Subject: [PATCH 1/4] created.rid: use SOURCE_DATE_EPOCH | ||||
| 
 | ||||
| use SOURCE_DATE_EPOCH instead of current time in created.rid top line | ||||
| to enable reproducible builds of ruby docs | ||||
| 
 | ||||
| See https://reproducible-builds.org/ for why this is good | ||||
| and https://reproducible-builds.org/specs/source-date-epoch/ | ||||
| for the definition of this variable. | ||||
| ---
 | ||||
|  lib/rdoc/rdoc.rb | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
 | ||||
| index 68775c8be1..a2711fbbd1 100644
 | ||||
| --- a/lib/rdoc/rdoc.rb
 | ||||
| +++ b/lib/rdoc/rdoc.rb
 | ||||
| @@ -232,6 +232,9 @@ def store= store
 | ||||
|   | ||||
|    def update_output_dir(op_dir, time, last = {}) | ||||
|      return if @options.dry_run or not @options.update_output_dir | ||||
| +    unless ENV['SOURCE_DATE_EPOCH'].nil?
 | ||||
| +      time = Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime
 | ||||
| +    end
 | ||||
|   | ||||
|      open output_flag_file(op_dir), "w" do |f| | ||||
|        f.puts time.rfc2822 | ||||
| -- 
 | ||||
| 2.21.0 | ||||
| 
 | ||||
| From 73a935e9fa63b056ea0be69c0c923afdfb4d88da Mon Sep 17 00:00:00 2001 | ||||
| From: "Bernhard M. Wiedemann" <bwiedemann@suse.de> | ||||
| Date: Thu, 14 Dec 2017 10:54:54 +0100 | ||||
| Subject: [PATCH 2/4] Do not store current timestamps in gz headers | ||||
| 
 | ||||
| to enable reproducible builds of rdoc | ||||
| 
 | ||||
| Normally, 0 would be the preferred value to indicate "no date" | ||||
| but that value is handled differently in Zlib::GzipWriter | ||||
| to put in the current time | ||||
| ---
 | ||||
|  lib/rdoc/generator/json_index.rb | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb
 | ||||
| index e4cfe967c6..a059a5d4d0 100644
 | ||||
| --- a/lib/rdoc/generator/json_index.rb
 | ||||
| +++ b/lib/rdoc/generator/json_index.rb
 | ||||
| @@ -175,7 +175,7 @@ def generate_gzipped
 | ||||
|      debug_msg "Writing gzipped search index to %s" % outfile | ||||
|   | ||||
|      Zlib::GzipWriter.open(outfile) do |gz| | ||||
| -      gz.mtime = File.mtime(search_index_file)
 | ||||
| +      gz.mtime = 1 # make output reproducible
 | ||||
|        gz.orig_name = search_index_file.basename.to_s | ||||
|        gz.write search_index | ||||
|        gz.close | ||||
| @@ -193,7 +193,7 @@ def generate_gzipped
 | ||||
|          debug_msg "Writing gzipped file to %s" % outfile | ||||
|   | ||||
|          Zlib::GzipWriter.open(outfile) do |gz| | ||||
| -          gz.mtime = File.mtime(dest)
 | ||||
| +          gz.mtime = 1 # make output reproducible
 | ||||
|            gz.orig_name = dest.basename.to_s | ||||
|            gz.write data | ||||
|            gz.close | ||||
| -- 
 | ||||
| 2.21.0 | ||||
| 
 | ||||
| From 1b34b337b72918e83c3b952eed6998ad47974960 Mon Sep 17 00:00:00 2001 | ||||
| From: aycabta <aycabta@gmail.com> | ||||
| Date: Sat, 27 Jan 2018 14:37:42 +0900 | ||||
| Subject: [PATCH 3/4] Improve reproducible builds for .js and .js.gz files | ||||
| 
 | ||||
| The mtime for search_index.js.gz should be updated because it's | ||||
| generated dynamically. So uses SOURCE_DATE_EPOCH after | ||||
| RDoc::Generator::JsonIndex#generate creates index file. | ||||
| 
 | ||||
| FileUtils.install in RDoc::Generator::JsonIndex#generate with :preserve | ||||
| option because the mtime value is based on original .js file. | ||||
| ---
 | ||||
|  lib/rdoc/generator/json_index.rb            |  9 +++++--- | ||||
|  test/rdoc/test_rdoc_generator_json_index.rb | 25 ++++++++++++++++++++- | ||||
|  2 files changed, 30 insertions(+), 4 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/generator/json_index.rb b/lib/rdoc/generator/json_index.rb
 | ||||
| index a059a5d4d0..3a1000033d 100644
 | ||||
| --- a/lib/rdoc/generator/json_index.rb
 | ||||
| +++ b/lib/rdoc/generator/json_index.rb
 | ||||
| @@ -147,12 +147,15 @@ def generate
 | ||||
|   | ||||
|        JSON.dump data, io, 0 | ||||
|      end | ||||
| +    unless ENV['SOURCE_DATE_EPOCH'].nil?
 | ||||
| +      index_file.utime index_file.atime, Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime
 | ||||
| +    end
 | ||||
|   | ||||
|      Dir.chdir @template_dir do | ||||
|        Dir['**/*.js'].each do |source| | ||||
|          dest = File.join out_dir, source | ||||
|   | ||||
| -        FileUtils.install source, dest, :mode => 0644, :verbose => $DEBUG_RDOC
 | ||||
| +        FileUtils.install source, dest, :mode => 0644, :preserve => true, :verbose => $DEBUG_RDOC
 | ||||
|        end | ||||
|      end | ||||
|    end | ||||
| @@ -175,7 +178,7 @@ def generate_gzipped
 | ||||
|      debug_msg "Writing gzipped search index to %s" % outfile | ||||
|   | ||||
|      Zlib::GzipWriter.open(outfile) do |gz| | ||||
| -      gz.mtime = 1 # make output reproducible
 | ||||
| +      gz.mtime = File.mtime(search_index_file)
 | ||||
|        gz.orig_name = search_index_file.basename.to_s | ||||
|        gz.write search_index | ||||
|        gz.close | ||||
| @@ -193,7 +196,7 @@ def generate_gzipped
 | ||||
|          debug_msg "Writing gzipped file to %s" % outfile | ||||
|   | ||||
|          Zlib::GzipWriter.open(outfile) do |gz| | ||||
| -          gz.mtime = 1 # make output reproducible
 | ||||
| +          gz.mtime = File.mtime(dest)
 | ||||
|            gz.orig_name = dest.basename.to_s | ||||
|            gz.write data | ||||
|            gz.close | ||||
| diff --git a/test/rdoc/test_rdoc_generator_json_index.rb b/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| index 6cb5463d29..65e7f087cc 100644
 | ||||
| --- a/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| @@ -8,7 +8,7 @@ class TestRDocGeneratorJsonIndex < RDoc::TestCase
 | ||||
|    def setup | ||||
|      super | ||||
|   | ||||
| -    @tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_darkfish_#{$$}"
 | ||||
| +    @tmpdir = Dir.mktmpdir "test_rdoc_generator_darkfish_#{$$}_"
 | ||||
|      FileUtils.mkdir_p @tmpdir | ||||
|   | ||||
|      @options = RDoc::Options.new | ||||
| @@ -89,12 +89,21 @@ def test_file_dir
 | ||||
|    end | ||||
|   | ||||
|    def test_generate | ||||
| +    now = Time.now
 | ||||
|      @g.generate | ||||
|   | ||||
|      assert_file 'js/searcher.js' | ||||
|      assert_file 'js/navigation.js' | ||||
|      assert_file 'js/search_index.js' | ||||
|   | ||||
| +    orig_file = Pathname(File.join @pwd, 'lib/rdoc/generator/template/json_index/js/navigation.js')
 | ||||
| +    generated_file = Pathname(File.join @tmpdir, 'js/navigation.js')
 | ||||
| +    assert_equal orig_file.mtime, generated_file.mtime
 | ||||
| +    assert generated_file.mtime < now, '.js files should be the same timestamp'
 | ||||
| +
 | ||||
| +    generated_search_index = Pathname(File.join @tmpdir, 'js/search_index.js')
 | ||||
| +    assert generated_search_index.mtime > (now - 1), 'search_index.js should be generated timestamp'
 | ||||
| +
 | ||||
|      json = File.read 'js/search_index.js' | ||||
|   | ||||
|      json =~ /\Avar search_data = / | ||||
| @@ -137,6 +146,20 @@ def test_generate
 | ||||
|      assert_equal expected, index | ||||
|    end | ||||
|   | ||||
| +  def test_generate_search_index_with_reproducible_builds
 | ||||
| +    backup_epoch = ENV['SOURCE_DATE_EPOCH']
 | ||||
| +    ruby_birthday = Time.parse 'Wed, 24 Feb 1993 21:00:00 +0900'
 | ||||
| +    ENV['SOURCE_DATE_EPOCH'] = ruby_birthday.to_i.to_s
 | ||||
| +
 | ||||
| +    @g.generate
 | ||||
| +
 | ||||
| +    assert_file 'js/search_index.js'
 | ||||
| +    generated_search_index = Pathname(File.join @tmpdir, 'js/search_index.js')
 | ||||
| +    assert_equal ruby_birthday, generated_search_index.mtime
 | ||||
| +
 | ||||
| +    ENV['SOURCE_DATE_EPOCH'] = backup_epoch
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_generate_gzipped | ||||
|      begin | ||||
|        require 'zlib' | ||||
| -- 
 | ||||
| 2.21.0 | ||||
| 
 | ||||
| From 74c1e201f2146e7175e74d6fc0b9386c2e95210f Mon Sep 17 00:00:00 2001 | ||||
| From: aycabta <aycabta@gmail.com> | ||||
| Date: Sat, 27 Jan 2018 17:54:31 +0900 | ||||
| Subject: [PATCH 4/4] Use dirty hack on JRuby for MiniTest 4 | ||||
| 
 | ||||
| ---
 | ||||
|  test/rdoc/test_rdoc_generator_json_index.rb | 6 +++++- | ||||
|  1 file changed, 5 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/test/rdoc/test_rdoc_generator_json_index.rb b/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| index 65e7f087cc..714d496195 100644
 | ||||
| --- a/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_generator_json_index.rb
 | ||||
| @@ -98,7 +98,11 @@ def test_generate
 | ||||
|   | ||||
|      orig_file = Pathname(File.join @pwd, 'lib/rdoc/generator/template/json_index/js/navigation.js') | ||||
|      generated_file = Pathname(File.join @tmpdir, 'js/navigation.js') | ||||
| -    assert_equal orig_file.mtime, generated_file.mtime
 | ||||
| +
 | ||||
| +    # This is dirty hack on JRuby for MiniTest 4
 | ||||
| +    assert orig_file.mtime.inspect == generated_file.mtime.inspect,
 | ||||
| +      '.js files should be tha same timestamp of original'
 | ||||
| +
 | ||||
|      assert generated_file.mtime < now, '.js files should be the same timestamp' | ||||
|   | ||||
|      generated_search_index = Pathname(File.join @tmpdir, 'js/search_index.js') | ||||
| -- 
 | ||||
| 2.21.0 | ||||
| 
 | ||||
| @ -1,486 +0,0 @@ | ||||
| From b0bcb19cb4f95d260c5993df0aaa3667522fb99d Mon Sep 17 00:00:00 2001 | ||||
| From: Kazuki Yamaguchi <k@rhe.jp> | ||||
| Date: Thu, 16 Aug 2018 20:54:47 +0900 | ||||
| Subject: [PATCH 1/2] test/openssl/test_pair: fix deadlock in | ||||
|  test_connect_accept_nonblock | ||||
| 
 | ||||
| Call IO.select with a timeout value and limit the number of retries to | ||||
| prevent stacking forever. | ||||
| 
 | ||||
| Reference: https://github.com/ruby/openssl/issues/214 | ||||
| ---
 | ||||
|  test/openssl/test_pair.rb | 51 ++++++++++++++++++++--------------------------- | ||||
|  1 file changed, 22 insertions(+), 29 deletions(-) | ||||
| 
 | ||||
| diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
 | ||||
| index ea5f0dcf..eac3655e 100644
 | ||||
| --- a/test/openssl/test_pair.rb
 | ||||
| +++ b/test/openssl/test_pair.rb
 | ||||
| @@ -442,7 +442,7 @@ def test_connect_accept_nonblock_no_exception
 | ||||
|    end | ||||
|   | ||||
|    def test_connect_accept_nonblock | ||||
| -    ctx = OpenSSL::SSL::SSLContext.new()
 | ||||
| +    ctx = OpenSSL::SSL::SSLContext.new
 | ||||
|      ctx.cert = @svr_cert | ||||
|      ctx.key = @svr_key | ||||
|      ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") } | ||||
| @@ -451,45 +451,38 @@ def test_connect_accept_nonblock
 | ||||
|   | ||||
|      th = Thread.new { | ||||
|        s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx) | ||||
| -      s2.sync_close = true
 | ||||
| -      begin
 | ||||
| +      5.times {
 | ||||
| +        begin
 | ||||
| +          break s2.accept_nonblock
 | ||||
| +        rescue IO::WaitReadable
 | ||||
| +          IO.select([s2], nil, nil, 1)
 | ||||
| +        rescue IO::WaitWritable
 | ||||
| +          IO.select(nil, [s2], nil, 1)
 | ||||
| +        end
 | ||||
|          sleep 0.2 | ||||
| -        s2.accept_nonblock
 | ||||
| +      }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    s1 = OpenSSL::SSL::SSLSocket.new(sock1)
 | ||||
| +    5.times {
 | ||||
| +      begin
 | ||||
| +        break s1.connect_nonblock
 | ||||
|        rescue IO::WaitReadable | ||||
| -        IO.select([s2])
 | ||||
| -        retry
 | ||||
| +        IO.select([s1], nil, nil, 1)
 | ||||
|        rescue IO::WaitWritable | ||||
| -        IO.select(nil, [s2])
 | ||||
| -        retry
 | ||||
| +        IO.select(nil, [s1], nil, 1)
 | ||||
|        end | ||||
| -      s2
 | ||||
| -    }
 | ||||
| -
 | ||||
| -    sleep 0.1
 | ||||
| -    ctx = OpenSSL::SSL::SSLContext.new()
 | ||||
| -    s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
 | ||||
| -    begin
 | ||||
|        sleep 0.2 | ||||
| -      s1.connect_nonblock
 | ||||
| -    rescue IO::WaitReadable
 | ||||
| -      IO.select([s1])
 | ||||
| -      retry
 | ||||
| -    rescue IO::WaitWritable
 | ||||
| -      IO.select(nil, [s1])
 | ||||
| -      retry
 | ||||
| -    end
 | ||||
| -    s1.sync_close = true
 | ||||
| +    }
 | ||||
|   | ||||
|      s2 = th.value | ||||
|   | ||||
|      s1.print "a\ndef" | ||||
|      assert_equal("a\n", s2.gets) | ||||
|    ensure | ||||
| -    th.join if th
 | ||||
| -    s1.close if s1 && !s1.closed?
 | ||||
| -    s2.close if s2 && !s2.closed?
 | ||||
| -    sock1.close if sock1 && !sock1.closed?
 | ||||
| -    sock2.close if sock2 && !sock2.closed?
 | ||||
| +    sock1&.close
 | ||||
| +    sock2&.close
 | ||||
| +    th&.join
 | ||||
|    end | ||||
|  end | ||||
|   | ||||
| 
 | ||||
| From 5ba99ad7ae1267ed964f53906530579299f3fcc6 Mon Sep 17 00:00:00 2001 | ||||
| From: Kazuki Yamaguchi <k@rhe.jp> | ||||
| Date: Thu, 16 Aug 2018 20:04:13 +0900 | ||||
| Subject: [PATCH 2/2] test: use larger keys for SSL tests | ||||
| 
 | ||||
| Some systems enforce a system-wide policy to restrict key sizes used in | ||||
| SSL/TLS. Use larger ones if possible so that the test suite runs | ||||
| successfully. | ||||
| 
 | ||||
| New PEM files test/openssl/fixtures/pkey/{dh-1,rsa-1,rsa-2,rsa-3}.pem are added | ||||
| to the tree, and SSL tests now use them instead of the fixed-size keys. | ||||
| 
 | ||||
| Reference: https://github.com/ruby/openssl/issues/215 | ||||
| ---
 | ||||
|  test/openssl/fixtures/pkey/dh-1.pem  | 13 +++++++++ | ||||
|  test/openssl/fixtures/pkey/rsa-1.pem | 51 ++++++++++++++++++++++++++++++++++++ | ||||
|  test/openssl/fixtures/pkey/rsa-2.pem | 51 ++++++++++++++++++++++++++++++++++++ | ||||
|  test/openssl/fixtures/pkey/rsa-3.pem | 51 ++++++++++++++++++++++++++++++++++++ | ||||
|  test/openssl/test_pair.rb            |  8 +++--- | ||||
|  test/openssl/test_pkey_dh.rb         |  8 +++--- | ||||
|  test/openssl/test_ssl.rb             | 11 ++++---- | ||||
|  test/openssl/utils.rb                | 14 +++++----- | ||||
|  8 files changed, 186 insertions(+), 21 deletions(-) | ||||
|  create mode 100644 test/openssl/fixtures/pkey/dh-1.pem | ||||
|  create mode 100644 test/openssl/fixtures/pkey/rsa-1.pem | ||||
|  create mode 100644 test/openssl/fixtures/pkey/rsa-2.pem | ||||
|  create mode 100644 test/openssl/fixtures/pkey/rsa-3.pem | ||||
| 
 | ||||
| diff --git a/test/openssl/fixtures/pkey/dh-1.pem b/test/openssl/fixtures/pkey/dh-1.pem
 | ||||
| new file mode 100644 | ||||
| index 00000000..3340a6a1
 | ||||
| --- /dev/null
 | ||||
| +++ b/test/openssl/fixtures/pkey/dh-1.pem
 | ||||
| @@ -0,0 +1,13 @@
 | ||||
| +-----BEGIN DH PARAMETERS-----
 | ||||
| +MIICCAKCAgEAvRzXYxY6L2DjeYmm1eowtMDu1it3j+VwFr6s6PRWzc1apMtztr9G
 | ||||
| +xZ2mYndUAJLgNLO3n2fUDCYVMB6ZkcekW8Siocof3xWiMA6wqZ6uw0dsE3q7ZX+6
 | ||||
| +TLjgSjaXeGvjutvuEwVrFeaUi83bMgfXN8ToxIQVprIF35sYFt6fpbFATKfW7qqi
 | ||||
| +P1pQkjmCskU4tztaWvlLh0qg85wuQGnpJaQT3gS30378i0IGbA0EBvJcSpTHYbLa
 | ||||
| +nsdI9bfN/ZVgeolVMNMU9/n8R8vRhNPcHuciFwaqS656q+HavCIyxw/LfjSwwFvR
 | ||||
| +TngCn0wytRErkzFIXnRKckh8/BpI4S+0+l1NkOwG4WJ55KJ/9OOdZW5o/QCp2bDi
 | ||||
| +E0JN1EP/gkSom/prq8JR/yEqtsy99uc5nUxPmzv0IgdcFHZEfiQU7iRggEbx7qfQ
 | ||||
| +Ve55XksmmJInmpCy1bSabAEgIKp8Ckt5KLYZ0RgTXUhcEpsxEo6cuAwoSJT5o4Rp
 | ||||
| +yG3xow2ozPcqZkvb+d2CHj1sc54w9BVFAjVANEKmRil/9WKz14bu3wxEhOPqC54n
 | ||||
| +QojjLcoXSoT66ZUOQnYxTSiLtzoKGPy8cAVPbkBrXz2u2sj5gcvr1JjoGjdHm9/3
 | ||||
| +qnqC8fsTz8UndKNIQC337o4K0833bQMzRGl1/qjbAPit2B7E3b6xTZMCAQI=
 | ||||
| +-----END DH PARAMETERS-----
 | ||||
| diff --git a/test/openssl/fixtures/pkey/rsa-1.pem b/test/openssl/fixtures/pkey/rsa-1.pem
 | ||||
| new file mode 100644 | ||||
| index 00000000..bd5a624f
 | ||||
| --- /dev/null
 | ||||
| +++ b/test/openssl/fixtures/pkey/rsa-1.pem
 | ||||
| @@ -0,0 +1,51 @@
 | ||||
| +-----BEGIN RSA PRIVATE KEY-----
 | ||||
| +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
 | ||||
| +-----END RSA PRIVATE KEY-----
 | ||||
| diff --git a/test/openssl/fixtures/pkey/rsa-2.pem b/test/openssl/fixtures/pkey/rsa-2.pem
 | ||||
| new file mode 100644 | ||||
| index 00000000..e4fd4f43
 | ||||
| --- /dev/null
 | ||||
| +++ b/test/openssl/fixtures/pkey/rsa-2.pem
 | ||||
| @@ -0,0 +1,51 @@
 | ||||
| +-----BEGIN RSA PRIVATE KEY-----
 | ||||
| +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
 | ||||
| +-----END RSA PRIVATE KEY-----
 | ||||
| diff --git a/test/openssl/fixtures/pkey/rsa-3.pem b/test/openssl/fixtures/pkey/rsa-3.pem
 | ||||
| new file mode 100644 | ||||
| index 00000000..6c9c9ced
 | ||||
| --- /dev/null
 | ||||
| +++ b/test/openssl/fixtures/pkey/rsa-3.pem
 | ||||
| @@ -0,0 +1,51 @@
 | ||||
| +-----BEGIN RSA PRIVATE KEY-----
 | ||||
| +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
 | ||||
| +-----END RSA PRIVATE KEY-----
 | ||||
| diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
 | ||||
| index eac3655e..8d6ca1e9 100644
 | ||||
| --- a/test/openssl/test_pair.rb
 | ||||
| +++ b/test/openssl/test_pair.rb
 | ||||
| @@ -10,7 +10,7 @@ def setup
 | ||||
|      ee_exts = [ | ||||
|        ["keyUsage", "keyEncipherment,digitalSignature", true], | ||||
|      ] | ||||
| -    @svr_key = OpenSSL::TestUtils::Fixtures.pkey("rsa1024")
 | ||||
| +    @svr_key = OpenSSL::TestUtils::Fixtures.pkey("rsa-1")
 | ||||
|      @svr_cert = issue_cert(svr_dn, @svr_key, 1, ee_exts, nil, nil) | ||||
|    end | ||||
|   | ||||
| @@ -23,7 +23,7 @@ def ssl_pair
 | ||||
|        sctx = OpenSSL::SSL::SSLContext.new | ||||
|        sctx.cert = @svr_cert | ||||
|        sctx.key = @svr_key | ||||
| -      sctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
 | ||||
| +      sctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey("dh-1") }
 | ||||
|        sctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION | ||||
|        ssls = OpenSSL::SSL::SSLServer.new(tcps, sctx) | ||||
|        ns = ssls.accept | ||||
| @@ -397,7 +397,7 @@ def test_connect_accept_nonblock_no_exception
 | ||||
|      ctx2 = OpenSSL::SSL::SSLContext.new | ||||
|      ctx2.cert = @svr_cert | ||||
|      ctx2.key = @svr_key | ||||
| -    ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
 | ||||
| +    ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey("dh-1") }
 | ||||
|   | ||||
|      sock1, sock2 = tcp_pair | ||||
|   | ||||
| @@ -445,7 +445,7 @@ def test_connect_accept_nonblock
 | ||||
|      ctx = OpenSSL::SSL::SSLContext.new | ||||
|      ctx.cert = @svr_cert | ||||
|      ctx.key = @svr_key | ||||
| -    ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
 | ||||
| +    ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey("dh-1") }
 | ||||
|   | ||||
|      sock1, sock2 = tcp_pair | ||||
|   | ||||
| diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
 | ||||
| index fb713813..79bf9bb7 100644
 | ||||
| --- a/test/openssl/test_pkey_dh.rb
 | ||||
| +++ b/test/openssl/test_pkey_dh.rb
 | ||||
| @@ -19,7 +19,7 @@ def test_new_break
 | ||||
|    end | ||||
|   | ||||
|    def test_DHparams | ||||
| -    dh1024 = Fixtures.pkey_dh("dh1024")
 | ||||
| +    dh1024 = Fixtures.pkey("dh1024")
 | ||||
|      asn1 = OpenSSL::ASN1::Sequence([ | ||||
|        OpenSSL::ASN1::Integer(dh1024.p), | ||||
|        OpenSSL::ASN1::Integer(dh1024.g) | ||||
| @@ -42,7 +42,7 @@ def test_DHparams
 | ||||
|    end | ||||
|   | ||||
|    def test_public_key | ||||
| -    dh = Fixtures.pkey_dh("dh1024")
 | ||||
| +    dh = Fixtures.pkey("dh1024")
 | ||||
|      public_key = dh.public_key | ||||
|      assert_no_key(public_key) #implies public_key.public? is false! | ||||
|      assert_equal(dh.to_der, public_key.to_der) | ||||
| @@ -50,14 +50,14 @@ def test_public_key
 | ||||
|    end | ||||
|   | ||||
|    def test_generate_key | ||||
| -    dh = Fixtures.pkey_dh("dh1024").public_key # creates a copy
 | ||||
| +    dh = Fixtures.pkey("dh1024").public_key # creates a copy
 | ||||
|      assert_no_key(dh) | ||||
|      dh.generate_key! | ||||
|      assert_key(dh) | ||||
|    end | ||||
|   | ||||
|    def test_key_exchange | ||||
| -    dh = Fixtures.pkey_dh("dh1024")
 | ||||
| +    dh = Fixtures.pkey("dh1024")
 | ||||
|      dh2 = dh.public_key | ||||
|      dh.generate_key! | ||||
|      dh2.generate_key! | ||||
| diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
 | ||||
| index 408c7d82..2633f7c4 100644
 | ||||
| --- a/test/openssl/test_ssl.rb
 | ||||
| +++ b/test/openssl/test_ssl.rb
 | ||||
| @@ -708,7 +708,7 @@ def socketpair
 | ||||
|   | ||||
|    def test_tlsext_hostname | ||||
|      fooctx = OpenSSL::SSL::SSLContext.new | ||||
| -    fooctx.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
 | ||||
| +    fooctx.tmp_dh_callback = proc { Fixtures.pkey("dh-1") }
 | ||||
|      fooctx.cert = @cli_cert | ||||
|      fooctx.key = @cli_key | ||||
|   | ||||
| @@ -760,7 +760,7 @@ def test_servername_cb_raises_an_exception_on_unknown_objects
 | ||||
|      ctx2 = OpenSSL::SSL::SSLContext.new | ||||
|      ctx2.cert = @svr_cert | ||||
|      ctx2.key = @svr_key | ||||
| -    ctx2.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
 | ||||
| +    ctx2.tmp_dh_callback = proc { Fixtures.pkey("dh-1") }
 | ||||
|      ctx2.servername_cb = lambda { |args| Object.new } | ||||
|   | ||||
|      sock1, sock2 = socketpair | ||||
| @@ -1140,7 +1140,7 @@ def test_alpn_protocol_selection_cancel
 | ||||
|      ctx1 = OpenSSL::SSL::SSLContext.new | ||||
|      ctx1.cert = @svr_cert | ||||
|      ctx1.key = @svr_key | ||||
| -    ctx1.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
 | ||||
| +    ctx1.tmp_dh_callback = proc { Fixtures.pkey("dh-1") }
 | ||||
|      ctx1.alpn_select_cb = -> (protocols) { nil } | ||||
|      ssl1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) | ||||
|   | ||||
| @@ -1382,20 +1382,21 @@ def test_get_ephemeral_key
 | ||||
|    def test_dh_callback | ||||
|      pend "TLS 1.2 is not supported" unless tls12_supported? | ||||
|   | ||||
| +    dh = Fixtures.pkey("dh-1")
 | ||||
|      called = false | ||||
|      ctx_proc = -> ctx { | ||||
|        ctx.ssl_version = :TLSv1_2 | ||||
|        ctx.ciphers = "DH:!NULL" | ||||
|        ctx.tmp_dh_callback = ->(*args) { | ||||
|          called = true | ||||
| -        Fixtures.pkey_dh("dh1024")
 | ||||
| +        dh
 | ||||
|        } | ||||
|      } | ||||
|      start_server(ctx_proc: ctx_proc) do |port| | ||||
|        server_connect(port) { |ssl| | ||||
|          assert called, "dh callback should be called" | ||||
|          if ssl.respond_to?(:tmp_key) | ||||
| -          assert_equal Fixtures.pkey_dh("dh1024").to_der, ssl.tmp_key.to_der
 | ||||
| +          assert_equal dh.to_der, ssl.tmp_key.to_der
 | ||||
|          end | ||||
|        } | ||||
|      end | ||||
| diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
 | ||||
| index b7ddd891..fe626ade 100644
 | ||||
| --- a/test/openssl/utils.rb
 | ||||
| +++ b/test/openssl/utils.rb
 | ||||
| @@ -42,10 +42,8 @@ module Fixtures
 | ||||
|   | ||||
|      def pkey(name) | ||||
|        OpenSSL::PKey.read(read_file("pkey", name)) | ||||
| -    end
 | ||||
| -
 | ||||
| -    def pkey_dh(name)
 | ||||
| -      # DH parameters can be read by OpenSSL::PKey.read atm
 | ||||
| +    rescue OpenSSL::PKey::PKeyError
 | ||||
| +      # TODO: DH parameters can be read by OpenSSL::PKey.read atm
 | ||||
|        OpenSSL::PKey::DH.new(read_file("pkey", name)) | ||||
|      end | ||||
|   | ||||
| @@ -157,9 +155,9 @@ class OpenSSL::SSLTestCase < OpenSSL::TestCase
 | ||||
|   | ||||
|    def setup | ||||
|      super | ||||
| -    @ca_key  = Fixtures.pkey("rsa2048")
 | ||||
| -    @svr_key = Fixtures.pkey("rsa1024")
 | ||||
| -    @cli_key = Fixtures.pkey("rsa2048")
 | ||||
| +    @ca_key  = Fixtures.pkey("rsa-1")
 | ||||
| +    @svr_key = Fixtures.pkey("rsa-2")
 | ||||
| +    @cli_key = Fixtures.pkey("rsa-3")
 | ||||
|      @ca  = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA") | ||||
|      @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") | ||||
|      @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") | ||||
| @@ -200,7 +198,7 @@ def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE, start_immediately: true
 | ||||
|        ctx.cert_store = store | ||||
|        ctx.cert = @svr_cert | ||||
|        ctx.key = @svr_key | ||||
| -      ctx.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
 | ||||
| +      ctx.tmp_dh_callback = proc { Fixtures.pkey("dh-1") }
 | ||||
|        ctx.verify_mode = verify_mode | ||||
|        ctx_proc.call(ctx) if ctx_proc | ||||
|   | ||||
| @ -1,73 +0,0 @@ | ||||
| From 8e2ed0b9d965a526b29f9dc3bff8e9fe33dae98d Mon Sep 17 00:00:00 2001 | ||||
| From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Tue, 12 Apr 2022 11:49:45 +0000 | ||||
| Subject: [PATCH] Fix CVE-2022-28739 Buffer overrun in str2float. | ||||
| 
 | ||||
| CVE-2022-28739: Buffer overrun in String-to-Float conversion | ||||
| Backported from upstream Ruby 2.6.10, | ||||
| Git commit: | ||||
| https://github.com/ruby/ruby/commit/69f9992ed41920389d4185141a14f02f89a4d306 | ||||
| 
 | ||||
| ==== Original commit message
 | ||||
| 
 | ||||
| Fix dtoa buffer overrun | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67957 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  test/ruby/test_float.rb | 18 ++++++++++++++++++ | ||||
|  util.c                  |  3 ++- | ||||
|  2 files changed, 20 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
 | ||||
| index 7fabfd3..78c63c2 100644
 | ||||
| --- a/test/ruby/test_float.rb
 | ||||
| +++ b/test/ruby/test_float.rb
 | ||||
| @@ -171,6 +171,24 @@ class TestFloat < Test::Unit::TestCase
 | ||||
|        assert_raise(ArgumentError, n += z + "A") {Float(n)} | ||||
|        assert_raise(ArgumentError, n += z + ".0") {Float(n)} | ||||
|      end | ||||
| +
 | ||||
| +    x = nil
 | ||||
| +    2000.times do
 | ||||
| +      x = Float("0x"+"0"*30)
 | ||||
| +      break unless x == 0.0
 | ||||
| +    end
 | ||||
| +    assert_equal(0.0, x, ->{"%a" % x})
 | ||||
| +    x = nil
 | ||||
| +    2000.times do
 | ||||
| +      begin
 | ||||
| +        x = Float("0x1."+"0"*270)
 | ||||
| +      rescue ArgumentError => e
 | ||||
| +        raise unless /"0x1\.0{270}"/ =~ e.message
 | ||||
| +      else
 | ||||
| +        break
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +    assert_nil(x, ->{"%a" % x})
 | ||||
|    end | ||||
|   | ||||
|    def test_divmod | ||||
| diff --git a/util.c b/util.c
 | ||||
| index 2222744..f1d910f 100644
 | ||||
| --- a/util.c
 | ||||
| +++ b/util.c
 | ||||
| @@ -2046,6 +2046,7 @@ break2:
 | ||||
|  	    if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; | ||||
|  	    if (*s == '0') { | ||||
|  		while (*++s == '0'); | ||||
| +		if (!*s) goto ret;
 | ||||
|  		s1 = strchr(hexdigit, *s); | ||||
|  	    } | ||||
|  	    if (s1 != NULL) { | ||||
| @@ -2068,7 +2069,7 @@ break2:
 | ||||
|  		for (; *s && (s1 = strchr(hexdigit, *s)); ++s) { | ||||
|  		    adj += aadj * ((s1 - hexdigit) & 15); | ||||
|  		    if ((aadj /= 16) == 0.0) { | ||||
| -			while (strchr(hexdigit, *++s));
 | ||||
| +			while (*++s && strchr(hexdigit, *s));
 | ||||
|  			break; | ||||
|  		    } | ||||
|  		} | ||||
| -- 
 | ||||
| 2.41.0 | ||||
| 
 | ||||
| @ -1,61 +0,0 @@ | ||||
| diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c
 | ||||
| index 1a80b2b..b997e23 100644
 | ||||
| --- a/ext/fiddle/closure.c
 | ||||
| +++ b/ext/fiddle/closure.c
 | ||||
| @@ -13,25 +13,11 @@ typedef struct {
 | ||||
|      ffi_type **argv; | ||||
|  } fiddle_closure; | ||||
|   | ||||
| -#if defined(USE_FFI_CLOSURE_ALLOC)
 | ||||
| -#elif defined(__OpenBSD__) || defined(__APPLE__) || defined(__linux__)
 | ||||
| -# define USE_FFI_CLOSURE_ALLOC 0
 | ||||
| -#elif defined(RUBY_LIBFFI_MODVERSION) && RUBY_LIBFFI_MODVERSION < 3000005 && \
 | ||||
| -	(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64))
 | ||||
| -# define USE_FFI_CLOSURE_ALLOC 0
 | ||||
| -#else
 | ||||
| -# define USE_FFI_CLOSURE_ALLOC 1
 | ||||
| -#endif
 | ||||
| -
 | ||||
|  static void | ||||
|  dealloc(void * ptr) | ||||
|  { | ||||
|      fiddle_closure * cls = (fiddle_closure *)ptr; | ||||
| -#if USE_FFI_CLOSURE_ALLOC
 | ||||
|      ffi_closure_free(cls->pcl); | ||||
| -#else
 | ||||
| -    munmap(cls->pcl, sizeof(*cls->pcl));
 | ||||
| -#endif
 | ||||
|      if (cls->argv) xfree(cls->argv); | ||||
|      xfree(cls); | ||||
|  } | ||||
| @@ -205,12 +191,7 @@ allocate(VALUE klass)
 | ||||
|      VALUE i = TypedData_Make_Struct(klass, fiddle_closure, | ||||
|  	    &closure_data_type, closure); | ||||
|   | ||||
| -#if USE_FFI_CLOSURE_ALLOC
 | ||||
|      closure->pcl = ffi_closure_alloc(sizeof(ffi_closure), &closure->code); | ||||
| -#else
 | ||||
| -    closure->pcl = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
 | ||||
| -        MAP_ANON | MAP_PRIVATE, -1, 0);
 | ||||
| -#endif
 | ||||
|   | ||||
|      return i; | ||||
|  } | ||||
| @@ -257,17 +238,8 @@ initialize(int rbargc, VALUE argv[], VALUE self)
 | ||||
|      if (FFI_OK != result) | ||||
|  	rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); | ||||
|   | ||||
| -#if USE_FFI_CLOSURE_ALLOC
 | ||||
|      result = ffi_prep_closure_loc(pcl, cif, callback, | ||||
|  		(void *)self, cl->code); | ||||
| -#else
 | ||||
| -    result = ffi_prep_closure(pcl, cif, callback, (void *)self);
 | ||||
| -    cl->code = (void *)pcl;
 | ||||
| -    i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC);
 | ||||
| -    if (i) {
 | ||||
| -	rb_sys_fail("mprotect");
 | ||||
| -    }
 | ||||
| -#endif
 | ||||
|   | ||||
|      if (FFI_OK != result) | ||||
|  	rb_raise(rb_eRuntimeError, "error prepping closure %d", result); | ||||
| @ -1,247 +0,0 @@ | ||||
| commit be5a83e84a34091f2a4e3c6dfb911b20e78e690c | ||||
| Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date:   Wed Jul 7 10:34:08 2021 +0000 | ||||
| 
 | ||||
|     Ignore IP addresses in PASV responses by default, and add new option use_pasv_ip | ||||
|      | ||||
|     This fixes CVE-2021-31810. | ||||
|     Reported by Alexandr Savca. | ||||
|      | ||||
|     Co-authored-by: Shugo Maeda <shugo@ruby-lang.org> | ||||
|      | ||||
|      | ||||
|     git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| 
 | ||||
| diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
 | ||||
| index e68d825dcf..c5d669d898 100644
 | ||||
| --- a/lib/net/ftp.rb
 | ||||
| +++ b/lib/net/ftp.rb
 | ||||
| @@ -97,6 +97,10 @@ class FTP < Protocol
 | ||||
|      # When +true+, the connection is in passive mode.  Default: +true+. | ||||
|      attr_accessor :passive | ||||
|   | ||||
| +    # When +true+, use the IP address in PASV responses.  Otherwise, it uses
 | ||||
| +    # the same IP address for the control connection.  Default: +false+.
 | ||||
| +    attr_accessor :use_pasv_ip
 | ||||
| +
 | ||||
|      # When +true+, all traffic to and from the server is written | ||||
|      # to +$stdout+.  Default: +false+. | ||||
|      attr_accessor :debug_mode | ||||
| @@ -205,6 +209,9 @@ def FTP.open(host, *args)
 | ||||
|      #                          handshake. | ||||
|      #                          See Net::FTP#ssl_handshake_timeout for | ||||
|      #                          details.  Default: +nil+. | ||||
| +    # use_pasv_ip::  When +true+, use the IP address in PASV responses.
 | ||||
| +    #                Otherwise, it uses the same IP address for the control
 | ||||
| +    #                connection.  Default: +false+.
 | ||||
|      # debug_mode::  When +true+, all traffic to and from the server is | ||||
|      #               written to +$stdout+.  Default: +false+. | ||||
|      # | ||||
| @@ -265,6 +272,7 @@ def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil)
 | ||||
|        @open_timeout = options[:open_timeout] | ||||
|        @ssl_handshake_timeout = options[:ssl_handshake_timeout] | ||||
|        @read_timeout = options[:read_timeout] || 60 | ||||
| +      @use_pasv_ip = options[:use_pasv_ip] || false
 | ||||
|        if host | ||||
|          connect(host, options[:port] || FTP_PORT) | ||||
|          if options[:username] | ||||
| @@ -1330,7 +1338,12 @@ def parse227(resp) # :nodoc:
 | ||||
|          raise FTPReplyError, resp | ||||
|        end | ||||
|        if m = /\((?<host>\d+(,\d+){3}),(?<port>\d+,\d+)\)/.match(resp) | ||||
| -        return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
 | ||||
| +        if @use_pasv_ip
 | ||||
| +          host = parse_pasv_ipv4_host(m["host"])
 | ||||
| +        else
 | ||||
| +          host = @bare_sock.remote_address.ip_address
 | ||||
| +        end
 | ||||
| +        return host, parse_pasv_port(m["port"])
 | ||||
|        else | ||||
|          raise FTPProtoError, resp | ||||
|        end | ||||
| diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb
 | ||||
| index a5219644bb..b3fe7774ed 100644
 | ||||
| --- a/test/net/ftp/test_ftp.rb
 | ||||
| +++ b/test/net/ftp/test_ftp.rb
 | ||||
| @@ -61,7 +61,7 @@ def test_connect_fail
 | ||||
|    end | ||||
|   | ||||
|    def test_parse227 | ||||
| -    ftp = Net::FTP.new
 | ||||
| +    ftp = Net::FTP.new(nil, use_pasv_ip: true)
 | ||||
|      host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)") | ||||
|      assert_equal("192.168.0.1", host) | ||||
|      assert_equal(3106, port) | ||||
| @@ -80,6 +80,14 @@ def test_parse227
 | ||||
|      assert_raise(Net::FTPProtoError) do | ||||
|        ftp.send(:parse227, "227 ) foo bar (") | ||||
|      end | ||||
| +
 | ||||
| +    ftp = Net::FTP.new
 | ||||
| +    sock = OpenStruct.new
 | ||||
| +    sock.remote_address = OpenStruct.new
 | ||||
| +    sock.remote_address.ip_address = "10.0.0.1"
 | ||||
| +    ftp.instance_variable_set(:@bare_sock, sock)
 | ||||
| +    host, port = ftp.send(:parse227, "227 Entering Passive Mode (192,168,0,1,12,34)")
 | ||||
| +    assert_equal("10.0.0.1", host)
 | ||||
|    end | ||||
|   | ||||
|    def test_parse228 | ||||
| @@ -2360,10 +2368,155 @@ def test_puttextfile_command_injection
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| +  def test_ignore_pasv_ip
 | ||||
| +    commands = []
 | ||||
| +    binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
 | ||||
| +    server = create_ftp_server(nil, "127.0.0.1") { |sock|
 | ||||
| +      sock.print("220 (test_ftp).\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("331 Please specify the password.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("230 Login successful.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("200 Switching to Binary mode.\r\n")
 | ||||
| +      line = sock.gets
 | ||||
| +      commands.push(line)
 | ||||
| +      data_server = TCPServer.new("127.0.0.1", 0)
 | ||||
| +      port = data_server.local_address.ip_port
 | ||||
| +      sock.printf("227 Entering Passive Mode (999,0,0,1,%s).\r\n",
 | ||||
| +                  port.divmod(256).join(","))
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
 | ||||
| +      conn = data_server.accept
 | ||||
| +      binary_data.scan(/.{1,1024}/nm) do |s|
 | ||||
| +        conn.print(s)
 | ||||
| +      end
 | ||||
| +      conn.shutdown(Socket::SHUT_WR)
 | ||||
| +      conn.read
 | ||||
| +      conn.close
 | ||||
| +      data_server.close
 | ||||
| +      sock.print("226 Transfer complete.\r\n")
 | ||||
| +    }
 | ||||
| +    begin
 | ||||
| +      begin
 | ||||
| +        ftp = Net::FTP.new
 | ||||
| +        ftp.passive = true
 | ||||
| +        ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
 | ||||
| +        ftp.connect("127.0.0.1", server.port)
 | ||||
| +        ftp.login
 | ||||
| +        assert_match(/\AUSER /, commands.shift)
 | ||||
| +        assert_match(/\APASS /, commands.shift)
 | ||||
| +        assert_equal("TYPE I\r\n", commands.shift)
 | ||||
| +        buf = ftp.getbinaryfile("foo", nil)
 | ||||
| +        assert_equal(binary_data, buf)
 | ||||
| +        assert_equal(Encoding::ASCII_8BIT, buf.encoding)
 | ||||
| +        assert_equal("PASV\r\n", commands.shift)
 | ||||
| +        assert_equal("RETR foo\r\n", commands.shift)
 | ||||
| +        assert_equal(nil, commands.shift)
 | ||||
| +      ensure
 | ||||
| +        ftp.close if ftp
 | ||||
| +      end
 | ||||
| +    ensure
 | ||||
| +      server.close
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  def test_use_pasv_ip
 | ||||
| +    commands = []
 | ||||
| +    binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
 | ||||
| +    server = create_ftp_server(nil, "127.0.0.1") { |sock|
 | ||||
| +      sock.print("220 (test_ftp).\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("331 Please specify the password.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("230 Login successful.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("200 Switching to Binary mode.\r\n")
 | ||||
| +      line = sock.gets
 | ||||
| +      commands.push(line)
 | ||||
| +      data_server = TCPServer.new("127.0.0.1", 0)
 | ||||
| +      port = data_server.local_address.ip_port
 | ||||
| +      sock.printf("227 Entering Passive Mode (127,0,0,1,%s).\r\n",
 | ||||
| +                  port.divmod(256).join(","))
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("150 Opening BINARY mode data connection for foo (#{binary_data.size} bytes)\r\n")
 | ||||
| +      conn = data_server.accept
 | ||||
| +      binary_data.scan(/.{1,1024}/nm) do |s|
 | ||||
| +        conn.print(s)
 | ||||
| +      end
 | ||||
| +      conn.shutdown(Socket::SHUT_WR)
 | ||||
| +      conn.read
 | ||||
| +      conn.close
 | ||||
| +      data_server.close
 | ||||
| +      sock.print("226 Transfer complete.\r\n")
 | ||||
| +    }
 | ||||
| +    begin
 | ||||
| +      begin
 | ||||
| +        ftp = Net::FTP.new
 | ||||
| +        ftp.passive = true
 | ||||
| +        ftp.use_pasv_ip = true
 | ||||
| +        ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
 | ||||
| +        ftp.connect("127.0.0.1", server.port)
 | ||||
| +        ftp.login
 | ||||
| +        assert_match(/\AUSER /, commands.shift)
 | ||||
| +        assert_match(/\APASS /, commands.shift)
 | ||||
| +        assert_equal("TYPE I\r\n", commands.shift)
 | ||||
| +        buf = ftp.getbinaryfile("foo", nil)
 | ||||
| +        assert_equal(binary_data, buf)
 | ||||
| +        assert_equal(Encoding::ASCII_8BIT, buf.encoding)
 | ||||
| +        assert_equal("PASV\r\n", commands.shift)
 | ||||
| +        assert_equal("RETR foo\r\n", commands.shift)
 | ||||
| +        assert_equal(nil, commands.shift)
 | ||||
| +      ensure
 | ||||
| +        ftp.close if ftp
 | ||||
| +      end
 | ||||
| +    ensure
 | ||||
| +      server.close
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  def test_use_pasv_invalid_ip
 | ||||
| +    commands = []
 | ||||
| +    binary_data = (0..0xff).map {|i| i.chr}.join * 4 * 3
 | ||||
| +    server = create_ftp_server(nil, "127.0.0.1") { |sock|
 | ||||
| +      sock.print("220 (test_ftp).\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("331 Please specify the password.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("230 Login successful.\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +      sock.print("200 Switching to Binary mode.\r\n")
 | ||||
| +      line = sock.gets
 | ||||
| +      commands.push(line)
 | ||||
| +      sock.print("227 Entering Passive Mode (999,0,0,1,48,57).\r\n")
 | ||||
| +      commands.push(sock.gets)
 | ||||
| +    }
 | ||||
| +    begin
 | ||||
| +      begin
 | ||||
| +        ftp = Net::FTP.new
 | ||||
| +        ftp.passive = true
 | ||||
| +        ftp.use_pasv_ip = true
 | ||||
| +        ftp.read_timeout *= 5 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait
 | ||||
| +        ftp.connect("127.0.0.1", server.port)
 | ||||
| +        ftp.login
 | ||||
| +        assert_match(/\AUSER /, commands.shift)
 | ||||
| +        assert_match(/\APASS /, commands.shift)
 | ||||
| +        assert_equal("TYPE I\r\n", commands.shift)
 | ||||
| +        assert_raise(SocketError) do
 | ||||
| +          ftp.getbinaryfile("foo", nil)
 | ||||
| +        end
 | ||||
| +      ensure
 | ||||
| +        ftp.close if ftp
 | ||||
| +      end
 | ||||
| +    ensure
 | ||||
| +      server.close
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    private | ||||
|   | ||||
| -  def create_ftp_server(sleep_time = nil)
 | ||||
| -    server = TCPServer.new(SERVER_ADDR, 0)
 | ||||
| +  def create_ftp_server(sleep_time = nil, addr = SERVER_ADDR)
 | ||||
| +    server = TCPServer.new(addr, 0)
 | ||||
|      @thread = Thread.start do | ||||
|        if sleep_time | ||||
|          sleep(sleep_time) | ||||
| @ -1,101 +0,0 @@ | ||||
| commit 95ba9053e20ad8d113af37b3f1f4cbfff1f6a8f1 | ||||
| Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date:   Wed Jul 7 10:38:10 2021 +0000 | ||||
| 
 | ||||
|     Fix StartTLS stripping vulnerability | ||||
|      | ||||
|     Reported by Alexandr Savca in https://hackerone.com/reports/1178562 | ||||
|      | ||||
|     Co-authored-by: Shugo Maeda <shugo@ruby-lang.org> | ||||
|      | ||||
|      | ||||
|     git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67950 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| 
 | ||||
| diff --git a/lib/net/imap.rb b/lib/net/imap.rb
 | ||||
| index 1c7e89ba14..91df89b79e 100644
 | ||||
| --- a/lib/net/imap.rb
 | ||||
| +++ b/lib/net/imap.rb
 | ||||
| @@ -1213,12 +1213,14 @@ def get_tagged_response(tag, cmd)
 | ||||
|        end | ||||
|        resp = @tagged_responses.delete(tag) | ||||
|        case resp.name | ||||
| +      when /\A(?:OK)\z/ni
 | ||||
| +        return resp
 | ||||
|        when /\A(?:NO)\z/ni | ||||
|          raise NoResponseError, resp | ||||
|        when /\A(?:BAD)\z/ni | ||||
|          raise BadResponseError, resp | ||||
|        else | ||||
| -        return resp
 | ||||
| +        raise UnknownResponseError, resp
 | ||||
|        end | ||||
|      end | ||||
|   | ||||
| @@ -3714,6 +3716,10 @@ class BadResponseError < ResponseError
 | ||||
|      class ByeResponseError < ResponseError | ||||
|      end | ||||
|   | ||||
| +    # Error raised upon an unknown response from the server.
 | ||||
| +    class UnknownResponseError < ResponseError
 | ||||
| +    end
 | ||||
| +
 | ||||
|      RESPONSE_ERRORS = Hash.new(ResponseError) | ||||
|      RESPONSE_ERRORS["NO"] = NoResponseError | ||||
|      RESPONSE_ERRORS["BAD"] = BadResponseError | ||||
| diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
 | ||||
| index 936f4e0f42..81928cb8fe 100644
 | ||||
| --- a/test/net/imap/test_imap.rb
 | ||||
| +++ b/test/net/imap/test_imap.rb
 | ||||
| @@ -127,6 +127,24 @@ def test_starttls
 | ||||
|          imap.disconnect | ||||
|        end | ||||
|      end | ||||
| +
 | ||||
| +    def test_starttls_stripping
 | ||||
| +      starttls_stripping_test do |port|
 | ||||
| +        imap = Net::IMAP.new("localhost", :port => port)
 | ||||
| +        assert_raise(Net::IMAP::UnknownResponseError) do
 | ||||
| +          imap.starttls(:ca_file => CA_FILE)
 | ||||
| +        end
 | ||||
| +        imap
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  def start_server
 | ||||
| +    th = Thread.new do
 | ||||
| +      yield
 | ||||
| +    end
 | ||||
| +    @threads << th
 | ||||
| +    sleep 0.1 until th.stop?
 | ||||
|    end | ||||
|   | ||||
|    def test_unexpected_eof | ||||
| @@ -760,6 +760,27 @@ def starttls_test
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| +  def starttls_stripping_test
 | ||||
| +    server = create_tcp_server
 | ||||
| +    port = server.addr[1]
 | ||||
| +    start_server do
 | ||||
| +      sock = server.accept
 | ||||
| +      begin
 | ||||
| +        sock.print("* OK test server\r\n")
 | ||||
| +        sock.gets
 | ||||
| +        sock.print("RUBY0001 BUG unhandled command\r\n")
 | ||||
| +      ensure
 | ||||
| +        sock.close
 | ||||
| +        server.close
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +    begin
 | ||||
| +      imap = yield(port)
 | ||||
| +    ensure
 | ||||
| +      imap.disconnect if imap && !imap.disconnected?
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def create_tcp_server | ||||
|      return TCPServer.new(server_addr, 0) | ||||
|    end | ||||
| @ -1,88 +0,0 @@ | ||||
| commit fe3c49c9baeeab58304ede915b7edd18ecf360fc | ||||
| Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date:   Sat Jul 3 17:10:28 2021 +0000 | ||||
| 
 | ||||
|     merge revision(s) b1c73f23,c9ab8fe2: [Backport #17877] | ||||
|      | ||||
|             [ruby/rdoc] Use File.open to fix the OS Command Injection vulnerability in CVE-2021-31799 | ||||
|      | ||||
|             https://github.com/ruby/rdoc/commit/a7f5d6ab88 | ||||
|      | ||||
|             The test for command injection on Unix platforms should be omitted on Windows | ||||
|      | ||||
|      | ||||
|     git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| 
 | ||||
| diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
 | ||||
| index ca2c1abefd..46aace7839 100644
 | ||||
| --- a/lib/rdoc/rdoc.rb
 | ||||
| +++ b/lib/rdoc/rdoc.rb
 | ||||
| @@ -436,7 +436,7 @@ def remove_unparseable files
 | ||||
|      files.reject do |file| | ||||
|        file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or | ||||
|          (file =~ /tags$/i and | ||||
| -         open(file, 'rb') { |io|
 | ||||
| +         File.open(file, 'rb') { |io|
 | ||||
|             io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/ | ||||
|           }) | ||||
|      end | ||||
| --- a/lib/rdoc/encoding.rb	2022-02-16 16:51:28.080178281 +0100
 | ||||
| +++ b/lib/rdoc/encoding.rb	2022-02-16 16:51:37.108160840 +0100
 | ||||
| @@ -18,7 +18,7 @@
 | ||||
|    # unknown character in the target encoding will be replaced with '?' | ||||
|   | ||||
|    def self.read_file filename, encoding, force_transcode = false | ||||
| -    content = open filename, "rb" do |f| f.read end
 | ||||
| +    content = File.open filename, "rb" do |f| f.read end
 | ||||
|      content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/ | ||||
|   | ||||
|      utf8 = content.sub!(/\A\xef\xbb\xbf/, '') | ||||
| --- a/lib/rdoc/parser.rb	2021-04-05 13:46:35.000000000 +0200
 | ||||
| +++ b/lib/rdoc/parser.rb	2022-02-16 15:37:17.904822389 +0100
 | ||||
| @@ -74,7 +74,12 @@
 | ||||
|    def self.binary?(file) | ||||
|      return false if file =~ /\.(rdoc|txt)$/ | ||||
|   | ||||
| -    s = File.read(file, 1024) or return false
 | ||||
| +    begin
 | ||||
| +      open_file = File.open(file)
 | ||||
| +      s = open_file.read(1024) or return false
 | ||||
| +    ensure
 | ||||
| +      open_file.close if open_file
 | ||||
| +    end
 | ||||
|   | ||||
|      return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00") | ||||
|   | ||||
| @@ -92,7 +97,8 @@
 | ||||
|    # http://www.garykessler.net/library/file_sigs.html | ||||
|   | ||||
|    def self.zip? file | ||||
| -    zip_signature = File.read file, 4
 | ||||
| +    zip_signature = ''
 | ||||
| +    File.open(file) { |f| zip_signature = f.read(4) }
 | ||||
|   | ||||
|      zip_signature == "PK\x03\x04" or | ||||
|        zip_signature == "PK\x05\x06" or | ||||
| diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
 | ||||
| index 3bce54b243..123b1a4f87 100644
 | ||||
| --- a/test/rdoc/test_rdoc_rdoc.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_rdoc.rb
 | ||||
| @@ -366,6 +366,18 @@ def test_remove_unparseable_tags_vim
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| +  def test_remove_unparseable_CVE_2021_31799
 | ||||
| +    skip 'for Un*x platforms' if Gem.win_platform?
 | ||||
| +    temp_dir do
 | ||||
| +      file_list = ['| touch evil.txt && echo tags']
 | ||||
| +      file_list.each do |f|
 | ||||
| +        FileUtils.touch f
 | ||||
| +      end
 | ||||
| +      assert_equal file_list, @rdoc.remove_unparseable(file_list)
 | ||||
| +      assert_equal file_list, Dir.children('.')
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_setup_output_dir | ||||
|      Dir.mktmpdir {|d| | ||||
|        path = File.join d, 'testdir' | ||||
| @ -1,42 +0,0 @@ | ||||
| From e2c0652dff671dc6e16a80887e781edc0abc8454 Mon Sep 17 00:00:00 2001 | ||||
| From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | ||||
| Date: Wed, 24 Nov 2021 11:41:55 +0000 | ||||
| Subject: [PATCH 2/2] When parsing cookies, only decode the values | ||||
| 
 | ||||
| git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67953 b2dd03c8-39d4-4d8f-98ff-823fe69b080e | ||||
| ---
 | ||||
|  lib/cgi/cookie.rb           | 1 - | ||||
|  test/cgi/test_cgi_cookie.rb | 5 +++++ | ||||
|  2 files changed, 5 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
 | ||||
| index a2155edb77..009566bb92 100644
 | ||||
| --- a/lib/cgi/cookie.rb
 | ||||
| +++ b/lib/cgi/cookie.rb
 | ||||
| @@ -165,7 +165,6 @@ def self.parse(raw_cookie)
 | ||||
|        raw_cookie.split(/;\s?/).each do |pairs| | ||||
|          name, values = pairs.split('=',2) | ||||
|          next unless name and values | ||||
| -        name = CGI.unescape(name)
 | ||||
|          values ||= "" | ||||
|          values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) } | ||||
|          if cookies.has_key?(name) | ||||
| diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
 | ||||
| index 115a57e4a1..985cc0d7a1 100644
 | ||||
| --- a/test/cgi/test_cgi_cookie.rb
 | ||||
| +++ b/test/cgi/test_cgi_cookie.rb
 | ||||
| @@ -101,6 +101,11 @@ def test_cgi_cookie_parse
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| +  def test_cgi_cookie_parse_not_decode_name
 | ||||
| +    cookie_str = "%66oo=baz;foo=bar"
 | ||||
| +    cookies = CGI::Cookie.parse(cookie_str)
 | ||||
| +    assert_equal({"%66oo" => ["baz"], "foo" => ["bar"]}, cookies)
 | ||||
| +  end
 | ||||
|   | ||||
|    def test_cgi_cookie_arrayinterface | ||||
|      cookie = CGI::Cookie.new('name1', 'a', 'b', 'c') | ||||
| -- 
 | ||||
| 2.36.1 | ||||
| 
 | ||||
| @ -1,918 +0,0 @@ | ||||
| From d5753ec513fa5a4bdcf59fa298642fd0d3a3c364 Mon Sep 17 00:00:00 2001 | ||||
| From: Yusuke Endoh <mame@ruby-lang.org> | ||||
| Date: Fri, 12 Nov 2021 12:11:13 +0900 | ||||
| Subject: [PATCH 1/2] Add length limit option for methods that parses date | ||||
|  strings | ||||
| 
 | ||||
| This patch fixes CVE-2021-41817 and created from the commit | ||||
| <https://github.com/ruby/date/commit/4f9b8e946ba98f0a1774f8e677baa4a45637ebb3>. | ||||
| We didn't merge the files included in the original commit below, as those are | ||||
| for rebasing date gem version. | ||||
| 
 | ||||
| * ext/date/date.gemspec | ||||
| * ext/date/lib/date.rb | ||||
| 
 | ||||
| == Original commit message ==
 | ||||
| 
 | ||||
| `Date.parse` now raises an ArgumentError when a given date string is | ||||
| longer than 128. You can configure the limit by giving `limit` keyword | ||||
| arguments like `Date.parse(str, limit: 1000)`. If you pass `limit: nil`, | ||||
| the limit is disabled. | ||||
| 
 | ||||
| Not only `Date.parse` but also the following methods are changed. | ||||
| 
 | ||||
| * Date._parse | ||||
| * Date.parse | ||||
| * DateTime.parse | ||||
| * Date._iso8601 | ||||
| * Date.iso8601 | ||||
| * DateTime.iso8601 | ||||
| * Date._rfc3339 | ||||
| * Date.rfc3339 | ||||
| * DateTime.rfc3339 | ||||
| * Date._xmlschema | ||||
| * Date.xmlschema | ||||
| * DateTime.xmlschema | ||||
| * Date._rfc2822 | ||||
| * Date.rfc2822 | ||||
| * DateTime.rfc2822 | ||||
| * Date._rfc822 | ||||
| * Date.rfc822 | ||||
| * DateTime.rfc822 | ||||
| * Date._jisx0301 | ||||
| * Date.jisx0301 | ||||
| * DateTime.jisx0301 | ||||
| ---
 | ||||
|  ext/date/date_core.c         | 384 +++++++++++++++++++++++++++-------- | ||||
|  test/date/test_date_parse.rb |  29 +++ | ||||
|  2 files changed, 325 insertions(+), 88 deletions(-) | ||||
| 
 | ||||
| diff --git a/ext/date/date_core.c b/ext/date/date_core.c
 | ||||
| index c250633426..177ea0f6c5 100644
 | ||||
| --- a/ext/date/date_core.c
 | ||||
| +++ b/ext/date/date_core.c
 | ||||
| @@ -4290,12 +4290,37 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
 | ||||
|   | ||||
|  VALUE date__parse(VALUE str, VALUE comp); | ||||
|   | ||||
| +static size_t
 | ||||
| +get_limit(VALUE opt)
 | ||||
| +{
 | ||||
| +    if (!NIL_P(opt)) {
 | ||||
| +        VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
 | ||||
| +        if (NIL_P(limit)) return SIZE_MAX;
 | ||||
| +        return NUM2SIZET(limit);
 | ||||
| +    }
 | ||||
| +    return 128;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +check_limit(VALUE str, VALUE opt)
 | ||||
| +{
 | ||||
| +    StringValue(str);
 | ||||
| +    size_t slen = RSTRING_LEN(str);
 | ||||
| +    size_t limit = get_limit(opt);
 | ||||
| +    if (slen > limit) {
 | ||||
| +	rb_raise(rb_eArgError,
 | ||||
| +		 "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
|  static VALUE | ||||
|  date_s__parse_internal(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE vstr, vcomp, hash;
 | ||||
| +    VALUE vstr, vcomp, hash, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "11", &vstr, &vcomp);
 | ||||
| +    rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
| +    check_limit(vstr, opt);
 | ||||
|      StringValue(vstr); | ||||
|      if (!rb_enc_str_asciicompat_p(vstr)) | ||||
|  	rb_raise(rb_eArgError, | ||||
| @@ -4320,7 +4345,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
 | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._parse(string[, comp=true])  ->  hash
 | ||||
| + *    Date._parse(string[, comp=true], limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Parses the given representation of date and time, and returns a | ||||
|   * hash of parsed elements.  This method does not function as a | ||||
| @@ -4331,6 +4356,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
 | ||||
|   * it full. | ||||
|   * | ||||
|   *    Date._parse('2001-02-03')	#=> {:year=>2001, :mon=>2, :mday=>3} | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s__parse(int argc, VALUE *argv, VALUE klass) | ||||
| @@ -4340,7 +4369,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
 | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]])  ->  date
 | ||||
| + *    Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Parses the given representation of date and time, and creates a | ||||
|   * date object.  This method does not function as a validator. | ||||
| @@ -4352,13 +4381,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
 | ||||
|   *    Date.parse('2001-02-03')		#=> #<Date: 2001-02-03 ...> | ||||
|   *    Date.parse('20010203')		#=> #<Date: 2001-02-03 ...> | ||||
|   *    Date.parse('3rd Feb 2001')	#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_parse(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, comp, sg;
 | ||||
| +    VALUE str, comp, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "03", &str, &comp, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4370,11 +4404,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE argv2[2], hash;
 | ||||
| -
 | ||||
| -	argv2[0] = str;
 | ||||
| -	argv2[1] = comp;
 | ||||
| -	hash = date_s__parse(2, argv2, klass);
 | ||||
| +        int argc2 = 2;
 | ||||
| +	VALUE argv2[3];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = comp;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__parse(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
| @@ -4388,19 +4423,28 @@ VALUE date__jisx0301(VALUE);
 | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._iso8601(string)  ->  hash
 | ||||
| + *    Date._iso8601(string, limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__iso8601(VALUE klass, VALUE str)
 | ||||
| +date_s__iso8601(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__iso8601(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.iso8601(string='-4712-01-01'[, start=Date::ITALY])  ->  date
 | ||||
| + *    Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some typical ISO 8601 formats. | ||||
| @@ -4408,13 +4452,18 @@ date_s__iso8601(VALUE klass, VALUE str)
 | ||||
|   *    Date.iso8601('2001-02-03')	#=> #<Date: 2001-02-03 ...> | ||||
|   *    Date.iso8601('20010203')		#=> #<Date: 2001-02-03 ...> | ||||
|   *    Date.iso8601('2001-W05-6')	#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_iso8601(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4424,38 +4473,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__iso8601(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__iso8601(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._rfc3339(string)  ->  hash
 | ||||
| + *    Date._rfc3339(string, limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__rfc3339(VALUE klass, VALUE str)
 | ||||
| +date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__rfc3339(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  date
 | ||||
| + *    Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some typical RFC 3339 formats. | ||||
|   * | ||||
|   *    Date.rfc3339('2001-02-03T04:05:06+07:00')	#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_rfc3339(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4465,38 +4532,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__rfc3339(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__rfc3339(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._xmlschema(string)  ->  hash
 | ||||
| + *    Date._xmlschema(string, limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__xmlschema(VALUE klass, VALUE str)
 | ||||
| +date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__xmlschema(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY])  ->  date
 | ||||
| + *    Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some typical XML Schema formats. | ||||
|   * | ||||
|   *    Date.xmlschema('2001-02-03')	#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_xmlschema(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4506,41 +4591,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__xmlschema(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__xmlschema(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._rfc2822(string)  ->  hash
 | ||||
| - *    Date._rfc822(string)   ->  hash
 | ||||
| + *    Date._rfc2822(string, limit: 128)  ->  hash
 | ||||
| + *    Date._rfc822(string, limit: 128)   ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__rfc2822(VALUE klass, VALUE str)
 | ||||
| +date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__rfc2822(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])  ->  date
 | ||||
| - *    Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])   ->  date
 | ||||
| + *    Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
| + *    Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)   ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some typical RFC 2822 formats. | ||||
|   * | ||||
|   *    Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000') | ||||
|   *						#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_rfc2822(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4550,39 +4652,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__rfc2822(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__rfc2822(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._httpdate(string)  ->  hash
 | ||||
| + *    Date._httpdate(string, limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__httpdate(VALUE klass, VALUE str)
 | ||||
| +date_s__httpdate(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__httpdate(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY])  ->  date
 | ||||
| + *    Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some RFC 2616 format. | ||||
|   * | ||||
|   *    Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT') | ||||
|   *						#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_httpdate(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4592,38 +4711,56 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__httpdate(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__httpdate(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date._jisx0301(string)  ->  hash
 | ||||
| + *    Date._jisx0301(string, limit: 128)  ->  hash
 | ||||
|   * | ||||
|   * Returns a hash of parsed elements. | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
| -date_s__jisx0301(VALUE klass, VALUE str)
 | ||||
| +date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
 | ||||
|  { | ||||
| +    VALUE str, opt;
 | ||||
| +
 | ||||
| +    rb_scan_args(argc, argv, "1:", &str, &opt);
 | ||||
| +    check_limit(str, opt);
 | ||||
| +
 | ||||
|      return date__jisx0301(str); | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY])  ->  date
 | ||||
| + *    Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
 | ||||
|   * | ||||
|   * Creates a new Date object by parsing from a string according to | ||||
|   * some typical JIS X 0301 formats. | ||||
|   * | ||||
|   *    Date.jisx0301('H13.02.03')		#=> #<Date: 2001-02-03 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  date_s_jisx0301(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -4633,7 +4770,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__jisx0301(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        if (!NIL_P(opt)) argv2[argc2++] = opt;
 | ||||
| +	VALUE hash = date_s__jisx0301(argc2, argv2, klass);
 | ||||
|  	return d_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
| @@ -7925,7 +8066,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
 | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]])  ->  datetime
 | ||||
| + *    DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128)  ->  datetime
 | ||||
|   * | ||||
|   * Parses the given representation of date and time, and creates a | ||||
|   * DateTime object.  This method does not function as a validator. | ||||
| @@ -7939,13 +8080,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
 | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
|   *    DateTime.parse('3rd Feb 2001 04:05:06 PM') | ||||
|   *				#=> #<DateTime: 2001-02-03T16:05:06+00:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_parse(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, comp, sg;
 | ||||
| +    VALUE str, comp, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "03", &str, &comp, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -7957,18 +8103,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE argv2[2], hash;
 | ||||
| -
 | ||||
| -	argv2[0] = str;
 | ||||
| -	argv2[1] = comp;
 | ||||
| -	hash = date_s__parse(2, argv2, klass);
 | ||||
| +        int argc2 = 2;
 | ||||
| +        VALUE argv2[3];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = comp;
 | ||||
| +        argv2[2] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__parse(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
 | ||||
| + *    DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
 | ||||
|   * | ||||
|   * Creates a new DateTime object by parsing from a string according to | ||||
|   * some typical ISO 8601 formats. | ||||
| @@ -7979,13 +8127,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
 | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
|   *    DateTime.iso8601('2001-W05-6T04:05:06+07:00') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -7995,27 +8148,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__iso8601(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2--;
 | ||||
| +	VALUE hash = date_s__iso8601(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
 | ||||
| + *    DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
 | ||||
|   * | ||||
|   * Creates a new DateTime object by parsing from a string according to | ||||
|   * some typical RFC 3339 formats. | ||||
|   * | ||||
|   *    DateTime.rfc3339('2001-02-03T04:05:06+07:00') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -8025,27 +8188,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__rfc3339(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__rfc3339(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
 | ||||
| + *    DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
 | ||||
|   * | ||||
|   * Creates a new DateTime object by parsing from a string according to | ||||
|   * some typical XML Schema formats. | ||||
|   * | ||||
|   *    DateTime.xmlschema('2001-02-03T04:05:06+07:00') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -8055,28 +8228,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__xmlschema(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__xmlschema(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])  ->  datetime
 | ||||
| - *    DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])   ->  datetime
 | ||||
| + *    DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)  ->  datetime
 | ||||
| + *    DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)   ->  datetime
 | ||||
|   * | ||||
|   * Creates a new DateTime object by parsing from a string according to | ||||
|   * some typical RFC 2822 formats. | ||||
|   * | ||||
|   *     DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -8086,7 +8269,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__rfc2822(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__rfc2822(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
| @@ -8100,13 +8288,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
 | ||||
|   * | ||||
|   *    DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+00:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -8116,27 +8309,37 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__httpdate(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__httpdate(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
|   | ||||
|  /* | ||||
|   * call-seq: | ||||
| - *    DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
 | ||||
| + *    DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
 | ||||
|   * | ||||
|   * Creates a new DateTime object by parsing from a string according to | ||||
|   * some typical JIS X 0301 formats. | ||||
|   * | ||||
|   *    DateTime.jisx0301('H13.02.03T04:05:06+07:00') | ||||
|   *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...> | ||||
| + *
 | ||||
| + * Raise an ArgumentError when the string length is longer than _limit_.
 | ||||
| + * You can stop this check by passing `limit: nil`, but note that
 | ||||
| + * it may take a long time to parse.
 | ||||
|   */ | ||||
|  static VALUE | ||||
|  datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) | ||||
|  { | ||||
| -    VALUE str, sg;
 | ||||
| +    VALUE str, sg, opt;
 | ||||
|   | ||||
| -    rb_scan_args(argc, argv, "02", &str, &sg);
 | ||||
| +    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
 | ||||
| +    if (!NIL_P(opt)) argc--;
 | ||||
|   | ||||
|      switch (argc) { | ||||
|        case 0: | ||||
| @@ -8146,7 +8349,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
 | ||||
|      } | ||||
|   | ||||
|      { | ||||
| -	VALUE hash = date_s__jisx0301(klass, str);
 | ||||
| +        int argc2 = 1;
 | ||||
| +        VALUE argv2[2];
 | ||||
| +        argv2[0] = str;
 | ||||
| +        argv2[1] = opt;
 | ||||
| +        if (!NIL_P(opt)) argc2++;
 | ||||
| +	VALUE hash = date_s__jisx0301(argc2, argv2, klass);
 | ||||
|  	return dt_new_by_frags(klass, hash, sg); | ||||
|      } | ||||
|  } | ||||
| @@ -9297,19 +9505,19 @@ Init_date_core(void)
 | ||||
|      rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1); | ||||
|      rb_define_singleton_method(cDate, "_parse", date_s__parse, -1); | ||||
|      rb_define_singleton_method(cDate, "parse", date_s_parse, -1); | ||||
| -    rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
 | ||||
|      rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1); | ||||
| -    rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
 | ||||
|      rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1); | ||||
| -    rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
 | ||||
|      rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1); | ||||
| -    rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
 | ||||
| -    rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
 | ||||
| +    rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
 | ||||
|      rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1); | ||||
|      rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1); | ||||
| -    rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
 | ||||
|      rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1); | ||||
| -    rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
 | ||||
| +    rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
 | ||||
|      rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1); | ||||
|   | ||||
|  #ifndef NDEBUG | ||||
| diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
 | ||||
| index ac0eb85ca7..f9b160ee8c 100644
 | ||||
| --- a/test/date/test_date_parse.rb
 | ||||
| +++ b/test/date/test_date_parse.rb
 | ||||
| @@ -1,6 +1,7 @@
 | ||||
|  # frozen_string_literal: true | ||||
|  require 'test/unit' | ||||
|  require 'date' | ||||
| +require 'timeout'
 | ||||
|   | ||||
|  class TestDateParse < Test::Unit::TestCase | ||||
|   | ||||
| @@ -1122,4 +1123,32 @@ def test_given_string
 | ||||
|      assert_equal(s0, s) | ||||
|    end | ||||
|   | ||||
| +  def test_length_limit
 | ||||
| +    assert_raise(ArgumentError) { Date._parse("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._iso8601("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._rfc3339("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._xmlschema("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._rfc2822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._rfc822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date._jisx0301("1" * 1000) }
 | ||||
| +
 | ||||
| +    assert_raise(ArgumentError) { Date.parse("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.iso8601("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.rfc3339("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.xmlschema("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.rfc2822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.rfc822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { Date.jisx0301("1" * 1000) }
 | ||||
| +
 | ||||
| +    assert_raise(ArgumentError) { DateTime.parse("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.iso8601("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.rfc3339("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.xmlschema("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.rfc2822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.rfc822("1" * 1000) }
 | ||||
| +    assert_raise(ArgumentError) { DateTime.jisx0301("1" * 1000) }
 | ||||
| +
 | ||||
| +    assert_raise(ArgumentError) { Date._parse("Jan " + "9" * 1000000) }
 | ||||
| +    assert_raise(Timeout::Error) { Timeout.timeout(1) { Date._parse("Jan " + "9" * 1000000, limit: nil) } }
 | ||||
| +  end
 | ||||
|  end | ||||
| -- 
 | ||||
| 2.36.1 | ||||
| 
 | ||||
| @ -1,328 +0,0 @@ | ||||
| From 8fc4b4792919c627183f4ddb6dc256aae49eb738 Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Tue, 22 Nov 2022 13:48:18 +0900 | ||||
| Subject: [PATCH] Fix CVE-2021-33621 HTTP response splitting in CGI. | ||||
| 
 | ||||
| Backported from upstream Ruby, commit: | ||||
| https://github.com/ruby/ruby/commit/7cf697179dab52b0d024543304f4d3ab5fa5e847 | ||||
| 
 | ||||
| Test "CGICookieTest#test_cgi_cookie_new_with_domain" was adjusted to | ||||
| deal with Ruby 2.5 not allowing String with double splat operator. | ||||
| 
 | ||||
| ==== Original commit message
 | ||||
| Merge CGI-0.1.0.2 | ||||
| ---
 | ||||
|  lib/cgi/cookie.rb           | 51 ++++++++++++++++------- | ||||
|  lib/cgi/core.rb             | 45 ++++++++++++-------- | ||||
|  test/cgi/test_cgi_cookie.rb | 82 +++++++++++++++++++++++++++++++++++++ | ||||
|  test/cgi/test_cgi_header.rb |  8 ++++ | ||||
|  4 files changed, 154 insertions(+), 32 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
 | ||||
| index 009566b..f26f015 100644
 | ||||
| --- a/lib/cgi/cookie.rb
 | ||||
| +++ b/lib/cgi/cookie.rb
 | ||||
| @@ -40,6 +40,10 @@ class CGI
 | ||||
|    class Cookie < Array | ||||
|      @@accept_charset="UTF-8" unless defined?(@@accept_charset) | ||||
|   | ||||
| +    TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
 | ||||
| +    PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
 | ||||
| +    DOMAIN_VALUE_RE = %r"\A(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
 | ||||
| +
 | ||||
|      # Create a new CGI::Cookie object. | ||||
|      # | ||||
|      # :call-seq: | ||||
| @@ -72,9 +76,8 @@ class CGI
 | ||||
|        @domain = nil | ||||
|        @expires = nil | ||||
|        if name.kind_of?(String) | ||||
| -        @name = name
 | ||||
| -        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
 | ||||
| -        @path = ($1 or "")
 | ||||
| +        self.name = name
 | ||||
| +        self.path = (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
 | ||||
|          @secure = false | ||||
|          @httponly = false | ||||
|          return super(value) | ||||
| @@ -85,16 +88,11 @@ class CGI
 | ||||
|          raise ArgumentError, "`name' required" | ||||
|        end | ||||
|   | ||||
| -      @name = options["name"]
 | ||||
| +      self.name = options["name"]
 | ||||
|        value = Array(options["value"]) | ||||
|        # simple support for IE | ||||
| -      if options["path"]
 | ||||
| -        @path = options["path"]
 | ||||
| -      else
 | ||||
| -        %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
 | ||||
| -        @path = ($1 or "")
 | ||||
| -      end
 | ||||
| -      @domain = options["domain"]
 | ||||
| +      self.path = options["path"] || (%r|\A(.*/)| =~ ENV["SCRIPT_NAME"] ? $1 : "")
 | ||||
| +      self.domain = options["domain"]
 | ||||
|        @expires = options["expires"] | ||||
|        @secure = options["secure"] == true | ||||
|        @httponly = options["httponly"] == true | ||||
| @@ -102,12 +100,35 @@ class CGI
 | ||||
|        super(value) | ||||
|      end | ||||
|   | ||||
| -    # Name of this cookie, as a +String+
 | ||||
| -    attr_accessor :name
 | ||||
| +    attr_reader :name
 | ||||
| +    # Set name of this cookie
 | ||||
| +    def name=(str)
 | ||||
| +      if str and !TOKEN_RE.match?(str)
 | ||||
| +        raise ArgumentError, "invalid name: #{str.dump}"
 | ||||
| +      end
 | ||||
| +      @name = str
 | ||||
| +    end
 | ||||
| +
 | ||||
|      # Path for which this cookie applies, as a +String+ | ||||
| -    attr_accessor :path
 | ||||
| +    attr_reader :path
 | ||||
| +    # Set path for which this cookie applies
 | ||||
| +    def path=(str)
 | ||||
| +      if str and !PATH_VALUE_RE.match?(str)
 | ||||
| +        raise ArgumentError, "invalid path: #{str.dump}"
 | ||||
| +      end
 | ||||
| +      @path = str
 | ||||
| +    end
 | ||||
| +
 | ||||
|      # Domain for which this cookie applies, as a +String+ | ||||
| -    attr_accessor :domain
 | ||||
| +    attr_reader :domain
 | ||||
| +    # Set domain for which this cookie applies
 | ||||
| +    def domain=(str)
 | ||||
| +      if str and ((str = str.b).bytesize > 255 or !DOMAIN_VALUE_RE.match?(str))
 | ||||
| +        raise ArgumentError, "invalid domain: #{str.dump}"
 | ||||
| +      end
 | ||||
| +      @domain = str
 | ||||
| +    end
 | ||||
| +
 | ||||
|      # Time at which this cookie expires, as a +Time+ | ||||
|      attr_accessor :expires | ||||
|      # True if this cookie is secure; false otherwise | ||||
| diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
 | ||||
| index 9bd7798..7d8b223 100644
 | ||||
| --- a/lib/cgi/core.rb
 | ||||
| +++ b/lib/cgi/core.rb
 | ||||
| @@ -188,17 +188,28 @@ class CGI
 | ||||
|    # Using #header with the HTML5 tag maker will create a <header> element. | ||||
|    alias :header :http_header | ||||
|   | ||||
| +  def _no_crlf_check(str)
 | ||||
| +    if str
 | ||||
| +      str = str.to_s
 | ||||
| +      raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
 | ||||
| +      str
 | ||||
| +    else
 | ||||
| +      nil
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +  private :_no_crlf_check
 | ||||
| +
 | ||||
|    def _header_for_string(content_type) #:nodoc: | ||||
|      buf = ''.dup | ||||
|      if nph?() | ||||
| -      buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
 | ||||
| +      buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
 | ||||
|        buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}" | ||||
| -      buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
 | ||||
| +      buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
 | ||||
|        buf << "Connection: close#{EOL}" | ||||
|      end | ||||
| -    buf << "Content-Type: #{content_type}#{EOL}"
 | ||||
| +    buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
 | ||||
|      if @output_cookies | ||||
| -      @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
 | ||||
| +      @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
 | ||||
|      end | ||||
|      return buf | ||||
|    end # _header_for_string | ||||
| @@ -213,9 +224,9 @@ class CGI
 | ||||
|      ## NPH | ||||
|      options.delete('nph') if defined?(MOD_RUBY) | ||||
|      if options.delete('nph') || nph?() | ||||
| -      protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
 | ||||
| +      protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
 | ||||
|        status = options.delete('status') | ||||
| -      status = HTTP_STATUS[status] || status || '200 OK'
 | ||||
| +      status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
 | ||||
|        buf << "#{protocol} #{status}#{EOL}" | ||||
|        buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}" | ||||
|        options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || '' | ||||
| @@ -223,38 +234,38 @@ class CGI
 | ||||
|      end | ||||
|      ## common headers | ||||
|      status = options.delete('status') | ||||
| -    buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
 | ||||
| +    buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
 | ||||
|      server = options.delete('server') | ||||
| -    buf << "Server: #{server}#{EOL}" if server
 | ||||
| +    buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
 | ||||
|      connection = options.delete('connection') | ||||
| -    buf << "Connection: #{connection}#{EOL}" if connection
 | ||||
| +    buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
 | ||||
|      type = options.delete('type') | ||||
| -    buf << "Content-Type: #{type}#{EOL}" #if type
 | ||||
| +    buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
 | ||||
|      length = options.delete('length') | ||||
| -    buf << "Content-Length: #{length}#{EOL}" if length
 | ||||
| +    buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
 | ||||
|      language = options.delete('language') | ||||
| -    buf << "Content-Language: #{language}#{EOL}" if language
 | ||||
| +    buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
 | ||||
|      expires = options.delete('expires') | ||||
|      buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires | ||||
|      ## cookie | ||||
|      if cookie = options.delete('cookie') | ||||
|        case cookie | ||||
|        when String, Cookie | ||||
| -        buf << "Set-Cookie: #{cookie}#{EOL}"
 | ||||
| +        buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
 | ||||
|        when Array | ||||
|          arr = cookie | ||||
| -        arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
 | ||||
| +        arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
 | ||||
|        when Hash | ||||
|          hash = cookie | ||||
| -        hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
 | ||||
| +        hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
 | ||||
|        end | ||||
|      end | ||||
|      if @output_cookies | ||||
| -      @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
 | ||||
| +      @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
 | ||||
|      end | ||||
|      ## other headers | ||||
|      options.each do |key, value| | ||||
| -      buf << "#{key}: #{value}#{EOL}"
 | ||||
| +      buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
 | ||||
|      end | ||||
|      return buf | ||||
|    end # _header_for_hash | ||||
| diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
 | ||||
| index 985cc0d..7afff5e 100644
 | ||||
| --- a/test/cgi/test_cgi_cookie.rb
 | ||||
| +++ b/test/cgi/test_cgi_cookie.rb
 | ||||
| @@ -60,6 +60,24 @@ class CGICookieTest < Test::Unit::TestCase
 | ||||
|    end | ||||
|   | ||||
|   | ||||
| +  def test_cgi_cookie_new_with_domain
 | ||||
| +    h = {'name'=>'name1', 'value'=>'value1'}
 | ||||
| +    cookie = CGI::Cookie.new({'domain' => 'a.example.com'}.merge(h))
 | ||||
| +    assert_equal('a.example.com', cookie.domain)
 | ||||
| +
 | ||||
| +    cookie = CGI::Cookie.new({'domain'=>'1.example.com'}.merge(h))
 | ||||
| +    assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
 | ||||
| +
 | ||||
| +    assert_raise(ArgumentError) {
 | ||||
| +      CGI::Cookie.new({'domain'=>'-a.example.com'}.merge(h))
 | ||||
| +    }
 | ||||
| +
 | ||||
| +    assert_raise(ArgumentError) {
 | ||||
| +      CGI::Cookie.new({'domain'=>'a-.example.com'}.merge(h))
 | ||||
| +    }
 | ||||
| +  end
 | ||||
| +
 | ||||
| +
 | ||||
|    def test_cgi_cookie_scriptname | ||||
|      cookie = CGI::Cookie.new('name1', 'value1') | ||||
|      assert_equal('', cookie.path) | ||||
| @@ -118,6 +136,70 @@ class CGICookieTest < Test::Unit::TestCase
 | ||||
|    end | ||||
|   | ||||
|   | ||||
| +  def test_cgi_cookie_domain_injection_into_name
 | ||||
| +    name = "a=b; domain=example.com;"
 | ||||
| +    path = "/"
 | ||||
| +    domain = "example.jp"
 | ||||
| +    assert_raise(ArgumentError) do
 | ||||
| +      CGI::Cookie.new('name' => name,
 | ||||
| +                      'value' => "value",
 | ||||
| +                      'domain' => domain,
 | ||||
| +                      'path' => path)
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +
 | ||||
| +  def test_cgi_cookie_newline_injection_into_name
 | ||||
| +    name = "a=b;\r\nLocation: http://example.com#"
 | ||||
| +    path = "/"
 | ||||
| +    domain = "example.jp"
 | ||||
| +    assert_raise(ArgumentError) do
 | ||||
| +      CGI::Cookie.new('name' => name,
 | ||||
| +                      'value' => "value",
 | ||||
| +                      'domain' => domain,
 | ||||
| +                      'path' => path)
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +
 | ||||
| +  def test_cgi_cookie_multibyte_injection_into_name
 | ||||
| +    name = "a=b;\u3042"
 | ||||
| +    path = "/"
 | ||||
| +    domain = "example.jp"
 | ||||
| +    assert_raise(ArgumentError) do
 | ||||
| +      CGI::Cookie.new('name' => name,
 | ||||
| +                      'value' => "value",
 | ||||
| +                      'domain' => domain,
 | ||||
| +                      'path' => path)
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +
 | ||||
| +  def test_cgi_cookie_injection_into_path
 | ||||
| +    name = "name"
 | ||||
| +    path = "/; samesite=none"
 | ||||
| +    domain = "example.jp"
 | ||||
| +    assert_raise(ArgumentError) do
 | ||||
| +      CGI::Cookie.new('name' => name,
 | ||||
| +                      'value' => "value",
 | ||||
| +                      'domain' => domain,
 | ||||
| +                      'path' => path)
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
| +
 | ||||
| +  def test_cgi_cookie_injection_into_domain
 | ||||
| +    name = "name"
 | ||||
| +    path = "/"
 | ||||
| +    domain = "example.jp; samesite=none"
 | ||||
| +    assert_raise(ArgumentError) do
 | ||||
| +      CGI::Cookie.new('name' => name,
 | ||||
| +                      'value' => "value",
 | ||||
| +                      'domain' => domain,
 | ||||
| +                      'path' => path)
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|   | ||||
|    instance_methods.each do |method| | ||||
|      private method if method =~ /^test_(.*)/ && $1 != ENV['TEST'] | ||||
| diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
 | ||||
| index bab2d03..ec2f4de 100644
 | ||||
| --- a/test/cgi/test_cgi_header.rb
 | ||||
| +++ b/test/cgi/test_cgi_header.rb
 | ||||
| @@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
 | ||||
|    end | ||||
|   | ||||
|   | ||||
| +  def test_cgi_http_header_crlf_injection
 | ||||
| +    cgi = CGI.new
 | ||||
| +    assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
 | ||||
| +    assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
 | ||||
| +    assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
 | ||||
| +    assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
 | ||||
| +  end
 | ||||
| +
 | ||||
|   | ||||
|    instance_methods.each do |method| | ||||
|      private method if method =~ /^test_(.*)/ && $1 != ENV['TEST'] | ||||
| -- 
 | ||||
| 2.41.0 | ||||
| 
 | ||||
| @ -1,52 +0,0 @@ | ||||
| From 61fb466ea0b492c990fcd2d681c08f2001d7a659 Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Tue, 28 Mar 2023 17:33:19 +0900 | ||||
| Subject: [PATCH] Fix CVE-2023-28755 ReDos vulnerability in URI. | ||||
| 
 | ||||
| This patch was backported from Ruby 2.7.8 | ||||
| 
 | ||||
| Backported from upstream Ruby, commit: | ||||
| https://github.com/ruby/ruby/commit/6855779d580358a6a0b4c9ee06f20e7cae72955a | ||||
| 
 | ||||
| ===== Original commit message
 | ||||
| 
 | ||||
| Merge URI-0.10.0.2 | ||||
| ---
 | ||||
|  lib/uri/rfc3986_parser.rb | 4 ++-- | ||||
|  test/uri/test_parser.rb   | 7 +++++++ | ||||
|  2 files changed, 9 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb
 | ||||
| index 8712800..ad32368 100644
 | ||||
| --- a/lib/uri/rfc3986_parser.rb
 | ||||
| +++ b/lib/uri/rfc3986_parser.rb
 | ||||
| @@ -3,8 +3,8 @@ module URI
 | ||||
|    class RFC3986_Parser # :nodoc: | ||||
|      # URI defined in RFC3986 | ||||
|      # this regexp is modified not to host is not empty string | ||||
| -    RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
 | ||||
| -    RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+)\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])+)(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
 | ||||
| +    RFC3986_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*+):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
 | ||||
| +    RFC3986_relative_ref = /\A(?<relative-ref>(?<relative-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*+)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:){,1}\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h++\.[!$&-.0-;=A-Z_a-z~]++))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])++))?(?::(?<port>\d*+))?)(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*+))*+)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])++)(?:\/\g<segment>)*+)?)|(?<path-noscheme>(?<segment-nz-nc>(?:%\h\h|[!$&-.0-9;=@-Z_a-z~])++)(?:\/\g<segment>)*+)|(?<path-empty>))(?:\?(?<query>[^#]*+))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*+))?)\z/
 | ||||
|      attr_reader :regexp | ||||
|   | ||||
|      def initialize | ||||
| diff --git a/test/uri/test_parser.rb b/test/uri/test_parser.rb
 | ||||
| index 757ac86..2f70559 100644
 | ||||
| --- a/test/uri/test_parser.rb
 | ||||
| +++ b/test/uri/test_parser.rb
 | ||||
| @@ -45,4 +45,11 @@ class URI::TestParser < Test::Unit::TestCase
 | ||||
|        URI.parse(1) | ||||
|      end | ||||
|    end | ||||
| +
 | ||||
| +  def test_split
 | ||||
| +    assert_equal(["http", nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("http://example.com"))
 | ||||
| +    assert_equal(["http", nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("http://[0::0]"))
 | ||||
| +    assert_equal([nil, nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("//example.com"))
 | ||||
| +    assert_equal([nil, nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("//[0::0]"))
 | ||||
| +  end
 | ||||
|  end | ||||
| -- 
 | ||||
| 2.41.0 | ||||
| 
 | ||||
| @ -1,41 +0,0 @@ | ||||
| From 71c37c29defeab2c98ad4291807efe12427a209f Mon Sep 17 00:00:00 2001 | ||||
| From: Nobuyoshi Nakada <nobu@ruby-lang.org> | ||||
| Date: Tue, 29 Nov 2022 16:22:15 +0900 | ||||
| Subject: [PATCH] Fix CVE-2023-28756 ReDoS vulnerability in Time. | ||||
| 
 | ||||
| Backported from: Ruby 2.7.8 | ||||
| Backported from the following commits: | ||||
| https://github.com/ruby/ruby/commit/2cb830602f52e7e76c6781115e7938b21f881c4f | ||||
| https://github.com/ruby/ruby/commit/e3f18f7d2e034f20053d7bf2fc7a50f8b7e1a27a | ||||
| 
 | ||||
| Do not include the test case, as assert_linear_time was introduced in Ruby 2.7. | ||||
| 
 | ||||
| ==== Original commit message(s)
 | ||||
| 
 | ||||
| Fix quadratic backtracking on invalid time | ||||
| 
 | ||||
| Make RFC2822 regexp linear | ||||
| 
 | ||||
| https://hackerone.com/reports/1485501 | ||||
| ---
 | ||||
|  lib/time.rb | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/time.rb b/lib/time.rb
 | ||||
| index eb46a03..cb6f1e4 100644
 | ||||
| --- a/lib/time.rb
 | ||||
| +++ b/lib/time.rb
 | ||||
| @@ -474,8 +474,8 @@ class Time
 | ||||
|            (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+ | ||||
|            (\d{2,})\s+ | ||||
|            (\d{2})\s* | ||||
| -          :\s*(\d{2})\s*
 | ||||
| -          (?::\s*(\d{2}))?\s+
 | ||||
| +          :\s*(\d{2})
 | ||||
| +          (?:\s*:\s*(\d\d))?\s+
 | ||||
|            ([+-]\d{4}| | ||||
|             UT|GMT|EST|EDT|CST|CDT|MST|MDT|PST|PDT|[A-IK-Z])/ix =~ date | ||||
|          # Since RFC 2822 permit comments, the regexp has no right anchor. | ||||
| -- 
 | ||||
| 2.41.0 | ||||
| 
 | ||||
| @ -1,26 +0,0 @@ | ||||
| From 2becb920e431110c4afc4fa069b051c5940c2096 Mon Sep 17 00:00:00 2001 | ||||
| From: Jeremy Evans <code@jeremyevans.net> | ||||
| Date: Fri, 29 May 2020 14:13:30 -0700 | ||||
| Subject: [PATCH] Convert ip addresses to canonical form in | ||||
|  Resolv::DNS::Requester::UnconnectedUDP#sender | ||||
| 
 | ||||
| Otherwise, if the IP address given is not in canonical form, it | ||||
| won't match, and Resolv will ignore it. | ||||
| 
 | ||||
| Fixes [Bug #16439] | ||||
| ---
 | ||||
|  lib/resolv.rb | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
| 
 | ||||
| diff --git a/lib/resolv.rb b/lib/resolv.rb
 | ||||
| index e7b45e785a85..d78531e174fd 100644
 | ||||
| --- a/lib/resolv.rb
 | ||||
| +++ b/lib/resolv.rb
 | ||||
| @@ -774,6 +774,7 @@ def recv_reply(readable_socks)
 | ||||
|          end | ||||
|   | ||||
|          def sender(msg, data, host, port=Port) | ||||
| +          host = Addrinfo.ip(host).ip_address
 | ||||
|            lazy_initialize | ||||
|            sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] | ||||
|            return nil if !sock | ||||
| @ -1,25 +0,0 @@ | ||||
| From a267a40be7844224c5f000530bd3e8e906f1acea Mon Sep 17 00:00:00 2001 | ||||
| From: Jeremy Evans <code@jeremyevans.net> | ||||
| Date: Wed, 10 Mar 2021 13:48:00 -0800 | ||||
| Subject: [PATCH] Do not use a libdir for glibc, it breaks Linux PPC64 (#70) | ||||
| 
 | ||||
| Fixes [Bug #12666] | ||||
| ---
 | ||||
|  test/fiddle/helper.rb | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
 | ||||
| index f38f903..a6e2019 100644
 | ||||
| --- a/test/fiddle/helper.rb
 | ||||
| +++ b/test/fiddle/helper.rb
 | ||||
| @@ -20,8 +20,8 @@
 | ||||
|      # 64-bit ruby | ||||
|      libdir = '/lib64' if File.directory? '/lib64' | ||||
|    end | ||||
| -  libc_so = File.join(libdir, "libc.so.6")
 | ||||
| -  libm_so = File.join(libdir, "libm.so.6")
 | ||||
| +  libc_so = "libc.so.6"
 | ||||
| +  libm_so = "libm.so.6"
 | ||||
|  when /mingw/, /mswin/ | ||||
|    require "rbconfig" | ||||
|    crtname = RbConfig::CONFIG["RUBY_SO_NAME"][/msvc\w+/] || 'ucrtbase' | ||||
| @ -1,44 +0,0 @@ | ||||
| From 5d08bbb0415c2ecc10037837b81e6a27d40ee7be Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Thu, 29 Jun 2023 22:25:17 +0900 | ||||
| Subject: [PATCH] CVE-2023-36617 for Ruby 3.0 (#7997) | ||||
| 
 | ||||
| * Merge URI-0.10.3 | ||||
| 
 | ||||
| ---
 | ||||
| 
 | ||||
| Backport note, bundler is not distributed the same as RubyGems in Ruby | ||||
| 2.5, therefore we do not use backport for Bundler. | ||||
| ---
 | ||||
|  lib/uri/rfc2396_parser.rb |  4 ++-- | ||||
|  lib/uri/rfc3986_parser.rb |  2 +- | ||||
|  3 files changed, 3 insertions(+), 3 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/uri/rfc2396_parser.rb b/lib/uri/rfc2396_parser.rb
 | ||||
| index b9e7b2b26e..c7c3ecd96d 100644
 | ||||
| --- a/lib/uri/rfc2396_parser.rb
 | ||||
| +++ b/lib/uri/rfc2396_parser.rb
 | ||||
| @@ -502,8 +502,8 @@ def initialize_regexp(pattern)
 | ||||
|        ret = {} | ||||
|   | ||||
|        # for URI::split | ||||
| -      ret[:ABS_URI] = Regexp.new('\A\s*' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
 | ||||
| -      ret[:REL_URI] = Regexp.new('\A\s*' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
 | ||||
| +      ret[:ABS_URI] = Regexp.new('\A\s*+' + pattern[:X_ABS_URI] + '\s*\z', Regexp::EXTENDED)
 | ||||
| +      ret[:REL_URI] = Regexp.new('\A\s*+' + pattern[:X_REL_URI] + '\s*\z', Regexp::EXTENDED)
 | ||||
|   | ||||
|        # for URI::extract | ||||
|        ret[:URI_REF]     = Regexp.new(pattern[:URI_REF]) | ||||
| diff --git a/lib/uri/rfc3986_parser.rb b/lib/uri/rfc3986_parser.rb
 | ||||
| index ad32368cfa..1accd03376 100644
 | ||||
| --- a/lib/uri/rfc3986_parser.rb
 | ||||
| +++ b/lib/uri/rfc3986_parser.rb
 | ||||
| @@ -106,7 +106,7 @@ def default_regexp # :nodoc:
 | ||||
|          QUERY: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, | ||||
|          FRAGMENT: /\A(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*\z/, | ||||
|          OPAQUE: /\A(?:[^\/].*)?\z/, | ||||
| -        PORT: /\A[\x09\x0a\x0c\x0d ]*\d*[\x09\x0a\x0c\x0d ]*\z/,
 | ||||
| +        PORT: /\A[\x09\x0a\x0c\x0d ]*+\d*[\x09\x0a\x0c\x0d ]*\z/,
 | ||||
|        } | ||||
|      end | ||||
|   | ||||
| @ -1,81 +0,0 @@ | ||||
| From 740289bf02c9bea54f75b702f62862c62c62672b Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Thu, 21 Mar 2024 15:55:48 +0900 | ||||
| Subject: [PATCH] Merge StringIO 3.0.1.1 | ||||
| 
 | ||||
| ---
 | ||||
|  ext/stringio/stringio.c        |  2 +- | ||||
|  test/stringio/test_stringio.rb | 27 ++++++++++++++++++++++----- | ||||
|  2 files changed, 23 insertions(+), 6 deletions(-) | ||||
| 
 | ||||
| diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
 | ||||
| index f537054b5d..946ae06da4 100644
 | ||||
| --- a/ext/stringio/stringio.c
 | ||||
| +++ b/ext/stringio/stringio.c
 | ||||
| @@ -833,7 +833,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
 | ||||
|      len = RSTRING_LEN(str); | ||||
|      rest = pos - len; | ||||
|      if (cl > pos) { | ||||
| -	long ex = (rest < 0 ? cl-pos : cl+rest);
 | ||||
| +	long ex = cl - (rest < 0 ? pos : len);
 | ||||
|  	rb_str_modify_expand(str, ex); | ||||
|  	rb_str_set_len(str, len + ex); | ||||
|  	s = RSTRING_PTR(str); | ||||
| diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb
 | ||||
| index f5169f641a..c055b901e3 100644
 | ||||
| --- a/test/stringio/test_stringio.rb
 | ||||
| +++ b/test/stringio/test_stringio.rb
 | ||||
| @@ -693,6 +693,15 @@ def test_ungetc_padding
 | ||||
|      assert_equal("b""\0""a", s.string) | ||||
|    end | ||||
|   | ||||
| +  def test_ungetc_fill
 | ||||
| +    count = 100
 | ||||
| +    s = StringIO.new
 | ||||
| +    s.print 'a' * count
 | ||||
| +    s.ungetc('b' * (count * 5))
 | ||||
| +    assert_equal((count * 5), s.string.size)
 | ||||
| +    assert_match(/\Ab+\z/, s.string)
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_ungetbyte_pos | ||||
|      b = '\\b00010001 \\B00010001 \\b1 \\B1 \\b000100011' | ||||
|      s = StringIO.new( b ) | ||||
| @@ -718,6 +727,15 @@ def test_ungetbyte_padding
 | ||||
|      assert_equal("b""\0""a", s.string) | ||||
|    end | ||||
|   | ||||
| +  def test_ungetbyte_fill
 | ||||
| +    count = 100
 | ||||
| +    s = StringIO.new
 | ||||
| +    s.print 'a' * count
 | ||||
| +    s.ungetbyte('b' * (count * 5))
 | ||||
| +    assert_equal((count * 5), s.string.size)
 | ||||
| +    assert_match(/\Ab+\z/, s.string)
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_frozen | ||||
|      s = StringIO.new | ||||
|      s.freeze | ||||
| @@ -760,18 +778,17 @@ def test_new_block_warning
 | ||||
|    end | ||||
|   | ||||
|    def test_overflow | ||||
| -    skip if RbConfig::SIZEOF["void*"] > RbConfig::SIZEOF["long"]
 | ||||
| +    return if RbConfig::SIZEOF["void*"] > RbConfig::SIZEOF["long"]
 | ||||
|      limit = (1 << (RbConfig::SIZEOF["void*"]*8-1)) - 0x10 | ||||
|      assert_separately(%w[-rstringio], "#{<<-"begin;"}\n#{<<-"end;"}") | ||||
|      begin; | ||||
|        limit = #{limit} | ||||
|        ary = [] | ||||
| -      while true
 | ||||
| +      begin
 | ||||
|          x = "a"*0x100000 | ||||
|          break if [x].pack("p").unpack("i!")[0] < 0 | ||||
|          ary << x | ||||
| -        skip if ary.size > 100
 | ||||
| -      end
 | ||||
| +      end while ary.size <= 100
 | ||||
|        s = StringIO.new(x) | ||||
|        s.gets("xxx", limit) | ||||
|        assert_equal(0x100000, s.pos) | ||||
| @ -1,203 +0,0 @@ | ||||
| From 7957a25edf844c966de45848fa7e9e2513955660 Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Thu, 21 Mar 2024 15:47:40 +0900 | ||||
| Subject: [PATCH 1/2] Merge RDoc-6.3.4.1 | ||||
| 
 | ||||
| ---
 | ||||
|  lib/rdoc/rdoc.rb               |  3 ++- | ||||
|  lib/rdoc/store.rb              | 45 ++++++++++++++++++++-------------- | ||||
|  test/rdoc/test_rdoc_options.rb |  6 ++--- | ||||
|  3 files changed, 31 insertions(+), 23 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
 | ||||
| index a2711fbbd1..c5690fc3b4 100644
 | ||||
| --- a/lib/rdoc/rdoc.rb
 | ||||
| +++ b/lib/rdoc/rdoc.rb
 | ||||
| @@ -162,8 +162,9 @@ def load_options
 | ||||
|      RDoc.load_yaml | ||||
|   | ||||
|      begin | ||||
| -      options = YAML.load_file '.rdoc_options'
 | ||||
| +      options = YAML.safe_load_file '.rdoc_options', permitted_classes: [RDoc::Options, Symbol]
 | ||||
|      rescue Psych::SyntaxError | ||||
| +      raise RDoc::Error, "#{options_file} is not a valid rdoc options file"
 | ||||
|      end | ||||
|   | ||||
|      raise RDoc::Error, "#{options_file} is not a valid rdoc options file" unless | ||||
| diff --git a/lib/rdoc/store.rb b/lib/rdoc/store.rb
 | ||||
| index 999aa76f92..07d03e90f7 100644
 | ||||
| --- a/lib/rdoc/store.rb
 | ||||
| +++ b/lib/rdoc/store.rb
 | ||||
| @@ -539,9 +539,7 @@ def load_all
 | ||||
|    def load_cache | ||||
|      #orig_enc = @encoding | ||||
|   | ||||
| -    open cache_path, 'rb' do |io|
 | ||||
| -      @cache = Marshal.load io.read
 | ||||
| -    end
 | ||||
| +    @cache = marshal_load(cache_path)
 | ||||
|   | ||||
|      load_enc = @cache[:encoding] | ||||
|   | ||||
| @@ -596,9 +594,7 @@ def load_class klass_name
 | ||||
|    def load_class_data klass_name | ||||
|      file = class_file klass_name | ||||
|   | ||||
| -    open file, 'rb' do |io|
 | ||||
| -      Marshal.load io.read
 | ||||
| -    end
 | ||||
| +    marshal_load(file)
 | ||||
|    rescue Errno::ENOENT => e | ||||
|      error = MissingFileError.new(self, file, klass_name) | ||||
|      error.set_backtrace e.backtrace | ||||
| @@ -611,14 +607,10 @@ def load_class_data klass_name
 | ||||
|    def load_method klass_name, method_name | ||||
|      file = method_file klass_name, method_name | ||||
|   | ||||
| -    open file, 'rb' do |io|
 | ||||
| -      obj = Marshal.load io.read
 | ||||
| -      obj.store = self
 | ||||
| -      obj.parent =
 | ||||
| -        find_class_or_module(klass_name) || load_class(klass_name) unless
 | ||||
| -          obj.parent
 | ||||
| -      obj
 | ||||
| -    end
 | ||||
| +    obj = marshal_load(file)
 | ||||
| +    obj.store = self
 | ||||
| +    obj.parent ||= find_class_or_module(klass_name) || load_class(klass_name)
 | ||||
| +    obj
 | ||||
|    rescue Errno::ENOENT => e | ||||
|      error = MissingFileError.new(self, file, klass_name + method_name) | ||||
|      error.set_backtrace e.backtrace | ||||
| @@ -631,11 +623,9 @@ def load_method klass_name, method_name
 | ||||
|    def load_page page_name | ||||
|      file = page_file page_name | ||||
|   | ||||
| -    open file, 'rb' do |io|
 | ||||
| -      obj = Marshal.load io.read
 | ||||
| -      obj.store = self
 | ||||
| -      obj
 | ||||
| -    end
 | ||||
| +    obj = marshal_load(file)
 | ||||
| +    obj.store = self
 | ||||
| +    obj
 | ||||
|    rescue Errno::ENOENT => e | ||||
|      error = MissingFileError.new(self, file, page_name) | ||||
|      error.set_backtrace e.backtrace | ||||
| @@ -965,4 +955,21 @@ def unique_modules
 | ||||
|      @unique_modules | ||||
|    end | ||||
|   | ||||
| +  private
 | ||||
| +  def marshal_load(file)
 | ||||
| +    File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)}
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  MarshalFilter = proc do |obj|
 | ||||
| +    case obj
 | ||||
| +    when true, false, nil, Array, Class, Encoding, Hash, Integer, String, Symbol, RDoc::Text
 | ||||
| +    else
 | ||||
| +      unless obj.class.name.start_with?("RDoc::")
 | ||||
| +        raise TypeError, "not permitted class: #{obj.class.name}"
 | ||||
| +      end
 | ||||
| +    end
 | ||||
| +    obj
 | ||||
| +  end
 | ||||
| +  private_constant :MarshalFilter
 | ||||
| +
 | ||||
|  end | ||||
| diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
 | ||||
| index 400ed9a549..247c7c87ce 100644
 | ||||
| --- a/test/rdoc/test_rdoc_options.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_options.rb
 | ||||
| @@ -145,7 +145,7 @@ def test_init_with_encoding
 | ||||
|   | ||||
|      @options.encoding = Encoding::IBM437 | ||||
|   | ||||
| -    options = YAML.load YAML.dump @options
 | ||||
| +    options = YAML.safe_load(YAML.dump(@options), permitted_classes: [RDoc::Options, Symbol])
 | ||||
|   | ||||
|      assert_equal Encoding::IBM437, options.encoding | ||||
|    end | ||||
| @@ -161,7 +161,7 @@ def test_init_with_trim_paths
 | ||||
|  - /etc | ||||
|      YAML | ||||
|   | ||||
| -    options = YAML.load yaml
 | ||||
| +    options = YAML.safe_load(yaml, permitted_classes: [RDoc::Options, Symbol])
 | ||||
|   | ||||
|      assert_empty options.rdoc_include | ||||
|      assert_empty options.static_path | ||||
| @@ -729,7 +729,7 @@ def test_write_options
 | ||||
|   | ||||
|        assert File.exist? '.rdoc_options' | ||||
|   | ||||
| -      assert_equal @options, YAML.load(File.read('.rdoc_options'))
 | ||||
| +      assert_equal @options, YAML.safe_load(File.read('.rdoc_options'), permitted_classes: [RDoc::Options, Symbol])
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| 
 | ||||
| From 153a4d16058783c923d0df5b1cbe2610ef96e3a8 Mon Sep 17 00:00:00 2001 | ||||
| From: Jarek Prokop <jprokop@redhat.com> | ||||
| Date: Tue, 28 May 2024 16:56:26 +0200 | ||||
| Subject: [PATCH 2/2] Port the rebase to work with Ruby 2.5.9. | ||||
| 
 | ||||
| Ruby 2.5's Psych does not have safe_load_file method. | ||||
| However, from Ruby 3.3's sources, the method is just File.read | ||||
| simple wrapper with a safe_load call. Therefore it was copied over to | ||||
| the lib/rdoc/rdoc.rb file. | ||||
| ---
 | ||||
|  lib/rdoc/rdoc.rb               | 9 ++++++- | ||||
|  test/rdoc/test_rdoc_options.rb | 6 +++--- | ||||
|  2 files changed, 11 insertions(+), 4 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb
 | ||||
| index c5690fc3b4..435cd2eaf0 100644
 | ||||
| --- a/lib/rdoc/rdoc.rb
 | ||||
| +++ b/lib/rdoc/rdoc.rb
 | ||||
| @@ -162,7 +162,12 @@ def load_options
 | ||||
|      RDoc.load_yaml | ||||
|   | ||||
|      begin | ||||
| -      options = YAML.safe_load_file '.rdoc_options', permitted_classes: [RDoc::Options, Symbol]
 | ||||
| +      # Opening file inspired from Ruby 3.3.0 sources,
 | ||||
| +      # file 'ext/psych/lib/psych.rb', line 658.
 | ||||
| +      # https://github.com/ruby/ruby/blob/v3_3_0/ext/psych/lib/psych.rb#L658
 | ||||
| +      options = File.open('.rdoc_options', 'r:bom|utf-8') do |file|
 | ||||
| +        YAML.safe_load file, [RDoc::Options, Symbol], [], false, '.rdoc_options'
 | ||||
| +      end
 | ||||
|      rescue Psych::SyntaxError | ||||
|        raise RDoc::Error, "#{options_file} is not a valid rdoc options file" | ||||
|      end | ||||
| diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
 | ||||
| index 247c7c87ce..60fe035dce 100644
 | ||||
| --- a/test/rdoc/test_rdoc_options.rb
 | ||||
| +++ b/test/rdoc/test_rdoc_options.rb
 | ||||
| @@ -145,7 +145,7 @@ def test_init_with_encoding
 | ||||
|   | ||||
|      @options.encoding = Encoding::IBM437 | ||||
|   | ||||
| -    options = YAML.safe_load(YAML.dump(@options), permitted_classes: [RDoc::Options, Symbol])
 | ||||
| +    options = YAML.safe_load(YAML.dump(@options), [RDoc::Options, Symbol])
 | ||||
|   | ||||
|      assert_equal Encoding::IBM437, options.encoding | ||||
|    end | ||||
| @@ -161,7 +161,7 @@ def test_init_with_trim_paths
 | ||||
|  - /etc | ||||
|      YAML | ||||
|   | ||||
| -    options = YAML.safe_load(yaml, permitted_classes: [RDoc::Options, Symbol])
 | ||||
| +    options = YAML.safe_load(yaml, [RDoc::Options, Symbol])
 | ||||
|   | ||||
|      assert_empty options.rdoc_include | ||||
|      assert_empty options.static_path | ||||
| @@ -729,7 +729,7 @@ def test_write_options
 | ||||
|   | ||||
|        assert File.exist? '.rdoc_options' | ||||
|   | ||||
| -      assert_equal @options, YAML.safe_load(File.read('.rdoc_options'), permitted_classes: [RDoc::Options, Symbol])
 | ||||
| +      assert_equal @options, YAML.safe_load(File.read('.rdoc_options'), [RDoc::Options, Symbol])
 | ||||
|      end | ||||
|    end | ||||
|   | ||||
| @ -1,48 +0,0 @@ | ||||
| From 9eda3000e3efd5bdd4ed60d07e2f43633e39d361 Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Tue, 23 Apr 2024 19:22:22 +0900 | ||||
| Subject: [PATCH] merge revision(s) 33e5b47c16f1fd3382186e6ffe73cfc6e00946f7: | ||||
| 
 | ||||
| 	Fix handling of reg->dmin in Regex matching | ||||
| 
 | ||||
| 	--- | ||||
| 	 regexec.c | 10 ++++++++++ | ||||
| 	 1 file changed, 10 insertions(+) | ||||
| ---
 | ||||
|  regexec.c | 10 ++++++++++ | ||||
|  1 file changed, 10 insertions(+) | ||||
| 
 | ||||
| diff --git a/regexec.c b/regexec.c
 | ||||
| index 4582c35c3f..36ac1d4bc5 100644
 | ||||
| --- a/regexec.c
 | ||||
| +++ b/regexec.c
 | ||||
| @@ -3900,12 +3900,17 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
 | ||||
|  		     UChar* range, UChar** low, UChar** high, UChar** low_prev) | ||||
|  { | ||||
|    UChar *p, *pprev = (UChar* )NULL; | ||||
| +  size_t input_len = end - str;
 | ||||
|   | ||||
|  #ifdef ONIG_DEBUG_SEARCH | ||||
|    fprintf(stderr, "forward_search_range: str: %"PRIuPTR" (%p), end: %"PRIuPTR" (%p), s: %"PRIuPTR" (%p), range: %"PRIuPTR" (%p)\n", | ||||
|  	  (uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )s, s, (uintptr_t )range, range); | ||||
|  #endif | ||||
|   | ||||
| +  if (reg->dmin > input_len) {
 | ||||
| +    return 0;
 | ||||
| +  }
 | ||||
| +
 | ||||
|    p = s; | ||||
|    if (reg->dmin > 0) { | ||||
|      if (ONIGENC_IS_SINGLEBYTE(reg->enc)) { | ||||
| @@ -4042,6 +4047,11 @@ backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
 | ||||
|  		      UChar** low, UChar** high) | ||||
|  { | ||||
|    UChar *p; | ||||
| +  size_t input_len = end - str;
 | ||||
| +
 | ||||
| +  if (reg->dmin > input_len) {
 | ||||
| +    return 0;
 | ||||
| +  }
 | ||||
|   | ||||
|    range += reg->dmin; | ||||
|    p = s; | ||||
| @ -1,70 +0,0 @@ | ||||
| From a1124dc162810f86cb0bff58cde24064cfc561bc Mon Sep 17 00:00:00 2001 | ||||
| From: nagachika <nagachika@ruby-lang.org> | ||||
| Date: Fri, 9 Dec 2022 21:11:47 +0900 | ||||
| Subject: [PATCH] merge revision(s) 58cc3c9f387dcf8f820b43e043b540fa06248da3: | ||||
|  [Backport #19187] | ||||
| 
 | ||||
| 	[Bug #19187] Fix for tzdata-2022g | ||||
| 
 | ||||
| 	--- | ||||
| 	 test/ruby/test_time_tz.rb | 21 +++++++++++++++------ | ||||
| 	 1 file changed, 15 insertions(+), 6 deletions(-) | ||||
| ---
 | ||||
|  test/ruby/test_time_tz.rb | 21 +++++++++++++++------ | ||||
|  1 files changed, 15 insertions(+), 6 deletions(-) | ||||
| 
 | ||||
| diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
 | ||||
| index b6785f336028d..939f218ed4d10 100644
 | ||||
| --- a/test/ruby/test_time_tz.rb
 | ||||
| +++ b/test/ruby/test_time_tz.rb
 | ||||
| @@ -6,9 +6,9 @@ class TestTimeTZ < Test::Unit::TestCase
 | ||||
|    has_lisbon_tz = true | ||||
|    force_tz_test = ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes" | ||||
|    case RUBY_PLATFORM | ||||
| -  when /linux/
 | ||||
| +  when /darwin|linux/
 | ||||
|      force_tz_test = true | ||||
| -  when /darwin|freebsd/
 | ||||
| +  when /freebsd|openbsd/
 | ||||
|      has_lisbon_tz = false | ||||
|      force_tz_test = true | ||||
|    end | ||||
| @@ -94,6 +94,9 @@ def group_by(e, &block)
 | ||||
|    CORRECT_KIRITIMATI_SKIP_1994 = with_tz("Pacific/Kiritimati") { | ||||
|      Time.local(1994, 12, 31, 0, 0, 0).year == 1995 | ||||
|    } | ||||
| +  CORRECT_SINGAPORE_1982 = with_tz("Asia/Singapore") {
 | ||||
| +    "2022g" if Time.local(1981, 12, 31, 23, 59, 59).utc_offset == 8*3600
 | ||||
| +  }
 | ||||
|   | ||||
|    def time_to_s(t) | ||||
|      t.to_s | ||||
| @@ -139,9 +142,12 @@ def test_america_managua
 | ||||
|   | ||||
|    def test_asia_singapore | ||||
|      with_tz(tz="Asia/Singapore") { | ||||
| -      assert_time_constructor(tz, "1981-12-31 23:59:59 +0730", :local, [1981,12,31,23,59,59])
 | ||||
| -      assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,0,0])
 | ||||
| -      assert_time_constructor(tz, "1982-01-01 00:59:59 +0800", :local, [1982,1,1,0,29,59])
 | ||||
| +      assert_time_constructor(tz, "1981-12-31 23:29:59 +0730", :local, [1981,12,31,23,29,59])
 | ||||
| +      if CORRECT_SINGAPORE_1982
 | ||||
| +        assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1981,12,31,23,30,00])
 | ||||
| +        assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1982,1,1,0,0,0])
 | ||||
| +        assert_time_constructor(tz, "1982-01-01 00:29:59 +0800", :local, [1982,1,1,0,29,59])
 | ||||
| +      end
 | ||||
|        assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,30,0]) | ||||
|      } | ||||
|    end | ||||
| @@ -364,8 +370,11 @@ def self.gen_zdump_test(data)
 | ||||
|  America/Managua  Wed Jan  1 04:59:59 1997 UTC = Tue Dec 31 23:59:59 1996 EST isdst=0 gmtoff=-18000 | ||||
|  America/Managua  Wed Jan  1 05:00:00 1997 UTC = Tue Dec 31 23:00:00 1996 CST isdst=0 gmtoff=-21600 | ||||
|  Asia/Singapore  Sun Aug  8 16:30:00 1965 UTC = Mon Aug  9 00:00:00 1965 SGT isdst=0 gmtoff=27000 | ||||
| -Asia/Singapore  Thu Dec 31 16:29:59 1981 UTC = Thu Dec 31 23:59:59 1981 SGT isdst=0 gmtoff=27000
 | ||||
| +Asia/Singapore  Thu Dec 31 15:59:59 1981 UTC = Thu Dec 31 23:29:59 1981 SGT isdst=0 gmtoff=27000
 | ||||
|  Asia/Singapore  Thu Dec 31 16:30:00 1981 UTC = Fri Jan  1 00:30:00 1982 SGT isdst=0 gmtoff=28800 | ||||
| +End
 | ||||
| +  gen_zdump_test <<'End' if CORRECT_SINGAPORE_1982
 | ||||
| +Asia/Singapore  Thu Dec 31 16:00:00 1981 UTC = Fri Jan  1 00:00:00 1982 SGT isdst=0 gmtoff=28800
 | ||||
|  End | ||||
|    gen_zdump_test CORRECT_TOKYO_DST_1951 ? <<'End' + (CORRECT_TOKYO_DST_1951 < "2018f" ? <<'2018e' : <<'2018f') : <<'End' | ||||
|  Asia/Tokyo  Sat May  5 14:59:59 1951 UTC = Sat May  5 23:59:59 1951 JST isdst=0 gmtoff=32400 | ||||
| @ -1,27 +0,0 @@ | ||||
| From dae843f6b7502f921a7e66f39e3714a39d860181 Mon Sep 17 00:00:00 2001 | ||||
| From: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| Date: Wed, 19 Oct 2022 19:40:00 +0900 | ||||
| Subject: [PATCH] Bypass git submodule add/update with git config | ||||
|  protocol.file.allow=always option. | ||||
| 
 | ||||
| Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> | ||||
| ---
 | ||||
|  test/rubygems/test_gem_source_git.rb | 5 +++++ | ||||
|  1 file changed, 5 insertions(+) | ||||
| 
 | ||||
| diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb
 | ||||
| index 5702da05974b6..c3b324771fa4d 100644
 | ||||
| --- a/test/rubygems/test_gem_source_git.rb
 | ||||
| +++ b/test/rubygems/test_gem_source_git.rb
 | ||||
| @@ -64,6 +64,11 @@ def test_checkout_local_cached
 | ||||
|    end | ||||
|   | ||||
|    def test_checkout_submodules | ||||
| +    # We need to allow to checkout submodules with file:// protocol
 | ||||
| +    # CVE-2022-39253
 | ||||
| +    # https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
 | ||||
| +    system(@git, *%W"config --global protocol.file.allow always")
 | ||||
| +
 | ||||
|      source = Gem::Source::Git.new @name, @repository, 'master', true | ||||
|   | ||||
|      git_gem 'b' | ||||
| @ -1,236 +0,0 @@ | ||||
| From d3933fc753187a055a4904af82f5f3794c88c416 Mon Sep 17 00:00:00 2001 | ||||
| From: Sorah Fukumori <her@sorah.jp> | ||||
| Date: Mon, 1 Jan 2024 20:45:54 +0900 | ||||
| Subject: [PATCH] [ruby/net-http] Renew test certificates | ||||
| 
 | ||||
| The private key is replaced with a public known test key published at | ||||
| [RFC 9500]. | ||||
| 
 | ||||
| Also lifetime has been extended to 10 years from 4 years. | ||||
| 
 | ||||
| [RFC 9500]: https://www.rfc-editor.org/rfc/rfc9500.html | ||||
| 
 | ||||
| https://github.com/ruby/net-http/commit/4ab6c4a500 | ||||
| ---
 | ||||
|  test/net/fixtures/cacert.pem | 44 ++++++++-------- | ||||
|  test/net/fixtures/server.crt | 99 +++++++----------------------------- | ||||
|  test/net/fixtures/server.key | 55 ++++++++++---------- | ||||
|  4 files changed, 68 insertions(+), 130 deletions(-) | ||||
| 
 | ||||
| diff --git a/test/net/fixtures/cacert.pem b/test/net/fixtures/cacert.pem
 | ||||
| index f623bd62ed375..24c83f1c65225 100644
 | ||||
| --- a/test/net/fixtures/cacert.pem
 | ||||
| +++ b/test/net/fixtures/cacert.pem
 | ||||
| @@ -1,24 +1,24 @@
 | ||||
|  -----BEGIN CERTIFICATE----- | ||||
| -MIID7TCCAtWgAwIBAgIJAIltvxrFAuSnMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
 | ||||
| -VQQGEwJKUDEQMA4GA1UECAwHU2hpbWFuZTEUMBIGA1UEBwwLTWF0ei1lIGNpdHkx
 | ||||
| -FzAVBgNVBAoMDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDDAxSdWJ5IFRlc3QgQ0Ex
 | ||||
| -JTAjBgkqhkiG9w0BCQEWFnNlY3VyaXR5QHJ1YnktbGFuZy5vcmcwHhcNMTkwMTAy
 | ||||
| -MDI1ODI4WhcNMjQwMTAxMDI1ODI4WjCBjDELMAkGA1UEBhMCSlAxEDAOBgNVBAgM
 | ||||
| -B1NoaW1hbmUxFDASBgNVBAcMC01hdHotZSBjaXR5MRcwFQYDVQQKDA5SdWJ5IENv
 | ||||
| -cmUgVGVhbTEVMBMGA1UEAwwMUnVieSBUZXN0IENBMSUwIwYJKoZIhvcNAQkBFhZz
 | ||||
| -ZWN1cml0eUBydWJ5LWxhbmcub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
 | ||||
| -CgKCAQEAznlbjRVhz1NlutHVrhcGnK8W0qug2ujKXv1njSC4U6nJF6py7I9EeehV
 | ||||
| -SaKePyv+I9z3K1LnfUHOtUbdwdKC77yN66A6q2aqzu5q09/NSykcZGOIF0GuItYI
 | ||||
| -3nvW3IqBddff2ffsyR+9pBjfb5AIPP08WowF9q4s1eGULwZc4w2B8PFhtxYANd7d
 | ||||
| -BvGLXFlcufv9tDtzyRi4t7eqxCRJkZQIZNZ6DHHIJrNxejOILfHLarI12yk8VK6L
 | ||||
| -2LG4WgGqyeePiRyd1o1MbuiAFYqAwpXNUbRKg5NaZGwBHZk8UZ+uFKt1QMBURO5R
 | ||||
| -WFy1c349jbWszTqFyL4Lnbg9HhAowQIDAQABo1AwTjAdBgNVHQ4EFgQU9tEiKdU9
 | ||||
| -I9derQyc5nWPnc34nVMwHwYDVR0jBBgwFoAU9tEiKdU9I9derQyc5nWPnc34nVMw
 | ||||
| -DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAxj7F/u3C3fgq24N7hGRA
 | ||||
| -of7ClFQxGmo/IGT0AISzW3HiVYiFaikKhbO1NwD9aBpD8Zwe62sCqMh8jGV/b0+q
 | ||||
| -aOORnWYNy2R6r9FkASAglmdF6xn3bhgGD5ls4pCvcG9FynGnGc24g6MrjFNrBYUS
 | ||||
| -2iIZsg36i0IJswo/Dy6HLphCms2BMCD3DeWtfjePUiTmQHJo6HsQIKP/u4N4Fvee
 | ||||
| -uMBInei2M4VU74fLXbmKl1F9AEX7JDP3BKSZG19Ch5pnUo4uXM1uNTGsi07P4Y0s
 | ||||
| -K44+SKBC0bYEFbDK0eQWMrX3kIhkPxyIWhxdq9/NqPYjShuSEAhA6CSpmRg0pqc+
 | ||||
| -mA==
 | ||||
| +MIID+zCCAuOgAwIBAgIUGMvHl3EhtKPKcgc3NQSAYfFuC+8wDQYJKoZIhvcNAQEL
 | ||||
| +BQAwgYwxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdTaGltYW5lMRQwEgYDVQQHDAtN
 | ||||
| +YXR6LWUgY2l0eTEXMBUGA1UECgwOUnVieSBDb3JlIFRlYW0xFTATBgNVBAMMDFJ1
 | ||||
| +YnkgVGVzdCBDQTElMCMGCSqGSIb3DQEJARYWc2VjdXJpdHlAcnVieS1sYW5nLm9y
 | ||||
| +ZzAeFw0yNDAxMDExMTQ3MjNaFw0zMzEyMjkxMTQ3MjNaMIGMMQswCQYDVQQGEwJK
 | ||||
| +UDEQMA4GA1UECAwHU2hpbWFuZTEUMBIGA1UEBwwLTWF0ei1lIGNpdHkxFzAVBgNV
 | ||||
| +BAoMDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDDAxSdWJ5IFRlc3QgQ0ExJTAjBgkq
 | ||||
| +hkiG9w0BCQEWFnNlY3VyaXR5QHJ1YnktbGFuZy5vcmcwggEiMA0GCSqGSIb3DQEB
 | ||||
| +AQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI
 | ||||
| ++1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0f
 | ||||
| +qXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0
 | ||||
| +yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIe
 | ||||
| +NWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1
 | ||||
| +JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMBAAGjUzBRMB0GA1Ud
 | ||||
| +DgQWBBSJGVleDvFp9cu9R+E0/OKYzGkwkTAfBgNVHSMEGDAWgBSJGVleDvFp9cu9
 | ||||
| +R+E0/OKYzGkwkTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBl
 | ||||
| +8GLB8skAWlkSw/FwbUmEV3zyqu+p7PNP5YIYoZs0D74e7yVulGQ6PKMZH5hrZmHo
 | ||||
| +orFSQU+VUUirG8nDGj7Rzce8WeWBxsaDGC8CE2dq6nC6LuUwtbdMnBrH0LRWAz48
 | ||||
| +jGFF3jHtVz8VsGfoZTZCjukWqNXvU6hETT9GsfU+PZqbqcTVRPH52+XgYayKdIbD
 | ||||
| +r97RM4X3+aXBHcUW0b76eyyi65RR/Xtvn8ioZt2AdX7T2tZzJyXJN3Hupp77s6Ui
 | ||||
| +AZR35SToHCZeTZD12YBvLBdaTPLZN7O/Q/aAO9ZiJaZ7SbFOjz813B2hxXab4Fob
 | ||||
| +2uJX6eMWTVxYK5D4M9lm
 | ||||
|  -----END CERTIFICATE----- | ||||
| diff --git a/test/net/fixtures/server.crt b/test/net/fixtures/server.crt
 | ||||
| index 5ca78a6d146a0..5d2923795dabc 100644
 | ||||
| --- a/test/net/fixtures/server.crt
 | ||||
| +++ b/test/net/fixtures/server.crt
 | ||||
| @@ -1,82 +1,21 @@
 | ||||
| -Certificate:
 | ||||
| -    Data:
 | ||||
| -        Version: 3 (0x2)
 | ||||
| -        Serial Number: 2 (0x2)
 | ||||
| -    Signature Algorithm: sha256WithRSAEncryption
 | ||||
| -        Issuer: C=JP, ST=Shimane, L=Matz-e city, O=Ruby Core Team, CN=Ruby Test CA/emailAddress=security@ruby-lang.org
 | ||||
| -        Validity
 | ||||
| -            Not Before: Jan  2 03:27:13 2019 GMT
 | ||||
| -            Not After : Jan  1 03:27:13 2024 GMT
 | ||||
| -        Subject: C=JP, ST=Shimane, O=Ruby Core Team, OU=Ruby Test, CN=localhost
 | ||||
| -        Subject Public Key Info:
 | ||||
| -            Public Key Algorithm: rsaEncryption
 | ||||
| -                Public-Key: (2048 bit)
 | ||||
| -                Modulus:
 | ||||
| -                    00:e8:da:9c:01:2e:2b:10:ec:49:cd:5e:07:13:07:
 | ||||
| -                    9c:70:9e:c6:74:bc:13:c2:e1:6f:c6:82:fd:e3:48:
 | ||||
| -                    e0:2c:a5:68:c7:9e:42:de:60:54:65:e6:6a:14:57:
 | ||||
| -                    7a:30:d0:cc:b5:b6:d9:c3:d2:df:c9:25:97:54:67:
 | ||||
| -                    cf:f6:be:5e:cb:8b:ee:03:c5:e1:e2:f9:e7:f7:d1:
 | ||||
| -                    0c:47:f0:b8:da:33:5a:ad:41:ad:e7:b5:a2:7b:b7:
 | ||||
| -                    bf:30:da:60:f8:e3:54:a2:bc:3a:fd:1b:74:d9:dc:
 | ||||
| -                    74:42:e9:29:be:df:ac:b4:4f:eb:32:f4:06:f1:e1:
 | ||||
| -                    8c:4b:a8:8b:fb:29:e7:b1:bf:1d:01:ee:73:0f:f9:
 | ||||
| -                    40:dc:d5:15:79:d9:c6:73:d0:c0:dd:cb:e4:da:19:
 | ||||
| -                    47:80:c6:14:04:72:fd:9a:7c:8f:11:82:76:49:04:
 | ||||
| -                    79:cc:f2:5c:31:22:95:13:3e:5d:40:a6:4d:e0:a3:
 | ||||
| -                    02:26:7d:52:3b:bb:ed:65:a1:0f:ed:6b:b0:3c:d4:
 | ||||
| -                    de:61:15:5e:d3:dd:68:09:9f:4a:57:a5:c2:a9:6d:
 | ||||
| -                    86:92:c5:f4:a4:d4:b7:13:3b:52:63:24:05:e2:cc:
 | ||||
| -                    e3:8a:3c:d4:35:34:2b:10:bb:58:72:e7:e1:8d:1d:
 | ||||
| -                    74:8c:61:16:20:3d:d0:1c:4e:8f:6e:fd:fe:64:10:
 | ||||
| -                    4f:41
 | ||||
| -                Exponent: 65537 (0x10001)
 | ||||
| -        X509v3 extensions:
 | ||||
| -            X509v3 Basic Constraints: 
 | ||||
| -                CA:FALSE
 | ||||
| -            Netscape Comment: 
 | ||||
| -                OpenSSL Generated Certificate
 | ||||
| -            X509v3 Subject Key Identifier: 
 | ||||
| -                ED:28:C2:7E:AB:4B:C8:E8:FE:55:6D:66:95:31:1C:2D:60:F9:02:36
 | ||||
| -            X509v3 Authority Key Identifier: 
 | ||||
| -                keyid:F6:D1:22:29:D5:3D:23:D7:5E:AD:0C:9C:E6:75:8F:9D:CD:F8:9D:53
 | ||||
| -
 | ||||
| -    Signature Algorithm: sha256WithRSAEncryption
 | ||||
| -         1d:b8:c5:8b:72:41:20:65:ad:27:6f:15:63:06:26:12:8d:9c:
 | ||||
| -         ad:ca:f4:db:97:b4:90:cb:ff:35:94:bb:2a:a7:a1:ab:1e:35:
 | ||||
| -         2d:a5:3f:c9:24:b0:1a:58:89:75:3e:81:0a:2c:4f:98:f9:51:
 | ||||
| -         fb:c0:a3:09:d0:0a:9b:e7:a2:b7:c3:60:40:c8:f4:6d:b2:6a:
 | ||||
| -         56:12:17:4c:00:24:31:df:9c:60:ae:b1:68:54:a9:e6:b5:4a:
 | ||||
| -         04:e6:92:05:86:d9:5a:dc:96:30:a5:58:de:14:99:0f:e5:15:
 | ||||
| -         89:3e:9b:eb:80:e3:bd:83:c3:ea:33:35:4b:3e:2f:d3:0d:64:
 | ||||
| -         93:67:7f:8d:f5:3f:0c:27:bc:37:5a:cc:d6:47:16:af:5a:62:
 | ||||
| -         d2:da:51:f8:74:06:6b:24:ad:28:68:08:98:37:7d:ed:0e:ab:
 | ||||
| -         1e:82:61:05:d0:ba:75:a0:ab:21:b0:9a:fd:2b:54:86:1d:0d:
 | ||||
| -         1f:c2:d4:77:1f:72:26:5e:ad:8a:9f:09:36:6d:44:be:74:c2:
 | ||||
| -         5a:3e:ff:5c:9d:75:d6:38:7b:c5:39:f9:44:6e:a1:d1:8e:ff:
 | ||||
| -         63:db:c4:bb:c6:91:92:ca:5c:60:9b:1d:eb:0a:de:08:ee:bf:
 | ||||
| -         da:76:03:65:62:29:8b:f8:7f:c7:86:73:1e:f6:1f:2d:89:69:
 | ||||
| -         fd:be:bd:6e
 | ||||
|  -----BEGIN CERTIFICATE----- | ||||
| -MIID4zCCAsugAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCSlAx
 | ||||
| -EDAOBgNVBAgMB1NoaW1hbmUxFDASBgNVBAcMC01hdHotZSBjaXR5MRcwFQYDVQQK
 | ||||
| -DA5SdWJ5IENvcmUgVGVhbTEVMBMGA1UEAwwMUnVieSBUZXN0IENBMSUwIwYJKoZI
 | ||||
| -hvcNAQkBFhZzZWN1cml0eUBydWJ5LWxhbmcub3JnMB4XDTE5MDEwMjAzMjcxM1oX
 | ||||
| -DTI0MDEwMTAzMjcxM1owYDELMAkGA1UEBhMCSlAxEDAOBgNVBAgMB1NoaW1hbmUx
 | ||||
| -FzAVBgNVBAoMDlJ1YnkgQ29yZSBUZWFtMRIwEAYDVQQLDAlSdWJ5IFRlc3QxEjAQ
 | ||||
| -BgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
 | ||||
| -AOjanAEuKxDsSc1eBxMHnHCexnS8E8Lhb8aC/eNI4CylaMeeQt5gVGXmahRXejDQ
 | ||||
| -zLW22cPS38kll1Rnz/a+XsuL7gPF4eL55/fRDEfwuNozWq1Bree1onu3vzDaYPjj
 | ||||
| -VKK8Ov0bdNncdELpKb7frLRP6zL0BvHhjEuoi/sp57G/HQHucw/5QNzVFXnZxnPQ
 | ||||
| -wN3L5NoZR4DGFARy/Zp8jxGCdkkEeczyXDEilRM+XUCmTeCjAiZ9Uju77WWhD+1r
 | ||||
| -sDzU3mEVXtPdaAmfSlelwqlthpLF9KTUtxM7UmMkBeLM44o81DU0KxC7WHLn4Y0d
 | ||||
| -dIxhFiA90BxOj279/mQQT0ECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
 | ||||
| -AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFO0o
 | ||||
| -wn6rS8jo/lVtZpUxHC1g+QI2MB8GA1UdIwQYMBaAFPbRIinVPSPXXq0MnOZ1j53N
 | ||||
| -+J1TMA0GCSqGSIb3DQEBCwUAA4IBAQAduMWLckEgZa0nbxVjBiYSjZytyvTbl7SQ
 | ||||
| -y/81lLsqp6GrHjUtpT/JJLAaWIl1PoEKLE+Y+VH7wKMJ0Aqb56K3w2BAyPRtsmpW
 | ||||
| -EhdMACQx35xgrrFoVKnmtUoE5pIFhtla3JYwpVjeFJkP5RWJPpvrgOO9g8PqMzVL
 | ||||
| -Pi/TDWSTZ3+N9T8MJ7w3WszWRxavWmLS2lH4dAZrJK0oaAiYN33tDqsegmEF0Lp1
 | ||||
| -oKshsJr9K1SGHQ0fwtR3H3ImXq2Knwk2bUS+dMJaPv9cnXXWOHvFOflEbqHRjv9j
 | ||||
| -28S7xpGSylxgmx3rCt4I7r/adgNlYimL+H/HhnMe9h8tiWn9vr1u
 | ||||
| +MIIDYTCCAkkCAQAwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAkpQMRAwDgYD
 | ||||
| +VQQIDAdTaGltYW5lMRQwEgYDVQQHDAtNYXR6LWUgY2l0eTEXMBUGA1UECgwOUnVi
 | ||||
| +eSBDb3JlIFRlYW0xFTATBgNVBAMMDFJ1YnkgVGVzdCBDQTElMCMGCSqGSIb3DQEJ
 | ||||
| +ARYWc2VjdXJpdHlAcnVieS1sYW5nLm9yZzAeFw0yNDAxMDExMTQ3MjNaFw0zMzEy
 | ||||
| +MjkxMTQ3MjNaMGAxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdTaGltYW5lMRcwFQYD
 | ||||
| +VQQKDA5SdWJ5IENvcmUgVGVhbTESMBAGA1UECwwJUnVieSBUZXN0MRIwEAYDVQQD
 | ||||
| +DAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZ
 | ||||
| +Q6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJ
 | ||||
| +tWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvA
 | ||||
| +aIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51a
 | ||||
| +a5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj
 | ||||
| +702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G
 | ||||
| +9zKyqGtGAWXAj1MTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACtGNdj5TEtnJBYp
 | ||||
| +M+LhBeU3oNteldfycEm993gJp6ghWZFg23oX8fVmyEeJr/3Ca9bAgDqg0t9a0npN
 | ||||
| +oWKEY6wVKqcHgu3gSvThF5c9KhGbeDDmlTSVVNQmXWX0K2d4lS2cwZHH8mCm2mrY
 | ||||
| +PDqlEkSc7k4qSiqigdS8i80Yk+lDXWsm8CjsiC93qaRM7DnS0WPQR0c16S95oM6G
 | ||||
| +VklFKUSDAuFjw9aVWA/nahOucjn0w5fVW6lyIlkBslC1ChlaDgJmvhz+Ol3iMsE0
 | ||||
| +kAmFNu2KKPVrpMWaBID49QwQTDyhetNLaVVFM88iUdA9JDoVMEuP1mm39JqyzHTu
 | ||||
| +uBrdP4Q=
 | ||||
|  -----END CERTIFICATE----- | ||||
| diff --git a/test/net/fixtures/server.key b/test/net/fixtures/server.key
 | ||||
| index 7f2380e71e637..6a83d5bcf4a52 100644
 | ||||
| --- a/test/net/fixtures/server.key
 | ||||
| +++ b/test/net/fixtures/server.key
 | ||||
| @@ -1,28 +1,27 @@
 | ||||
| ------BEGIN PRIVATE KEY-----
 | ||||
| -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDo2pwBLisQ7EnN
 | ||||
| -XgcTB5xwnsZ0vBPC4W/Ggv3jSOAspWjHnkLeYFRl5moUV3ow0My1ttnD0t/JJZdU
 | ||||
| -Z8/2vl7Li+4DxeHi+ef30QxH8LjaM1qtQa3ntaJ7t78w2mD441SivDr9G3TZ3HRC
 | ||||
| -6Sm+36y0T+sy9Abx4YxLqIv7Keexvx0B7nMP+UDc1RV52cZz0MDdy+TaGUeAxhQE
 | ||||
| -cv2afI8RgnZJBHnM8lwxIpUTPl1Apk3gowImfVI7u+1loQ/ta7A81N5hFV7T3WgJ
 | ||||
| -n0pXpcKpbYaSxfSk1LcTO1JjJAXizOOKPNQ1NCsQu1hy5+GNHXSMYRYgPdAcTo9u
 | ||||
| -/f5kEE9BAgMBAAECggEBAOHkwhc7DLh8IhTDNSW26oMu5OP2WU1jmiYAigDmf+OQ
 | ||||
| -DBgrZj+JQBci8qINQxL8XLukSZn5hvQCLc7Kbyu1/wyEEUFDxSGGwwzclodr9kho
 | ||||
| -LX2LDASPZrOSzD2+fPi2wTKmXKuS6Uc44OjQfZkYMNkz9r4Vkm8xGgOD3VipjIYX
 | ||||
| -QXlhhdqkXZcNABsihCV52GKkDFSVm8jv95YJc5xhoYCy/3a4/qPdF0aT2R7oYUej
 | ||||
| -hKrxVDskyooe8Zg/JTydZNV5GQEDmW01/K3r6XGT26oPi1AqMU1gtv/jkW56CRQQ
 | ||||
| -1got8smnqM+AV7Slf9R6DauIPdQJ2S8wsr/o8ISBsOECgYEA9YrqEP2gAYSGFXRt
 | ||||
| -liw0WI2Ant8BqXS6yvq1jLo/qWhLw/ph4Di73OQ2mpycVTpgfGr2wFPQR1XJ+0Fd
 | ||||
| -U+Ir/C3Q7FK4VIGHK7B0zNvZr5tEjlFfeRezo2JMVw5YWeSagIFcSwK+KqCTH9qc
 | ||||
| -pw/Eb8nB/4XNcpTZu7Fg0Wc+ooUCgYEA8sVaicn1Wxkpb45a4qfrA6wOr5xdJ4cC
 | ||||
| -A5qs7vjX2OdPIQOmoQhdI7bCWFXZzF33wA4YCws6j5wRaySLIJqdms8Gl9QnODy1
 | ||||
| -ZlA5gwKToBC/jqPmWAXSKb8EH7cHilaxU9OKnQ7CfwlGLHqjMtjrhR7KHlt3CVRs
 | ||||
| -oRmvsjZVXI0CgYAmPedslAO6mMhFSSfULrhMXmV82OCqYrrA6EEkVNGbcdnzAOkD
 | ||||
| -gfKIWabDd8bFY10po4Mguy0CHzNhBXIioWQWV5BlbhC1YKMLw+S9DzSdLAKGY9gJ
 | ||||
| -xQ4+UQ3wtRQ/k+IYR413RUsW2oFvgZ3KSyNeAb9MK6uuv84VdG/OzVSs/QKBgQDn
 | ||||
| -kap//l2EbObiWyaERunckdVcW0lcN+KK75J/TGwPoOwQsLvTpPe65kxRGGrtDsEQ
 | ||||
| -uCDk/+v3KkZPLgdrrTAih9FhJ+PVN8tMcb+6IM4SA4fFFr/UPJEwct0LJ3oQ0grJ
 | ||||
| -y+HPWFHb/Uurh7t99/4H98uR02sjQh1wOeEmm78mzQKBgQDm+LzGH0se6CXQ6cdZ
 | ||||
| -g1JRZeXkDEsrW3hfAsW62xJQmXcWxBoblP9OamMY+A06rM5og3JbDk5Zm6JsOaA8
 | ||||
| -wS2gw4ilp46jors4eQey8ux7kB9LzdBoDBBElnsbjLO8oBNZlVcYXg+6BOl/CUi7
 | ||||
| -2whRF0FEjKA8ehrNhAq+VFfFNw==
 | ||||
| ------END PRIVATE KEY-----
 | ||||
| +-----BEGIN RSA PRIVATE KEY-----
 | ||||
| +MIIEowIBAAKCAQEAsPnoGUOnrpiSqt4XynxA+HRP7S+BSObI6qJ7fQAVSPtRkqso
 | ||||
| +tWxQYLEYzNEx5ZSHTGypibVsJylvCfuToDTfMul8b/CZjP2Ob0LdpYrNH6l5hvFE
 | ||||
| +89FU1nZQF15oVLOpUgA7wGiHuEVawrGfey92UE68mOyUVXGweJIVDdxqdMoPvNNU
 | ||||
| +l86BU02vlBiESxOuox+dWmuVV7vfYZ79Toh/LUK43YvJh+rhv4nKuF7iHjVjBd9s
 | ||||
| +B6iDjj70HFldzOQ9r8SRI+9NirupPTkF5AKNe6kUhKJ1luB7S27ZkvB3tSTT3P59
 | ||||
| +3VVJvnzOjaA1z6Cz+4+eRvcysqhrRgFlwI9TEwIDAQABAoIBAEEYiyDP29vCzx/+
 | ||||
| +dS3LqnI5BjUuJhXUnc6AWX/PCgVAO+8A+gZRgvct7PtZb0sM6P9ZcLrweomlGezI
 | ||||
| +FrL0/6xQaa8bBr/ve/a8155OgcjFo6fZEw3Dz7ra5fbSiPmu4/b/kvrg+Br1l77J
 | ||||
| +aun6uUAs1f5B9wW+vbR7tzbT/mxaUeDiBzKpe15GwcvbJtdIVMa2YErtRjc1/5B2
 | ||||
| +BGVXyvlJv0SIlcIEMsHgnAFOp1ZgQ08aDzvilLq8XVMOahAhP1O2A3X8hKdXPyrx
 | ||||
| +IVWE9bS9ptTo+eF6eNl+d7htpKGEZHUxinoQpWEBTv+iOoHsVunkEJ3vjLP3lyI/
 | ||||
| +fY0NQ1ECgYEA3RBXAjgvIys2gfU3keImF8e/TprLge1I2vbWmV2j6rZCg5r/AS0u
 | ||||
| +pii5CvJ5/T5vfJPNgPBy8B/yRDs+6PJO1GmnlhOkG9JAIPkv0RBZvR0PMBtbp6nT
 | ||||
| +Y3yo1lwamBVBfY6rc0sLTzosZh2aGoLzrHNMQFMGaauORzBFpY5lU50CgYEAzPHl
 | ||||
| +u5DI6Xgep1vr8QvCUuEesCOgJg8Yh1UqVoY/SmQh6MYAv1I9bLGwrb3WW/7kqIoD
 | ||||
| +fj0aQV5buVZI2loMomtU9KY5SFIsPV+JuUpy7/+VE01ZQM5FdY8wiYCQiVZYju9X
 | ||||
| +Wz5LxMNoz+gT7pwlLCsC4N+R8aoBk404aF1gum8CgYAJ7VTq7Zj4TFV7Soa/T1eE
 | ||||
| +k9y8a+kdoYk3BASpCHJ29M5R2KEA7YV9wrBklHTz8VzSTFTbKHEQ5W5csAhoL5Fo
 | ||||
| +qoHzFFi3Qx7MHESQb9qHyolHEMNx6QdsHUn7rlEnaTTyrXh3ifQtD6C0yTmFXUIS
 | ||||
| +CW9wKApOrnyKJ9nI0HcuZQKBgQCMtoV6e9VGX4AEfpuHvAAnMYQFgeBiYTkBKltQ
 | ||||
| +XwozhH63uMMomUmtSG87Sz1TmrXadjAhy8gsG6I0pWaN7QgBuFnzQ/HOkwTm+qKw
 | ||||
| +AsrZt4zeXNwsH7QXHEJCFnCmqw9QzEoZTrNtHJHpNboBuVnYcoueZEJrP8OnUG3r
 | ||||
| +UjmopwKBgAqB2KYYMUqAOvYcBnEfLDmyZv9BTVNHbR2lKkMYqv5LlvDaBxVfilE0
 | ||||
| +2riO4p6BaAdvzXjKeRrGNEKoHNBpOSfYCOM16NjL8hIZB1CaV3WbT5oY+jp7Mzd5
 | ||||
| +7d56RZOE+ERK2uz/7JX9VSsM/LbH9pJibd4e8mikDS9ntciqOH/3
 | ||||
| +-----END RSA PRIVATE KEY-----
 | ||||
| @ -1,41 +0,0 @@ | ||||
| From 5e09d632f3b56d85b2659ab47d5571ae9e270e10 Mon Sep 17 00:00:00 2001 | ||||
| From: Xenor Chang <tubaxenor@gmail.com> | ||||
| Date: Mon, 28 Nov 2022 12:34:06 +0800 | ||||
| Subject: [PATCH] Loosen the domain regex to accept '.' (#29) | ||||
| 
 | ||||
| * Loosen the domain regex to accept '.' | ||||
| 
 | ||||
| Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> | ||||
| Co-authored-by: Hiroshi SHIBATA <hsbt@ruby-lang.org> | ||||
| ---
 | ||||
|  lib/cgi/cookie.rb           | 2 +- | ||||
|  test/cgi/test_cgi_cookie.rb | 3 +++ | ||||
|  2 files changed, 4 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
 | ||||
| index 1a9c1a8..9498e2f 100644
 | ||||
| --- a/lib/cgi/cookie.rb
 | ||||
| +++ b/lib/cgi/cookie.rb
 | ||||
| @@ -42,7 +42,7 @@ class Cookie < Array
 | ||||
| 
 | ||||
|      TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z" | ||||
|      PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z" | ||||
| -    DOMAIN_VALUE_RE = %r"\A(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
 | ||||
| +    DOMAIN_VALUE_RE = %r"\A\.?(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
 | ||||
| 
 | ||||
|      # Create a new CGI::Cookie object. | ||||
|      # | ||||
| diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
 | ||||
| index 6d31932..eadae45 100644
 | ||||
| --- a/test/cgi/test_cgi_cookie.rb
 | ||||
| +++ b/test/cgi/test_cgi_cookie.rb
 | ||||
| @@ -65,6 +65,9 @@ class CGICookieTest < Test::Unit::TestCase
 | ||||
|      cookie = CGI::Cookie.new({'domain' => 'a.example.com'}.merge(h)) | ||||
|      assert_equal('a.example.com', cookie.domain) | ||||
| 
 | ||||
| +    cookie = CGI::Cookie.new(h.merge('domain'=>'.example.com'))
 | ||||
| +    assert_equal('.example.com', cookie.domain)
 | ||||
| +
 | ||||
|      cookie = CGI::Cookie.new({'domain'=>'1.example.com'}.merge(h)) | ||||
|      assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123') | ||||
| 
 | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,264 +0,0 @@ | ||||
| From e56ac27d19cc3acdf6c1cb13b14224c43df5f5f6 Mon Sep 17 00:00:00 2001 | ||||
| From: Kouhei Sutou <kou@clear-code.com> | ||||
| Date: Thu, 4 Apr 2019 17:52:50 +0900 | ||||
| Subject: [PATCH] Accept String as a pattern | ||||
| 
 | ||||
| It's only for head only match case such as StringScanner#scan. | ||||
| 
 | ||||
| If we use a String as a pattern, we can improve match performance. | ||||
| Here is a result of the including benchmark. It shows String as a | ||||
| pattern is 1.25x faster than Regexp as a pattern. | ||||
| 
 | ||||
|     % rake benchmark | ||||
|     /tmp/local/bin/ruby -S benchmark-driver benchmark/scan.yaml | ||||
|     Warming up -------------------------------------- | ||||
|                   regexp    12.094M i/s -     12.242M times in 1.012250s (82.69ns/i, 277clocks/i) | ||||
|                   string    14.653M i/s -     14.889M times in 1.016124s (68.25ns/i, 252clocks/i) | ||||
|     Calculating ------------------------------------- | ||||
|                   regexp    14.713M i/s -     36.281M times in 2.465970s (67.97ns/i, 254clocks/i) | ||||
|                   string    18.422M i/s -     43.959M times in 2.386255s (54.28ns/i, 201clocks/i) | ||||
| 
 | ||||
|     Comparison: | ||||
|                   string:  18421631.8 i/s | ||||
|                   regexp:  14712660.7 i/s - 1.25x  slower | ||||
| 
 | ||||
| ====
 | ||||
| Backport https://github.com/ruby/strscan/pull/4 for strscan. | ||||
| 
 | ||||
| REXML fixes for CVE-2024-35716 depend on this feature. | ||||
| ---
 | ||||
|  ext/strscan/strscan.c              | 92 +++++++++++++++++++----------- | ||||
|  test/strscan/test_stringscanner.rb | 45 ++++++++++++++- | ||||
|  2 files changed, 100 insertions(+), 37 deletions(-) | ||||
| 
 | ||||
| diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c
 | ||||
| index d6168a0d4f..43319b672e 100644
 | ||||
| --- a/ext/strscan/strscan.c
 | ||||
| +++ b/ext/strscan/strscan.c
 | ||||
| @@ -447,15 +447,18 @@ strscan_set_pos(VALUE self, VALUE v)
 | ||||
|  } | ||||
|   | ||||
|  static VALUE | ||||
| -strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
 | ||||
| +strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly)
 | ||||
|  { | ||||
| -    regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
 | ||||
|      struct strscanner *p; | ||||
| -    regex_t *re;
 | ||||
| -    long ret;
 | ||||
| -    int tmpreg;
 | ||||
|   | ||||
| -    Check_Type(regex, T_REGEXP);
 | ||||
| +    if (headonly) {
 | ||||
| +        if (!RB_TYPE_P(pattern, T_REGEXP)) {
 | ||||
| +            StringValue(pattern);
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +    else {
 | ||||
| +        Check_Type(pattern, T_REGEXP);
 | ||||
| +    }
 | ||||
|      GET_SCANNER(self, p); | ||||
|   | ||||
|      CLEAR_MATCH_STATUS(p); | ||||
| @@ -463,37 +466,55 @@ strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
 | ||||
|          return Qnil; | ||||
|      } | ||||
|   | ||||
| -    p->regex = regex;
 | ||||
| -    re = rb_reg_prepare_re(regex, p->str);
 | ||||
| -    tmpreg = re != RREGEXP_PTR(regex);
 | ||||
| -    if (!tmpreg) RREGEXP(regex)->usecnt++;
 | ||||
| +    if (RB_TYPE_P(pattern, T_REGEXP)) {
 | ||||
| +        regex_t *rb_reg_prepare_re(VALUE re, VALUE str);
 | ||||
| +        regex_t *re;
 | ||||
| +        long ret;
 | ||||
| +        int tmpreg;
 | ||||
| +
 | ||||
| +        p->regex = pattern;
 | ||||
| +        re = rb_reg_prepare_re(pattern, p->str);
 | ||||
| +        tmpreg = re != RREGEXP_PTR(pattern);
 | ||||
| +        if (!tmpreg) RREGEXP(pattern)->usecnt++;
 | ||||
| +
 | ||||
| +        if (headonly) {
 | ||||
| +            ret = onig_match(re, (UChar* )CURPTR(p),
 | ||||
| +                             (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| +                             (UChar* )CURPTR(p), &(p->regs), ONIG_OPTION_NONE);
 | ||||
| +        }
 | ||||
| +        else {
 | ||||
| +            ret = onig_search(re,
 | ||||
| +                              (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| +                              (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| +                              &(p->regs), ONIG_OPTION_NONE);
 | ||||
| +        }
 | ||||
| +        if (!tmpreg) RREGEXP(pattern)->usecnt--;
 | ||||
| +        if (tmpreg) {
 | ||||
| +            if (RREGEXP(pattern)->usecnt) {
 | ||||
| +                onig_free(re);
 | ||||
| +            }
 | ||||
| +            else {
 | ||||
| +                onig_free(RREGEXP_PTR(pattern));
 | ||||
| +                RREGEXP_PTR(pattern) = re;
 | ||||
| +            }
 | ||||
| +        }
 | ||||
|   | ||||
| -    if (headonly) {
 | ||||
| -        ret = onig_match(re, (UChar* )CURPTR(p),
 | ||||
| -                         (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| -                         (UChar* )CURPTR(p), &(p->regs), ONIG_OPTION_NONE);
 | ||||
| +        if (ret == -2) rb_raise(ScanError, "regexp buffer overflow");
 | ||||
| +        if (ret < 0) {
 | ||||
| +            /* not matched */
 | ||||
| +            return Qnil;
 | ||||
| +        }
 | ||||
|      } | ||||
|      else { | ||||
| -        ret = onig_search(re,
 | ||||
| -                          (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| -                          (UChar* )CURPTR(p), (UChar* )(CURPTR(p) + S_RESTLEN(p)),
 | ||||
| -                          &(p->regs), ONIG_OPTION_NONE);
 | ||||
| -    }
 | ||||
| -    if (!tmpreg) RREGEXP(regex)->usecnt--;
 | ||||
| -    if (tmpreg) {
 | ||||
| -        if (RREGEXP(regex)->usecnt) {
 | ||||
| -            onig_free(re);
 | ||||
| +        rb_enc_check(p->str, pattern);
 | ||||
| +        if (S_RESTLEN(p) < RSTRING_LEN(pattern)) {
 | ||||
| +            return Qnil;
 | ||||
|          } | ||||
| -        else {
 | ||||
| -            onig_free(RREGEXP_PTR(regex));
 | ||||
| -            RREGEXP_PTR(regex) = re;
 | ||||
| +        if (memcmp(CURPTR(p), RSTRING_PTR(pattern), RSTRING_LEN(pattern)) != 0) {
 | ||||
| +            return Qnil;
 | ||||
|          } | ||||
| -    }
 | ||||
| -
 | ||||
| -    if (ret == -2) rb_raise(ScanError, "regexp buffer overflow");
 | ||||
| -    if (ret < 0) {
 | ||||
| -        /* not matched */
 | ||||
| -        return Qnil;
 | ||||
| +        onig_region_clear(&(p->regs));
 | ||||
| +        onig_region_set(&(p->regs), 0, 0, RSTRING_LEN(pattern));
 | ||||
|      } | ||||
|   | ||||
|      MATCHED(p); | ||||
| @@ -520,7 +541,8 @@ strscan_do_scan(VALUE self, VALUE regex, int succptr, int getstr, int headonly)
 | ||||
|   *   p s.scan(/\w+/)   # -> "test" | ||||
|   *   p s.scan(/\w+/)   # -> nil | ||||
|   *   p s.scan(/\s+/)   # -> " " | ||||
| - *   p s.scan(/\w+/)   # -> "string"
 | ||||
| + *   p s.scan("str")   # -> "str"
 | ||||
| + *   p s.scan(/\w+/)   # -> "ing"
 | ||||
|   *   p s.scan(/./)     # -> nil | ||||
|   * | ||||
|   */ | ||||
| @@ -539,6 +561,7 @@ strscan_scan(VALUE self, VALUE re)
 | ||||
|   *   s = StringScanner.new('test string') | ||||
|   *   p s.match?(/\w+/)   # -> 4 | ||||
|   *   p s.match?(/\w+/)   # -> 4 | ||||
| + *   p s.match?("test")  # -> 4
 | ||||
|   *   p s.match?(/\s+/)   # -> nil | ||||
|   */ | ||||
|  static VALUE | ||||
| @@ -560,7 +583,8 @@ strscan_match_p(VALUE self, VALUE re)
 | ||||
|   *   p s.skip(/\w+/)   # -> 4 | ||||
|   *   p s.skip(/\w+/)   # -> nil | ||||
|   *   p s.skip(/\s+/)   # -> 1 | ||||
| - *   p s.skip(/\w+/)   # -> 6
 | ||||
| + *   p s.skip("st")    # -> 2
 | ||||
| + *   p s.skip(/\w+/)   # -> 4
 | ||||
|   *   p s.skip(/./)     # -> nil | ||||
|   * | ||||
|   */ | ||||
| diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb
 | ||||
| index 3423f9cfed..63b1ce1f9b 100644
 | ||||
| --- a/test/strscan/test_stringscanner.rb
 | ||||
| +++ b/test/strscan/test_stringscanner.rb
 | ||||
| @@ -282,6 +282,22 @@ def test_scan
 | ||||
|      assert_equal "", s.scan(//) | ||||
|    end | ||||
|   | ||||
| +  def test_scan_string
 | ||||
| +    s = StringScanner.new('stra strb strc')
 | ||||
| +    assert_equal 'str', s.scan('str')
 | ||||
| +    assert_equal 'str', s[0]
 | ||||
| +    assert_equal 3, s.pos
 | ||||
| +    assert_equal false, s.tainted?
 | ||||
| +    assert_equal 'a ', s.scan('a ')
 | ||||
| +
 | ||||
| +    str = 'stra strb strc'.dup
 | ||||
| +    str.taint
 | ||||
| +    s = StringScanner.new(str, false)
 | ||||
| +    matched = s.scan('str')
 | ||||
| +    assert_equal 'str', matched
 | ||||
| +    assert_equal true, matched.tainted?
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_skip | ||||
|      s = StringScanner.new('stra strb strc', true) | ||||
|      assert_equal 4, s.skip(/\w+/) | ||||
| @@ -367,8 +383,10 @@ def test_matched
 | ||||
|      assert_equal false, s.matched.tainted? | ||||
|      s.scan(/\s+/) | ||||
|      assert_equal ' ', s.matched | ||||
| +    s.scan('st')
 | ||||
| +    assert_equal 'st', s.matched
 | ||||
|      s.scan(/\w+/) | ||||
| -    assert_equal 'strb', s.matched
 | ||||
| +    assert_equal 'rb', s.matched
 | ||||
|      s.scan(/\s+/) | ||||
|      assert_equal ' ', s.matched | ||||
|      s.scan(/\w+/) | ||||
| @@ -483,7 +501,7 @@ def test_pre_match
 | ||||
|      s.skip(/\s/) | ||||
|      assert_equal 'a', s.pre_match | ||||
|      assert_equal false, s.pre_match.tainted? | ||||
| -    s.scan(/\w/)
 | ||||
| +    s.scan('b')
 | ||||
|      assert_equal 'a ', s.pre_match | ||||
|      s.scan_until(/c/) | ||||
|      assert_equal 'a b ', s.pre_match | ||||
| @@ -513,7 +531,7 @@ def test_post_match
 | ||||
|      assert_equal ' b c d e', s.post_match | ||||
|      s.skip(/\s/) | ||||
|      assert_equal 'b c d e', s.post_match | ||||
| -    s.scan(/\w/)
 | ||||
| +    s.scan('b')
 | ||||
|      assert_equal ' c d e', s.post_match | ||||
|      s.scan_until(/c/) | ||||
|      assert_equal ' d e', s.post_match | ||||
| @@ -589,6 +607,20 @@ def test_encoding
 | ||||
|      assert_equal(Encoding::EUC_JP, ss.scan(/./e).encoding) | ||||
|    end | ||||
|   | ||||
| +  def test_encoding_string
 | ||||
| +    str = "\xA1\xA2".dup.force_encoding("euc-jp")
 | ||||
| +    ss = StringScanner.new(str)
 | ||||
| +    assert_equal(str.dup, ss.scan(str.dup))
 | ||||
| +  end
 | ||||
| +
 | ||||
| +  def test_invalid_encoding_string
 | ||||
| +    str = "\xA1\xA2".dup.force_encoding("euc-jp")
 | ||||
| +    ss = StringScanner.new(str)
 | ||||
| +    assert_raise(Encoding::CompatibilityError) do
 | ||||
| +      ss.scan(str.encode("UTF-8"))
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_generic_regexp | ||||
|      ss = StringScanner.new("\xA1\xA2".dup.force_encoding("euc-jp")) | ||||
|      t = ss.scan(/./) | ||||
| @@ -643,6 +675,13 @@ def test_exist_p
 | ||||
|      assert_equal(nil, s.exist?(/e/)) | ||||
|    end | ||||
|   | ||||
| +  def test_exist_p_string
 | ||||
| +    s = StringScanner.new("test string")
 | ||||
| +    assert_raise(TypeError) do
 | ||||
| +      s.exist?(" ")
 | ||||
| +    end
 | ||||
| +  end
 | ||||
| +
 | ||||
|    def test_skip_until | ||||
|      s = StringScanner.new("Foo Bar Baz") | ||||
|      assert_equal(3, s.skip_until(/Foo/)) | ||||
| @ -2,13 +2,31 @@ | ||||
| %gem_dir %{_datadir}/gems | ||||
| %gem_archdir %{_libdir}/gems | ||||
| 
 | ||||
| # %gem_name_version - Provides gem_name-version string. | ||||
| # | ||||
| # Usage: %gem_name_version [custom_gem_name] | ||||
| # | ||||
| # Prints gem_name-version string, by default joining %gem_name, %version and | ||||
| # %prerelease macros. When [custom_gem_name] is provided, the | ||||
| # custom_gem_name is joined with %custom_gem_name_version macro which needs | ||||
| # to be predefined. Please note that for the version macros are the dashes | ||||
| # replaced by underscores. | ||||
| # | ||||
| %gem_name_version() %{?1}%{!?1:%{gem_name}}-%{?1:%{expand:%{%{gsub %{1} - _}_version}}}%{!?1:%{version}}%{?prerelease} | ||||
| 
 | ||||
| # Common gem locations and files. | ||||
| %gem_instdir %{gem_dir}/gems/%{gem_name}-%{version}%{?prerelease} | ||||
| %gem_extdir_mri %{gem_archdir}/%{name}/%{gem_name}-%{version}%{?prerelease} | ||||
| %gem_libdir %{gem_instdir}/lib | ||||
| %gem_cache %{gem_dir}/cache/%{gem_name}-%{version}%{?prerelease}.gem | ||||
| %gem_spec %{gem_dir}/specifications/%{gem_name}-%{version}%{?prerelease}.gemspec | ||||
| %gem_docdir %{gem_dir}/doc/%{gem_name}-%{version}%{?prerelease} | ||||
| # | ||||
| # These macros leverages %gem_name_version macro and accepts custom gem_name. | ||||
| # | ||||
| # -d                 Use default gem install location. | ||||
| # | ||||
| %gem_instdir() %{gem_dir}/gems/%{gem_name_version %{?1}} | ||||
| %gem_extdir_mri() %{gem_archdir}/%{name}/%{gem_name_version %{?1}} | ||||
| %gem_libdir() %{gem_instdir %{?1}}/lib | ||||
| %gem_cache() %{gem_dir}/cache/%{gem_name_version %{?1}}.gem | ||||
| %gem_spec(d) %{gem_dir}/specifications%{?-d:/default}/%{gem_name_version %{?1}}.gemspec | ||||
| %gem_docdir() %{gem_dir}/doc/%{gem_name_version %{?1}} | ||||
| %gem_plugin() %{gem_dir}/plugins/%{?1}%{!?1:%{gem_name}}_plugin.rb | ||||
| 
 | ||||
| 
 | ||||
| # %gem_install - Install gem into appropriate directory. | ||||
| @ -21,7 +39,7 @@ | ||||
| %gem_install(d:n:) \ | ||||
| mkdir -p %{-d*}%{!?-d:.%{gem_dir}} \ | ||||
| \ | ||||
| CONFIGURE_ARGS="--with-cflags='%{optflags}' $CONFIGURE_ARGS" \\\ | ||||
| CONFIGURE_ARGS="--with-cflags='%{optflags}' --with-cxxflags='%{optflags}' --with-ldflags='%{build_ldflags}' $CONFIGURE_ARGS" \\\ | ||||
| gem install \\\ | ||||
|         -V \\\ | ||||
|         --local \\\ | ||||
| @ -32,16 +50,6 @@ gem install \\\ | ||||
| %{nil} | ||||
| 
 | ||||
| 
 | ||||
| # For rubygems packages we want to filter out any provides caused by private | ||||
| # libs in %%{gem_archdir}. | ||||
| # | ||||
| # Note that this must be invoked in the spec file, preferably as | ||||
| # "%{?rubygems_default_filter}", before any %description block. | ||||
| %rubygems_default_filter %{expand: \ | ||||
| %global __provides_exclude_from %{?__provides_exclude_from:%{__provides_exclude_from}|}^%{gem_extdir_mri}/.*\\\\.so$ \ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| # The 'read' command in %%gemspec_* macros is not essential, but it is usefull | ||||
| # to make the sript appear in build log. | ||||
| 
 | ||||
| @ -87,34 +87,34 @@ module Gem | ||||
|     # Remove methods we are going to override. This avoids "method redefined;" | ||||
|     # warnings otherwise issued by Ruby. | ||||
| 
 | ||||
|     remove_method :operating_system_defaults if method_defined? :operating_system_defaults | ||||
|     remove_method :default_dir if method_defined? :default_dir | ||||
|     remove_method :default_specifications_dir if method_defined? :default_specifications_dir | ||||
|     remove_method :default_path if method_defined? :default_path | ||||
|     remove_method :default_bindir if method_defined? :default_bindir | ||||
|     remove_method :default_ext_dir_for if method_defined? :default_ext_dir_for | ||||
| 
 | ||||
|     ## | ||||
|     # Regular user installs into user directory, root manages /usr/local. | ||||
| 
 | ||||
|     def operating_system_defaults | ||||
|       unless opt_build_root? | ||||
|         options = if Process.uid == 0 | ||||
|           "--install-dir=#{Gem.default_dirs[:local][:gem_dir]} --bindir #{Gem.default_dirs[:local][:bin_dir]}" | ||||
|         else | ||||
|           "--user-install --bindir #{File.join [Dir.home, 'bin']}" | ||||
|         end | ||||
| 
 | ||||
|         {"gem" => options} | ||||
|       else | ||||
|         {} | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     ## | ||||
|     # RubyGems default overrides. | ||||
| 
 | ||||
|     def default_dir | ||||
|       if opt_build_root? | ||||
|         Gem.default_dirs[:system][:gem_dir] | ||||
|       elsif Process.uid == 0 | ||||
|         Gem.default_dirs[:local][:gem_dir] | ||||
|       else | ||||
|         Gem.user_dir | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     ## | ||||
|     # Path to specification files of default gems. | ||||
| 
 | ||||
|     def default_specifications_dir | ||||
|       @default_specifications_dir ||= File.join(Gem.default_dirs[:system][:gem_dir], "specifications", "default") | ||||
|     end | ||||
| 
 | ||||
|     ## | ||||
|     # Default gem load path | ||||
| 
 | ||||
|     def default_path | ||||
|       path = default_dirs.collect {|location, paths| paths[:gem_dir]} | ||||
| @ -122,6 +122,16 @@ module Gem | ||||
|       path | ||||
|     end | ||||
| 
 | ||||
|     def default_bindir | ||||
|       if opt_build_root? | ||||
|         Gem.default_dirs[:system][:bin_dir] | ||||
|       elsif Process.uid == 0 | ||||
|         Gem.default_dirs[:local][:bin_dir] | ||||
|       else | ||||
|         File.join [Dir.home, 'bin'] | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def default_ext_dir_for base_dir | ||||
|       dir = if rpmbuild? | ||||
|         build_dir = base_dir.chomp Gem.default_dirs[:system][:gem_dir] | ||||
| @ -8,10 +8,10 @@ Subject: [PATCH] Allow to configure libruby.so placement. | ||||
|  1 file changed, 5 insertions(+) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 11fc237552..b77e88fc37 100644
 | ||||
| index d261ea57b5..3c13076b82 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -3642,6 +3642,11 @@ AS_IF([test ${multiarch+set}], [
 | ||||
| @@ -3473,6 +3473,11 @@ AS_IF([test ${multiarch+set}], [
 | ||||
|  ]) | ||||
|   | ||||
|  archlibdir='${libdir}/${arch}' | ||||
| @ -23,6 +23,3 @@ index 11fc237552..b77e88fc37 100644 | ||||
|  sitearchlibdir='${libdir}/${sitearch}' | ||||
|  archincludedir='${includedir}/${arch}' | ||||
|  sitearchincludedir='${includedir}/${sitearch}' | ||||
| -- 
 | ||||
| 1.8.3.1 | ||||
| 
 | ||||
| @ -11,10 +11,10 @@ Subject: [PATCH] Prevent duplicated paths when empty version string is | ||||
|  3 files changed, 15 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 999e2d6d5d..11fc237552 100644
 | ||||
| index c42436c23d..d261ea57b5 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4252,7 +4252,8 @@ AS_CASE(["$ruby_version_dir_name"],
 | ||||
| @@ -4312,7 +4312,8 @@ AS_CASE(["$ruby_version_dir_name"],
 | ||||
|  ruby_version_dir=/'${ruby_version_dir_name}' | ||||
|   | ||||
|  if test -z "${ruby_version_dir_name}"; then | ||||
| @ -66,7 +66,7 @@ diff --git a/tool/mkconfig.rb b/tool/mkconfig.rb | ||||
| index 07076d4..35e6c3c 100755
 | ||||
| --- a/tool/mkconfig.rb
 | ||||
| +++ b/tool/mkconfig.rb
 | ||||
| @@ -111,7 +111,7 @@
 | ||||
| @@ -115,7 +115,7 @@
 | ||||
|      val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump | ||||
|      case name | ||||
|      when /^prefix$/ | ||||
| @ -75,6 +75,3 @@ index 07076d4..35e6c3c 100755 | ||||
|      when /^ARCH_FLAG$/ | ||||
|        val = "arch_flag || #{val}" if universal | ||||
|      when /^UNIVERSAL_ARCHNAMES$/ | ||||
| -- 
 | ||||
| 1.9.0 | ||||
| 
 | ||||
| @ -8,10 +8,10 @@ Subject: [PATCH] Always use i386. | ||||
|  1 file changed, 2 insertions(+) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index b77e88fc37..6bba453e3c 100644
 | ||||
| index 3c13076b82..93af30321d 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4316,6 +4316,8 @@ AC_SUBST(vendorarchdir)dnl
 | ||||
| @@ -4376,6 +4376,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 | ||||
|   | ||||
| @ -20,6 +20,3 @@ index b77e88fc37..6bba453e3c 100644 | ||||
|  AS_IF([test "${universal_binary-no}" = yes ], [ | ||||
|      arch="universal-${target_os}" | ||||
|      AS_IF([test "${rb_cv_architecture_available}" = yes], [ | ||||
| -- 
 | ||||
| 1.8.3.1 | ||||
| 
 | ||||
| @ -8,14 +8,14 @@ Subject: [PATCH] Allow to install RubyGems into custom location, outside of | ||||
|  configure.ac            |  5 +++++ | ||||
|  loadpath.c              |  4 ++++ | ||||
|  template/verconf.h.tmpl |  3 +++ | ||||
|  tool/rbinstall.rb       | 7 +++++++ | ||||
|  4 files changed, 19 insertions(+) | ||||
|  tool/rbinstall.rb       | 10 ++++++++++ | ||||
|  4 files changed, 22 insertions(+) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 6bba453e3c..028ef7ca3e 100644
 | ||||
| index 93af30321d..bc13397e0e 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4288,6 +4288,10 @@ AC_ARG_WITH(vendorarchdir,
 | ||||
| @@ -4348,6 +4348,10 @@ AC_ARG_WITH(vendorarchdir,
 | ||||
|              [vendorarchdir=$withval], | ||||
|              [vendorarchdir=${multiarch+'${rubysitearchprefix}/vendor_ruby'${ruby_version_dir}}${multiarch-'${vendorlibdir}/${sitearch}'}]) | ||||
|   | ||||
| @ -26,7 +26,7 @@ index 6bba453e3c..028ef7ca3e 100644 | ||||
|  AS_IF([test "${LOAD_RELATIVE+set}"], [ | ||||
|      AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) | ||||
|      RUBY_EXEC_PREFIX='' | ||||
| @@ -4312,6 +4316,7 @@ AC_SUBST(sitearchdir)dnl
 | ||||
| @@ -4372,6 +4376,7 @@ AC_SUBST(sitearchdir)dnl
 | ||||
|  AC_SUBST(vendordir)dnl | ||||
|  AC_SUBST(vendorlibdir)dnl | ||||
|  AC_SUBST(vendorarchdir)dnl | ||||
| @ -64,31 +64,31 @@ index 79c003e..34f2382 100644 | ||||
|  % R = {} | ||||
|  % R["ruby_version"] = '"RUBY_LIB_VERSION"' | ||||
| diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
 | ||||
| index b47b6e1..0b99408 100755
 | ||||
| index e9110a17ca..76a1f0a315 100755
 | ||||
| --- a/tool/rbinstall.rb
 | ||||
| +++ b/tool/rbinstall.rb
 | ||||
| @@ -335,6 +335,7 @@ def CONFIG.[](name, mandatory = false)
 | ||||
| @@ -359,6 +359,7 @@ def CONFIG.[](name, mandatory = false)
 | ||||
|    vendorlibdir = CONFIG["vendorlibdir"] | ||||
|    vendorarchlibdir = CONFIG["vendorarchdir"] | ||||
|  end | ||||
| +rubygemsdir = CONFIG["rubygemsdir"]
 | ||||
|  mandir = CONFIG["mandir", true] | ||||
|  docdir = CONFIG["docdir", true] | ||||
|  configure_args = Shellwords.shellwords(CONFIG["configure_args"]) | ||||
| @@ -541,7 +542,13 @@ def install(src, cmd)
 | ||||
|  enable_shared = CONFIG["ENABLE_SHARED"] == 'yes' | ||||
| @@ -595,7 +596,16 @@ def stub
 | ||||
|  install?(:local, :comm, :lib) do | ||||
|    prepare "library scripts", rubylibdir | ||||
|    noinst = %w[*.txt *.rdoc *.gemspec] | ||||
| +  noinst += %w[rubygems.rb rubygems/ datadir.rb] if rubygemsdir
 | ||||
| +  # Bundler carries "rubygems.rb" file, so it must be specialcased :/
 | ||||
| +  noinst += %w[rubygems.rb rubygems/ bundler.rb bundler/] if rubygemsdir
 | ||||
|    install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode) | ||||
| +  if rubygemsdir
 | ||||
| +    noinst = %w[obsolete.rb]
 | ||||
| +    install_recursive(File.join(srcdir, "lib", "rubygems"), File.join(rubygemsdir, "rubygems"), :mode => $data_mode)
 | ||||
| +    noinst = %w[*.txt *.rdoc *.gemspec]
 | ||||
| +    install_recursive(File.join(srcdir, "lib", "rubygems"), File.join(rubygemsdir, "rubygems"), :no_install => noinst, :mode => $data_mode)
 | ||||
| +    install(File.join(srcdir, "lib", "rubygems.rb"), File.join(rubygemsdir, "rubygems.rb"), :mode => $data_mode)
 | ||||
| +    install_recursive(File.join(srcdir, "lib", "bundler"), File.join(rubylibdir, "bundler"), :no_install => noinst, :mode => $data_mode)
 | ||||
| +    install(File.join(srcdir, "lib", "bundler.rb"), rubylibdir, :mode => $data_mode)
 | ||||
| +  end
 | ||||
|  end | ||||
|   | ||||
|  install?(:local, :comm, :hdr, :'comm-hdr') do | ||||
| -- 
 | ||||
| 1.8.3.1 | ||||
| 
 | ||||
| @ -12,15 +12,15 @@ ruby_version_dir_name now specifies custom version string for versioned | ||||
| directories, e.g. instead of default X.Y.Z, you can specify whatever | ||||
| string. | ||||
| ---
 | ||||
|  configure.ac        | 64 ++++++++++++++++++++++++++++------------------------- | ||||
|  configure.ac        | 66 ++++++++++++++++++++++++--------------------- | ||||
|  template/ruby.pc.in |  1 + | ||||
|  2 files changed, 35 insertions(+), 30 deletions(-) | ||||
|  2 files changed, 36 insertions(+), 31 deletions(-) | ||||
| 
 | ||||
| diff --git a/configure.ac b/configure.ac
 | ||||
| index 8ea969412f..a00f2b6776 100644
 | ||||
| index 80b137e380..63cd3b4f8b 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -4203,9 +4203,6 @@ AS_CASE(["$target_os"],
 | ||||
| @@ -4262,9 +4262,6 @@ AS_CASE(["$target_os"],
 | ||||
|      rubyw_install_name='$(RUBYW_INSTALL_NAME)' | ||||
|      ]) | ||||
|   | ||||
| @ -30,7 +30,7 @@ index 8ea969412f..a00f2b6776 100644 | ||||
|  rubyarchprefix=${multiarch+'${archlibdir}/${RUBY_BASE_NAME}'}${multiarch-'${rubylibprefix}/${arch}'} | ||||
|  AC_ARG_WITH(rubyarchprefix, | ||||
|  	    AS_HELP_STRING([--with-rubyarchprefix=DIR], | ||||
| @@ -4228,56 +4225,62 @@ AC_ARG_WITH(ridir,
 | ||||
| @@ -4287,57 +4284,63 @@ AC_ARG_WITH(ridir,
 | ||||
|  AC_SUBST(ridir) | ||||
|  AC_SUBST(RI_BASE_NAME) | ||||
|   | ||||
| @ -46,6 +46,7 @@ index 8ea969412f..a00f2b6776 100644 | ||||
| -AS_IF([test ${RUBY_LIB_VERSION_STYLE+set}], [
 | ||||
| -    {
 | ||||
| -    echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE"
 | ||||
| -    echo '@%:@include "confdefs.h"'
 | ||||
| -    echo '#define STRINGIZE(x) x'
 | ||||
| -    test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0'
 | ||||
| -    echo '#include "version.h"'
 | ||||
| @ -61,6 +62,7 @@ index 8ea969412f..a00f2b6776 100644 | ||||
| +RUBY_LIB_VERSION_STYLE='3	/* full */'
 | ||||
| +{
 | ||||
| +echo "#define RUBY_LIB_VERSION_STYLE $RUBY_LIB_VERSION_STYLE"
 | ||||
| +echo '@%:@include "confdefs.h"'
 | ||||
| +echo '#define STRINGIZE(x) x'
 | ||||
| +test -f revision.h -o -f "${srcdir}/revision.h" || echo '#define RUBY_REVISION 0'
 | ||||
| +echo '#include "version.h"'
 | ||||
| @ -120,7 +122,7 @@ index 8ea969412f..a00f2b6776 100644 | ||||
|   | ||||
|  AS_IF([test "${LOAD_RELATIVE+set}"], [ | ||||
|      AC_DEFINE_UNQUOTED(LOAD_RELATIVE, $LOAD_RELATIVE) | ||||
| @@ -4294,6 +4297,7 @@ AC_SUBST(sitearchincludedir)dnl
 | ||||
| @@ -4354,6 +4357,7 @@ AC_SUBST(sitearchincludedir)dnl
 | ||||
|  AC_SUBST(arch)dnl | ||||
|  AC_SUBST(sitearch)dnl | ||||
|  AC_SUBST(ruby_version)dnl | ||||
| @ -132,16 +134,14 @@ diff --git a/template/ruby.pc.in b/template/ruby.pc.in | ||||
| index 8a2c066..c81b211 100644
 | ||||
| --- a/template/ruby.pc.in
 | ||||
| +++ b/template/ruby.pc.in
 | ||||
| @@ -9,6 +9,7 @@ MAJOR=@MAJOR@
 | ||||
| @@ -2,6 +2,7 @@ MAJOR=@MAJOR@
 | ||||
|  MINOR=@MINOR@ | ||||
|  TEENY=@TEENY@ | ||||
|  ruby_version=@ruby_version@ | ||||
| +ruby_version_dir_name=@ruby_version_dir_name@
 | ||||
|  RUBY_API_VERSION=@RUBY_API_VERSION@ | ||||
|  RUBY_PROGRAM_VERSION=@RUBY_PROGRAM_VERSION@ | ||||
|  RUBY_BASE_NAME=@RUBY_BASE_NAME@ | ||||
| -- 
 | ||||
| 2.1.0 | ||||
|  arch=@arch@ | ||||
| 
 | ||||
| 
 | ||||
| From 518850aba6eee76de7715aae8d37330e34b01983 Mon Sep 17 00:00:00 2001 | ||||
| @ -165,107 +165,87 @@ index 970cb91..5bf8230 100644 | ||||
| -  version = RbConfig::CONFIG['ruby_version']
 | ||||
| +  version = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|   | ||||
|    BASE    = if RbConfig::CONFIG.key? 'ridir' then | ||||
|                File.join RbConfig::CONFIG['ridir'], version | ||||
|    BASE    = File.join RbConfig::CONFIG['ridir'], version | ||||
|   | ||||
| diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
 | ||||
| index d4c110e..d39c9a6 100755
 | ||||
| --- a/tool/rbinstall.rb
 | ||||
| +++ b/tool/rbinstall.rb
 | ||||
| @@ -421,7 +421,7 @@ def CONFIG.[](name, mandatory = false)
 | ||||
| @@ -453,7 +453,7 @@ def CONFIG.[](name, mandatory = false)
 | ||||
|   | ||||
|  install?(:doc, :rdoc) do | ||||
|    if $rdocdir | ||||
| -    ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system")
 | ||||
| +    ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version_dir_name'] || CONFIG['ruby_version'], "system")
 | ||||
|      prepare "rdoc", ridatadir | ||||
|      install_recursive($rdocdir, ridatadir, :mode => $data_mode) | ||||
|      install_recursive($rdocdir, ridatadir, :no_install => rdoc_noinst, :mode => $data_mode) | ||||
|    end | ||||
| -- 
 | ||||
| 2.1.0 | ||||
| 
 | ||||
| 
 | ||||
| From f8d136f9a46d1fe87eba622ab9665935d05e981b Mon Sep 17 00:00:00 2001 | ||||
| From 9f0ec0233f618cbb862629816b22491c3df79578 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Tue, 31 Mar 2015 16:37:44 +0200 | ||||
| Subject: [PATCH 3/4] Add ruby_version_dir_name support for RubyGems. | ||||
| 
 | ||||
| ---
 | ||||
|  lib/rubygems/defaults.rb  | 11 ++++++----- | ||||
|  lib/rubygems/defaults.rb  | 7 ++++--- | ||||
|  test/rubygems/test_gem.rb | 5 +++-- | ||||
|  2 files changed, 9 insertions(+), 7 deletions(-) | ||||
|  2 files changed, 7 insertions(+), 5 deletions(-) | ||||
| 
 | ||||
| diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
 | ||||
| index 55ca080..75eea2b 100644
 | ||||
| index d4ff4a262c..3f9a5bf590 100644
 | ||||
| --- a/lib/rubygems/defaults.rb
 | ||||
| +++ b/lib/rubygems/defaults.rb
 | ||||
| @@ -32,20 +32,20 @@ def self.default_dir
 | ||||
|               [ | ||||
|                 File.dirname(RbConfig::CONFIG['sitedir']), | ||||
|                 'Gems', | ||||
| -               RbConfig::CONFIG['ruby_version']
 | ||||
| +               RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|               ] | ||||
|             elsif RbConfig::CONFIG['rubylibprefix'] then | ||||
|               [ | ||||
|                RbConfig::CONFIG['rubylibprefix'], | ||||
|                'gems', | ||||
| -              RbConfig::CONFIG['ruby_version']
 | ||||
| +              RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|               ] | ||||
|             else | ||||
|               [ | ||||
|                 RbConfig::CONFIG['libdir'], | ||||
|                 ruby_engine, | ||||
|                 'gems', | ||||
| -               RbConfig::CONFIG['ruby_version']
 | ||||
| +               RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|               ] | ||||
| @@ -35,7 +35,7 @@ def self.default_spec_cache_dir
 | ||||
|    # specified in the environment | ||||
|   | ||||
|    def self.default_dir | ||||
| -    @default_dir ||= File.join(RbConfig::CONFIG["rubylibprefix"], "gems", RbConfig::CONFIG["ruby_version"])
 | ||||
| +    @default_dir ||= File.join(RbConfig::CONFIG["rubylibprefix"], "gems", RbConfig::CONFIG["ruby_version_dir_name"] || RbConfig::CONFIG["ruby_version"])
 | ||||
|    end | ||||
|   | ||||
| @@ -75,7 +75,8 @@ def self.default_rubygems_dirs
 | ||||
|   | ||||
|    def self.user_dir | ||||
|      parts = [Gem.user_home, '.gem', ruby_engine] | ||||
| -    parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty?
 | ||||
| +    ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|    ## | ||||
| @@ -104,7 +104,8 @@ def self.user_dir
 | ||||
|      gem_dir = File.join(Gem.user_home, ".gem") | ||||
|      gem_dir = File.join(Gem.data_home, "gem") unless File.exist?(gem_dir) | ||||
|      parts = [gem_dir, ruby_engine] | ||||
| -    parts << RbConfig::CONFIG["ruby_version"] unless RbConfig::CONFIG["ruby_version"].empty?
 | ||||
| +    ruby_version_dir_name = RbConfig::CONFIG["ruby_version_dir_name"] || RbConfig::CONFIG["ruby_version"]
 | ||||
| +    parts << ruby_version_dir_name unless ruby_version_dir_name.empty?
 | ||||
|      File.join parts | ||||
|    end | ||||
|   | ||||
| @@ -172,7 +173,7 @@ def self.vendor_dir # :nodoc:
 | ||||
|      return nil unless RbConfig::CONFIG.key? 'vendordir' | ||||
| @@ -265,7 +266,7 @@ def self.vendor_dir # :nodoc:
 | ||||
|      return nil unless RbConfig::CONFIG.key? "vendordir" | ||||
|   | ||||
|      File.join RbConfig::CONFIG['vendordir'], 'gems', | ||||
| -              RbConfig::CONFIG['ruby_version']
 | ||||
| +              RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|      File.join RbConfig::CONFIG["vendordir"], "gems", | ||||
| -              RbConfig::CONFIG["ruby_version"]
 | ||||
| +              RbConfig::CONFIG["ruby_version_dir_name"] || RbConfig::CONFIG["ruby_version"]
 | ||||
|    end | ||||
|   | ||||
|    ## | ||||
| diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
 | ||||
| index 0428bea..b6e090e 100644
 | ||||
| index b25068405d..e9fef4a311 100644
 | ||||
| --- a/test/rubygems/test_gem.rb
 | ||||
| +++ b/test/rubygems/test_gem.rb
 | ||||
| @@ -1191,7 +1191,8 @@ def test_self_use_paths
 | ||||
| @@ -1351,7 +1351,8 @@ def test_self_use_paths
 | ||||
|   | ||||
|    def test_self_user_dir | ||||
|      parts = [@userhome, '.gem', Gem.ruby_engine] | ||||
| -    parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty?
 | ||||
| +    ruby_version_dir_name = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|      parts = [@userhome, ".gem", Gem.ruby_engine] | ||||
| -    parts << RbConfig::CONFIG["ruby_version"] unless RbConfig::CONFIG["ruby_version"].empty?
 | ||||
| +    ruby_version_dir_name = RbConfig::CONFIG["ruby_version_dir_name"] || RbConfig::CONFIG["ruby_version"]
 | ||||
| +    parts << ruby_version_dir_name unless ruby_version_dir_name.empty?
 | ||||
|   | ||||
|      assert_equal File.join(parts), Gem.user_dir | ||||
|    end | ||||
| @@ -1318,7 +1319,7 @@ def test_self_user_home_user_drive_and_path
 | ||||
|    def test_self_vendor_dir | ||||
|      FileUtils.mkdir_p File.join(parts) | ||||
|   | ||||
| @@ -1427,7 +1428,7 @@ def test_self_vendor_dir
 | ||||
|      vendordir(File.join(@tempdir, "vendor")) do | ||||
|        expected = | ||||
|        File.join RbConfig::CONFIG['vendordir'], 'gems', | ||||
| -                RbConfig::CONFIG['ruby_version']
 | ||||
| +                RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version']
 | ||||
|          File.join RbConfig::CONFIG["vendordir"], "gems", | ||||
| -                  RbConfig::CONFIG["ruby_version"]
 | ||||
| +                  RbConfig::CONFIG["ruby_version_dir_name"] || RbConfig::CONFIG["ruby_version"]
 | ||||
|   | ||||
|        assert_equal expected, Gem.vendor_dir | ||||
|      end | ||||
| -- 
 | ||||
| 2.1.0 | ||||
| 
 | ||||
| 
 | ||||
| From 88c38a030c22dbf9422ece847bdfbf87d6659313 Mon Sep 17 00:00:00 2001 | ||||
| @ -282,15 +262,12 @@ diff --git a/configure.ac b/configure.ac | ||||
| index a00f2b6776..999e2d6d5d 100644
 | ||||
| --- a/configure.ac
 | ||||
| +++ b/configure.ac
 | ||||
| @@ -164,7 +164,7 @@ RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"`
 | ||||
| @@ -135,7 +135,7 @@ RUBY_BASE_NAME=`echo ruby | sed "$program_transform_name"`
 | ||||
|  RUBYW_BASE_NAME=`echo rubyw | sed "$program_transform_name"` | ||||
|  AC_SUBST(RUBY_BASE_NAME) | ||||
|  AC_SUBST(RUBYW_BASE_NAME) | ||||
| -AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version}')
 | ||||
| +AC_SUBST(RUBY_VERSION_NAME, '${RUBY_BASE_NAME}-${ruby_version_dir_name}')
 | ||||
|   | ||||
|  AC_CANONICAL_TARGET | ||||
|  test x"$target_alias" = x && | ||||
| -- 
 | ||||
| 2.1.0 | ||||
| 
 | ||||
|  dnl checks for alternative programs | ||||
|  AC_CANONICAL_BUILD | ||||
							
								
								
									
										88
									
								
								ruby-2.7.0-Initialize-ABRT-hook.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								ruby-2.7.0-Initialize-ABRT-hook.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| From eca084e4079c77c061045df9c21b219175b05228 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Mon, 6 Jan 2020 13:56:04 +0100 | ||||
| Subject: [PATCH] Initialize ABRT hook. | ||||
| 
 | ||||
| The ABRT hook used to be initialized by preludes via patches [[1], [2]]. | ||||
| Unfortunately, due to [[3]] and especially since [[4]], this would | ||||
| require boostrapping [[5]]. | ||||
| 
 | ||||
| To keep the things simple for now, load the ABRT hook via C. | ||||
| 
 | ||||
| [1]: https://bugs.ruby-lang.org/issues/8566 | ||||
| [2]: https://bugs.ruby-lang.org/issues/15306 | ||||
| [3]: https://bugs.ruby-lang.org/issues/16254 | ||||
| [4]: https://github.com/ruby/ruby/pull/2735 | ||||
| [5]: https://lists.fedoraproject.org/archives/list/ruby-sig@lists.fedoraproject.org/message/LH6L6YJOYQT4Y5ZNOO4SLIPTUWZ5V45Q/ | ||||
| ---
 | ||||
|  abrt.c                                | 12 ++++++++++++ | ||||
|  common.mk                             |  3 ++- | ||||
|  ruby.c                                |  4 ++++ | ||||
|  spec/ruby/core/kernel/require_spec.rb |  2 ++ | ||||
|  4 files changed, 20 insertions(+), 1 deletion(-) | ||||
|  create mode 100644 abrt.c | ||||
| 
 | ||||
| diff --git a/abrt.c b/abrt.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000..74b0bd5c0f
 | ||||
| --- /dev/null
 | ||||
| +++ b/abrt.c
 | ||||
| @@ -0,0 +1,12 @@
 | ||||
| +#include "internal.h"
 | ||||
| +
 | ||||
| +void
 | ||||
| +Init_abrt(void)
 | ||||
| +{
 | ||||
| +  rb_eval_string(
 | ||||
| +    "  begin\n"
 | ||||
| +    "    require 'abrt'\n"
 | ||||
| +    "  rescue LoadError\n"
 | ||||
| +    "  end\n"
 | ||||
| +  );
 | ||||
| +}
 | ||||
| diff --git a/common.mk b/common.mk
 | ||||
| index b2e5b2b6d0..f39f81da5c 100644
 | ||||
| --- a/common.mk
 | ||||
| +++ b/common.mk
 | ||||
| @@ -111,7 +111,8 @@ PRISM_FILES = prism/api_node.$(OBJEXT) \
 | ||||
|  		prism/prism.$(OBJEXT) \ | ||||
|  		prism_init.$(OBJEXT) | ||||
|   | ||||
| -COMMONOBJS    = array.$(OBJEXT) \
 | ||||
| +COMMONOBJS    = abrt.$(OBJEXT) \
 | ||||
| +                array.$(OBJEXT) \
 | ||||
|  		ast.$(OBJEXT) \ | ||||
|  		bignum.$(OBJEXT) \ | ||||
|  		class.$(OBJEXT) \ | ||||
| diff --git a/ruby.c b/ruby.c
 | ||||
| index 60c57d6259..1eec16f2c8 100644
 | ||||
| --- a/ruby.c
 | ||||
| +++ b/ruby.c
 | ||||
| @@ -1724,10 +1724,14 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
 | ||||
|   | ||||
|  void Init_builtin_features(void); | ||||
|   | ||||
| +/* abrt.c */
 | ||||
| +void Init_abrt(void);
 | ||||
| +
 | ||||
|  static void | ||||
|  ruby_init_prelude(void) | ||||
|  { | ||||
|      Init_builtin_features(); | ||||
| +    Init_abrt();
 | ||||
|      rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX")); | ||||
|  } | ||||
|   | ||||
| diff --git a/spec/ruby/core/kernel/require_spec.rb b/spec/ruby/core/kernel/require_spec.rb
 | ||||
| index 60c57d6259..1eec16f2c8 100644
 | ||||
| --- a/spec/ruby/core/kernel/require_spec.rb
 | ||||
| +++ b/spec/ruby/core/kernel/require_spec.rb
 | ||||
| @@ -25,6 +25,8 @@
 | ||||
|      out = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems --disable-did-you-mean') | ||||
|      features = out.lines.map { |line| File.basename(line.chomp, '.*') } | ||||
|   | ||||
| +    # Ignore ABRT
 | ||||
| +    features -= %w[abrt]
 | ||||
|      # Ignore CRuby internals | ||||
|      features -= %w[encdb transdb windows_1252] | ||||
|      features.reject! { |feature| feature.end_with?('-fake') } | ||||
							
								
								
									
										23
									
								
								ruby-3.3.0-Disable-syntax-suggest-test-case.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								ruby-3.3.0-Disable-syntax-suggest-test-case.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| From 6365d1b79e10330fced83d00d4cb950380a3b0fe Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com> | ||||
| Date: Thu, 7 Sep 2023 13:13:02 +0200 | ||||
| Subject: [PATCH] Disable syntax-suggest test case. | ||||
| 
 | ||||
| This requires internet connection. | ||||
| ---
 | ||||
|  common.mk | 2 -- | ||||
|  1 file changed, 2 deletions(-) | ||||
| 
 | ||||
| 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)
 | ||||
|  	$(ACTIONS_ENDGROUP) | ||||
|  no-test-syntax-suggest: | ||||
|   | ||||
| -check: $(DOT_WAIT) $(PREPARE_SYNTAX_SUGGEST) test-syntax-suggest
 | ||||
| -
 | ||||
|  test-bundler-precheck: $(TEST_RUNNABLE)-test-bundler-precheck | ||||
|  no-test-bundler-precheck: | ||||
|  yes-test-bundler-precheck: main $(arch)-fake.rb | ||||
| @ -0,0 +1,92 @@ | ||||
| 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; | ||||
|  } | ||||
							
								
								
									
										24
									
								
								ruby-3.4.0-Fix-pointer-incompatiblity.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ruby-3.4.0-Fix-pointer-incompatiblity.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| 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; | ||||
							
								
								
									
										24
									
								
								ruby-3.4.0-fix-branch-protection-compilation-for-arm.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ruby-3.4.0-fix-branch-protection-compilation-for-arm.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| 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 | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,9 +9,9 @@ module RubyGemsProv | ||||
|     def self.normalize_prerelease(version) | ||||
|       if version.prerelease? | ||||
|         prerelease = version.version.sub /^#{version.release}\./, '' | ||||
|         "#{version.release}-0.1.#{prerelease}" | ||||
|         "#{version.release}~#{prerelease}" | ||||
|       else | ||||
|         "#{version.release}-1" | ||||
|         version.release | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| @ -38,28 +38,32 @@ module RubyGemsReq | ||||
|         version == Gem::Version.new(0) ? "" : " #{op} #{version}" | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Compose dependency together with its requirements in RPM rich dependency | ||||
|     # string. | ||||
|     def self.compose_dependency_string(name, requirements) | ||||
|       dependency_strings = requirements.map { |requirement| name + requirement } | ||||
|       dependency_string = dependency_strings.join(' with ') | ||||
|       dependency_string.prepend('(').concat(')') if dependency_strings.length > 1 | ||||
|       dependency_string | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # Report RubyGems dependency, versioned if required. | ||||
|   def self.rubygems_dependency(specification) | ||||
|     Helpers::requirement_versions_to_rpm(specification.required_rubygems_version).each do |requirement| | ||||
|       dependency_string = "ruby(rubygems)" | ||||
|       dependency_string += " #{specification.required_rubygems_version}" if requirement&.length > 0 | ||||
|       puts dependency_string | ||||
|     end | ||||
|     dependency_name = "ruby(rubygems)" | ||||
|     requirements = Helpers::requirement_versions_to_rpm(specification.required_rubygems_version) | ||||
| 
 | ||||
|     puts Helpers::compose_dependency_string(dependency_name, requirements) | ||||
|   end | ||||
| 
 | ||||
|   # Report all gem dependencies including their version. | ||||
|   def self.gem_depenencies(specification) | ||||
|     specification.runtime_dependencies.each do |dependency| | ||||
|       dependency_strings = Helpers::requirement_versions_to_rpm(dependency.requirement).map do |requirement| | ||||
|         requirement_string = "rubygem(#{dependency.name})" | ||||
|         requirement_string += " #{requirement}" if requirement&.length > 0 | ||||
|         requirement_string | ||||
|       end | ||||
|       dependency_string = dependency_strings.join(' with ') | ||||
|       dependency_string.prepend('(').concat(')') if dependency_strings.length > 1 | ||||
|       puts dependency_string | ||||
|       dependency_name = "rubygem(#{dependency.name})" | ||||
|       requirements = Helpers::requirement_versions_to_rpm(dependency.requirement) | ||||
| 
 | ||||
|       puts Helpers::compose_dependency_string(dependency_name, requirements) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								sources
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								sources
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| SHA512 (ruby-3.3.1.tar.xz) = c58e9be9b5ab48191fbf7d67e13f0ec42ee71ed338170e0f7b246708e9cfc617ce65098f5ce7ab32d4305e785642d3e44253462104d5b9c4abcb1a4113f48347 | ||||
							
								
								
									
										34
									
								
								test_openssl_fips.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								test_openssl_fips.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| require 'openssl' | ||||
| 
 | ||||
| # Run openssl tests in OpenSSL FIPS. See the link below for how to test. | ||||
| # https://github.com/ruby/openssl/blob/master/.github/workflows/test.yml | ||||
| # - step name: test on fips module | ||||
| 
 | ||||
| # Listing the testing files by an array explicitly rather than the `Dir.glob` | ||||
| # to prevent the test files from not loading unintentionally. | ||||
| TEST_FILES = %w[ | ||||
|   test/openssl/test_fips.rb | ||||
|   test/openssl/test_pkey.rb | ||||
| ].freeze | ||||
| 
 | ||||
| if ARGV.empty? | ||||
|   puts 'ERROR: Argument base_dir required.' | ||||
|   puts "Usage: #{__FILE__} base_dir [options]" | ||||
|   exit false | ||||
| end | ||||
| BASE_DIR = ARGV[0] | ||||
| abs_test_files = TEST_FILES.map { |file| File.join(BASE_DIR, file) } | ||||
| 
 | ||||
| # Set Fedora/RHEL downstream OpenSSL downstream environment variable to enable | ||||
| # FIPS module in non-FIPS OS environment. It is available in Fedora 38 or later | ||||
| # versions. | ||||
| # https://src.fedoraproject.org/rpms/openssl/blob/rawhide/f/0009-Add-Kernel-FIPS-mode-flag-support.patch | ||||
| ENV['OPENSSL_FORCE_FIPS_MODE'] = '1' | ||||
| # A flag to tell the tests the current environment is FIPS enabled. | ||||
| # https://github.com/ruby/openssl/blob/master/test/openssl/test_fips.rb | ||||
| ENV['TEST_RUBY_OPENSSL_FIPS_ENABLED'] = 'true' | ||||
| 
 | ||||
| abs_test_files.each do |file| | ||||
|   puts "INFO: Loading #{file}." | ||||
|   require file | ||||
| end | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user