Issue #19230 has been reported by mame (Yusuke Endoh).
----------------------------------------
Bug #19230: The openssl backend of securerandom is no longer needed
https://bugs.ruby-lang.org/issues/19230
* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-linux]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
securerandom first checks if Random.urandom is available ([Line 77](https://github.com/ruby/securerandom/blob/5bfe7d6c163f7a8a45af8d2fc377f…), and if not available, it uses the openssl backend as a degeneration.
However, the openssl backend does not work because it internally uses Random.urandom ([Line 55](https://github.com/ruby/securerandom/blob/5bfe7d6c163f7a8a45af8d2fc377f…) to create a seed.
This issue is found by @hanachin.
```
$ ruby -ve 'def Random.urandom(*); raise; end; require "securerandom"; p SecureRandom.bytes(10)'
ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-linux]
-e:1: warning: method redefined; discarding old urandom
-e:1:in `urandom': unhandled exception
from /home/mame/local/lib/ruby/3.1.0/securerandom.rb:75:in `singleton class'
from /home/mame/local/lib/ruby/3.1.0/securerandom.rb:42:in `<module:SecureRandom>'
from /home/mame/local/lib/ruby/3.1.0/securerandom.rb:41:in `<top (required)>'
from <internal:/home/mame/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/home/mame/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from -e:1:in `<main>'
```
There has been this bug since commit:abae70d6ed63054d7d01bd6cd80c1b5b98b93ba3, which made the urandom backend as default and left the openssl backend just for degeneration. I think no one need the openssl anymore because no one has reported this bug for such a long time.
How about removing it?
```diff
diff --git a/lib/securerandom.rb b/lib/securerandom.rb
index 07ae048634..32b76a2137 100644
--- a/lib/securerandom.rb
+++ b/lib/securerandom.rb
@@ -14,7 +14,6 @@
#
# It supports the following secure random number generators:
#
-# * openssl
# * /dev/urandom
# * Win32
#
@@ -46,21 +45,6 @@ def bytes(n)
private
- def gen_random_openssl(n)
- @pid = 0 unless defined?(@pid)
- pid = $$
- unless @pid == pid
- now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
- OpenSSL::Random.random_add([now, @pid, pid].join(""), 0.0)
- seed = Random.urandom(16)
- if (seed)
- OpenSSL::Random.random_add(seed, 16)
- end
- @pid = pid
- end
- return OpenSSL::Random.random_bytes(n)
- end
-
def gen_random_urandom(n)
ret = Random.urandom(n)
unless ret
@@ -77,13 +61,7 @@ def gen_random_urandom(n)
Random.urandom(1)
alias gen_random gen_random_urandom
rescue RuntimeError
- begin
- require 'openssl'
- rescue NoMethodError
- raise NotImplementedError, "No random device"
- else
- alias gen_random gen_random_openssl
- end
+ raise NotImplementedError, "No random device"
end
public :gen_random
```
--
https://bugs.ruby-lang.org/
Issue #19325 has been reported by dsisnero (Dominic Sisneros).
----------------------------------------
Bug #19325: Windows support lacking.
https://bugs.ruby-lang.org/issues/19325
* Author: dsisnero (Dominic Sisneros)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Ruby's support on windows has always been second class. With some of the recent decisions, windows support is falling even more behind. Recent developments in mjit and yjit that exclude windows are two glaring issues that should be corrected. Googling 'percent of windows vs other operating systems' and it shows windows has a share of 76%. Ceding that users to python and other programming languages has to be one of the reasons python continues get more market share from ruby. With rust having first class windows support and threading support, is there a reason why yjit is not able to work on windows? Also, windows compiler support has matured enough and vcpkg support has evolved enough that it seems it should be possible to finally get a ruby version without having to use msys2. Even Crystal language has a version that runs on windows without needing msys2.
--
https://bugs.ruby-lang.org/
Issue #19318 has been reported by Eregon (Benoit Daloze).
----------------------------------------
Bug #19318: Float#round rounds incorrectly for some cases
https://bugs.ruby-lang.org/issues/19318
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED
----------------------------------------
This was discovered by @aardvark179.
The following spec in `spec/ruby/core/float/round_spec.rb` fails on CRuby:
```ruby
ruby_bug "", ""..."3.3" do
# These numbers are neighbouring floating point numbers round a
# precise value. They test that the rounding modes work correctly
# round that value and precision is not lost which might cause
# incorrect results.
it "does not lose precision during the rounding process" do
767573.1875850001.round(5, half: nil).should eql(767573.18759)
767573.1875850001.round(5, half: :up).should eql(767573.18759)
767573.1875850001.round(5, half: :down).should eql(767573.18759)
767573.1875850001.round(5, half: :even).should eql(767573.18759)
-767573.1875850001.round(5, half: nil).should eql(-767573.18759)
-767573.1875850001.round(5, half: :up).should eql(-767573.18759)
-767573.1875850001.round(5, half: :down).should eql(-767573.18759)
-767573.1875850001.round(5, half: :even).should eql(-767573.18759)
767573.187585.round(5, half: nil).should eql(767573.18759)
767573.187585.round(5, half: :up).should eql(767573.18759)
767573.187585.round(5, half: :down).should eql(767573.18758)
767573.187585.round(5, half: :even).should eql(767573.18758)
-767573.187585.round(5, half: nil).should eql(-767573.18759)
-767573.187585.round(5, half: :up).should eql(-767573.18759)
-767573.187585.round(5, half: :down).should eql(-767573.18758)
-767573.187585.round(5, half: :even).should eql(-767573.18758)
767573.1875849998.round(5, half: nil).should eql(767573.18758)
767573.1875849998.round(5, half: :up).should eql(767573.18758)
767573.1875849998.round(5, half: :down).should eql(767573.18758)
767573.1875849998.round(5, half: :even).should eql(767573.18758)
-767573.1875849998.round(5, half: nil).should eql(-767573.18758)
-767573.1875849998.round(5, half: :up).should eql(-767573.18758)
-767573.1875849998.round(5, half: :down).should eql(-767573.18758)
-767573.1875849998.round(5, half: :even).should eql(-767573.18758)
end
end
```
Yet this test to the best of our knowledge is correct.
This was fixed on master by @mrkn in https://github.com/ruby/ruby/pull/7023 (thanks!).
The question is should we backport this? I think yes.
--
https://bugs.ruby-lang.org/
Issue #19394 has been reported by jamescdavis (James Davis).
----------------------------------------
Bug #19394: cvars in instance of cloned class point to source class's cvars even after class_variable_set on clone
https://bugs.ruby-lang.org/issues/19394
* Author: jamescdavis (James Davis)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
This unexpected change in behavior happens between Ruby 3.0.x and 3.1.x. In Ruby >= 3.1, when a class with a cvar is cloned (or duped), the cvar in instances of the cloned class continues to point to the source class’s cvar after the clone has its cvar updated with `class_variable_set`. In Ruby < 3.1, the cloned class instance points to the updated cvar, as expected.
It seems likely that this is a bug in the [cvar cache](https://bugs.ruby-lang.org/issues/17763) introduced in Ruby 3.1.
Repro:
```rb
class Foo
@@bar = 'bar'
def print_bar
puts "#{self.class.name} (from instance): #{@@bar} #{@@bar.object_id}"
end
end
foo_bar = Foo.class_variable_get(:@@bar)
puts "Foo (class_variable_get): #{foo_bar} #{foo_bar.object_id}"
Foo.new.print_bar
FooClone = Foo.clone
FooClone.class_variable_set(:@@bar, 'bar_clone')
foo_clone_bar = FooClone.class_variable_get(:@@bar)
puts "FooClone (class_variable_get): #{foo_clone_bar} #{foo_clone_bar.object_id}"
FooClone.new.print_bar
```
Ruby 3.0.5:
```
Foo (class_variable_get): bar 60
Foo (from instance): bar 60
FooClone (class_variable_get): bar_clone 80
FooClone (from instance): bar_clone 80
```
Ruby 3.1.3, 3.2.0:
```
Foo (class_variable_get): bar 60
Foo (from instance): bar 60
FooClone (class_variable_get): bar_clone 80
FooClone (from instance): bar 60
```
Something similar happens when there are multiple clones and a cvar that the source class does not have defined is set on the clones. In this case, the cvars in instances of the clones all point to the first clone’s cvar.
Repro:
```rb
class Foo
def print_bar
puts "#{self.class.name} (from instance): #{@@bar} #{@@bar.object_id}"
end
end
Foo1 = Foo.clone
Foo2 = Foo.clone
Foo3 = Foo.clone
Foo1.class_variable_set(:@@bar, 'bar1')
Foo2.class_variable_set(:@@bar, 'bar2')
Foo3.class_variable_set(:@@bar, 'bar3')
foo1_bar = Foo1.class_variable_get(:@@bar)
foo2_bar = Foo2.class_variable_get(:@@bar)
foo3_bar = Foo3.class_variable_get(:@@bar)
puts "Foo1 (class_variable_get): #{foo1_bar} #{foo1_bar.object_id}"
puts "Foo2 (class_variable_get): #{foo2_bar} #{foo2_bar.object_id}"
puts "Foo3 (class_variable_get): #{foo3_bar} #{foo3_bar.object_id}"
Foo1.new.print_bar
Foo2.new.print_bar
Foo3.new.print_bar
```
Ruby 3.0.5:
```
Foo1 (class_variable_get): bar1 60
Foo2 (class_variable_get): bar2 80
Foo3 (class_variable_get): bar3 100
Foo1 (from instance): bar1 60
Foo2 (from instance): bar2 80
Foo3 (from instance): bar3 100
```
Ruby 3.1.3, 3.2.0:
```
Foo1 (class_variable_get): bar1 60
Foo2 (class_variable_get): bar2 80
Foo3 (class_variable_get): bar3 100
Foo1 (from instance): bar1 60
Foo2 (from instance): bar1 60
Foo3 (from instance): bar1 60
```
--
https://bugs.ruby-lang.org/
Issue #19293 has been reported by matsuda (Akira Matsuda).
----------------------------------------
Bug #19293: The new Time.new(String) API is nice... but we still need a stricter version of this
https://bugs.ruby-lang.org/issues/19293
* Author: matsuda (Akira Matsuda)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.3.0dev (2023-01-01T07:39:00Z master 542e984d82) +YJIT [arm64-darwin21]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
The Ruby 3.2 style `Time.new(String)` API works very well so far, but since the original `Time.new(Integer, Integer, Integer...)` API actually accepts String objects as its arguments, there's one ambiguous case as follows:
`Time.new('20230123') #=> 20230123-01-01 00:00:00 +0900`
Then the problem that I'm facing is that we cannot tell if `Time.new` would parse the given String as ISO8601-ish or just a year, and in order to avoid this ambiguity, we still need to somehow parse the String beforehand in our application side (like we're doing this way in Ruby on Rails https://github.com/rails/rails/blob/c49b8270/activemodel/lib/active_model/t…), then dispatch to the new `Time.new` only when the String is validated to be conforming the ISO format. Otherwise, if we just optimistically pass in given Strings to `Time.new`, we'll occasionally get a Time object with an unintended buggy value.
Therefore, it unfortunately seems that my feature request on #16005 still continues... I have to keep proposing that we need either of the following:
1. A trustworthy version of ISO8601 parser method perhaps with another name than `.new` that accepts strict ISO8601-ish String only (but with the T delimiter, I still don't know what the proper name of this format is).
2. Change `Time.new(Integer-ish, Integer-ish, Integer-ish...)` not to accept Integer-ish Strings but to accept only Integers. But I can imagine that this direction is very unlikely acceptable, due to the incompatibility.
--
https://bugs.ruby-lang.org/
Issue #19351 has been reported by hsbt (Hiroshi SHIBATA).
----------------------------------------
Bug #19351: Promote bundled gems at Ruby 3.3
https://bugs.ruby-lang.org/issues/19351
* Author: hsbt (Hiroshi SHIBATA)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
In Ruby 3.2, the default gems and bundled gems are changed only adding `syntax_suggest`. I and some committers are considering promote default gems to bundled gems again for Ruby 3.3+.
We hope to keep the current developer experience with dependency resolution and ignore the additional work like "Put gem "xxx" into your Gemfile" for developers.
### Proposal
We propose the following libraries will promote default gems to bundled gems at Ruby 3.3. They are not the dependencies of Rails and RubyGems/Bundler.
```
abbrev
getoptlong
optparse
observable
resolv
resolv-replace
rinda
un
fcntl
nkf
syslog
win32ole
```
### Additional works
I also propose to poromote rails dependencies:
```
ostruct
base64
irb
rdoc
tsort
singleton
delegate
```
and gems maintained by @kou
```
csv
strscan
fiddle
stringio
```
But if we promote them to bundled gems, many of users need to add `gem "csv"` into their Gemfile. I'm considering to avoid this situation.
Can we the specific feature of bundled gems to RubyGems or Bundler? Example, bundler have allowed list for bundled gems. So, listed gems could be require without Gemfile under the bundle exec.
--
https://bugs.ruby-lang.org/
Issue #19315 has been reported by Eregon (Benoit Daloze).
----------------------------------------
Feature #19315: Lazy substrings in CRuby
https://bugs.ruby-lang.org/issues/19315
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
----------------------------------------
CRuby should implement lazy substrings, i.e., "abcdef"[1..3] must not copy bytes.
Currently CRuby only reuse the char* if the substring is until the end of the buffer.
But it should also work wherever the substring starts and ends.
Yes, it means RSTRING_PTR() might need to allocate to \0-terminate, so be it, it's worth it.
There is already code for this (`SHARABLE_MIDDLE_SUBSTRING`), but it's disabled by default and `RSTRING_PTR()` needs to be changed to deal with this.
It seems a good idea to introduce a variant of `RSTRING_PTR` which doesn't guarantee \0-termination, so such callers can then use the existing bytes always without copy.
There are countless workarounds for this missing optimization, all not worth and all less readable:
* https://bugs.ruby-lang.org/issues/19314
* https://github.com/ruby/net-protocol/pull/14
* Manual lazy substrings which track string + index + length
* More but I don't remember all now, feel free to comment or link more urls/tickets.
--
https://bugs.ruby-lang.org/
Issue #19197 has been reported by AMomchilov (Alexander Momchilov).
----------------------------------------
Feature #19197: Add Exception#root_cause
https://bugs.ruby-lang.org/issues/19197
* Author: AMomchilov (Alexander Momchilov)
* Status: Open
* Priority: Normal
----------------------------------------
## Description
I would like to add a `#root_cause` method to `Exception`.
It returns the last exception in linked-list of causality chain, that is, the original exception (whose own `cause` is `nil`).
## Example
```ruby
e = begin
raise 'a' # This is the root cause
rescue => a
begin
raise 'b'
rescue => b
begin
raise 'c' # This is the outermost cause assigned to `e`
rescue => c
c
end
end
end
p(e) # => #<RuntimeError: c>
p(e.cause) # => #<RuntimeError: b>
p(e.cause.cause) # => #<RuntimeError: a>
p(e.cause.cause.cause) # => nil
p(e.root_cause) # => #<RuntimeError: a>
p(e.root_cause.cause) # => nil
```
# Motivation
There are some kinds of exceptions that can occur all over the place (and might be wrapped by arbitrarily many middlemen), but are attributable to a singular global cause. For example, a database outage could raise exceptions in almost every line of business logic of an app that uses ActiveRecord models.
Fundamentally, you wouldn't want an error report for every one of these lines. You'd want to look at the root cause, and bucket all SQL-connection issues into a single report, regardless of where they surface.
### Implementation
Draft PR: https://github.com/ruby/ruby/pull/6913
--
https://bugs.ruby-lang.org/