Issue #19735 has been reported by nevans (Nicholas Evans).
----------------------------------------
Bug #19735: Add support for UUID version 7
https://bugs.ruby-lang.org/issues/19735
* Author: nevans (Nicholas Evans)
* Status: Open
* Priority: Normal
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Although the specification for UUIDv7 is still in draft, the UUIDv7 algorithm has been stable as the RFC progresses to completion.
Version 7 UUIDs can be very useful, because they are lexographically sortable, which can improve e.g: database index locality. See section 6.10 of the draft specification for further explanation:
https://www.ietf.org/archive/id/draft-ietf-uuidrev-rfc4122bis-06.html
```ruby
require 'random/formatter'
Random.uuid_v7 # => "0188ca50-fcc0-7881-b5c5-6d55cd8fc373"
Random.uuid_v7 # => "0188ca51-0069-7304-be2e-0c3cd908789b"
Random.uuid_v7 # => "0188ca51-04aa-7b57-a6ec-c49573412a9d"
Random.uuid_v7 # => "0188ca51-0853-7979-ae37-485460e9f4f1"
# or
prng = Random.new
prng.uuid_v7 # => "0188ca51-5e72-7950-a11d-def7ff977c98"
```
PR here: https://github.com/ruby/ruby/pull/7953
--
https://bugs.ruby-lang.org/
Issue #19720 has been reported by Eregon (Benoit Daloze).
----------------------------------------
Feature #19720: Warning for non-linear Regexps
https://bugs.ruby-lang.org/issues/19720
* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
----------------------------------------
I believe the best way to solve ReDoS is to ensure all Regexps used in the process are linear.
Using `Regexp.timeout = 5.0` or so does not really prevent ReDoS, given enough requests causing that timeout the servers will still be very unresponsive.
To this purpose, we should make it easy to identify non-linear Regexps and fix them.
I suggest we either use
1. a performance warning (enabled with `Warning[:performance] = true`, #19538) or
2. a new regexp warning category (enabled with `Warning[:regexp] = true`).
I think we should warn only once per non-linear Regexp, to avoid too many such warnings.
We could warn as soon as the Regexp is created, or on first match.
On first match might makes more sense for Ruby implementations which compile the Regexp lazily (since that is costly during startup), and also avoids warning for Regexps which are never used (which can be good or bad).
OTOH, if the warning is enabled, we could always compile the Regexp eagerly (or at least checks whether it's linear), and that would then provide a better way to guarantee that all Regexps created so far are linear.
Because warnings are easily customizable, it is also possible to e.g. `raise/abort` on such a warning, if one wants to ensure their application does not use a non-linear Regexp and so cannot be vulnerable to ReDoS:
```ruby
Warning.extend Module.new {
def warn(message, category: nil, **)
raise message if category == :regexp
super
end
}
```
A regexp warning category seems better for that as it makes it easy to filter by category, if a performance warning one would need to match the message which is less clean.
As a note, TruffleRuby already has a similar warning, as a command-line option:
```
$ truffleruby --experimental-options --warn-truffle-regex-compile-fallback -e 'Gem'
truffleruby-dev/lib/mri/rubygems/version.rb:176: warning: Regexp /\A\s*([0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?)?\s*\z/ at_start=false encoding=US-ASCII requires backtracking and will not match in linear time
truffleruby-dev/lib/mri/rubygems/requirement.rb:105: warning: Regexp /\A\s*(=|!=|>|<|>=|<=|~>)?\s*([0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?)\s*\z/ at_start=false encoding=US-ASCII requires backtracking and will not match in linear time
```
So the warning message could be like
`FILE:LINE: warning: Regexp /REGEXP/ requires backtracking and might not match in linear time and might cause ReDoS`
or more concise:
`FILE:LINE: warning: Regexp /REGEXP/ requires backtracking and might cause ReDoS`
--
https://bugs.ruby-lang.org/
Issue #19737 has been reported by unasuke (Yusuke Nakamura).
----------------------------------------
Feature #19737: Add `IO::Buffer#cat` for concat `IO::Buffer` instances
https://bugs.ruby-lang.org/issues/19737
* Author: unasuke (Yusuke Nakamura)
* Status: Open
* Priority: Normal
----------------------------------------
## motivation
In my use case, I want to concat two IO::Buffer instances. But current implementation doesn't have that way.
Then I created a patch. Opend here: TBD
## concern
I have two concerns about it.
### 1. Should we provide `IO::Buffer#+` as an alias?
In String instance, `"a" + "b"` returns `"ab",`. It feels intuitive.
So, should we provide the same way as `IO::Buffer.for("a") + IO::Buffer.for("b")`?
If `+` is provided, I naturally assume that `*` is also provided as an operator.
Should we also provide an `IO::Buffer#*` method for symmetry with the String class?
I thought the behavior of the "*" method is not obvious to me... (Is it right to just return joined buffers?)
### 2. Should it accept multiple IO::Buffer instances?
In the `cat` command, it accepts multiple inputs like this.
```
$ cat a.txt b.txt c.txt
a
b
c
```
Should `IO::Buffer#cat` accept multiple inputs too?
--
https://bugs.ruby-lang.org/
Issue #19297 has been reported by vo.x (Vit Ondruch).
----------------------------------------
Bug #19297: Don't download content from internet to execute Ruby test suite
https://bugs.ruby-lang.org/issues/19297
* Author: vo.x (Vit Ondruch)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Trying to build Ruby 3.2.0 for Fedora and execute its test suite via `make check` as we always did [1], the test suite suddenly fails (while it was working with commit:git|c5eefb7f37):
~~~
... snip ...
C-API Util function ruby_strtod
- converts a string to a double and returns the remaining string
- returns 0 and the full string if there's no numerical value
Finished in 45.737677 seconds
3827 files, 31635 examples, 177877 expectations, 0 failures, 0 errors, 0 tagged
./miniruby -I/builddir/build/BUILD/ruby-3.2.0/lib -I. -I.ext/common /builddir/build/BUILD/ruby-3.2.0/tool/runruby.rb --extout=.ext -- --disable-gems -C "/builddir/build/BUILD/ruby-3.2.0" bin/gem install --no-document \
--install-dir .bundle --conservative "bundler" "rake" "rspec:~> 3" #"ruby-prof"
ERROR: Could not find a valid gem 'bundler' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SocketError: Failed to open TCP connection to rubygems.org:443 (getaddrinfo: Temporary failure in name resolution) (https://rubygems.org/specs.4.8.gz)
ERROR: Could not find a valid gem 'rspec' (~> 3), here is why:
Unable to download data from https://rubygems.org/ - SocketError: Failed to open TCP connection to rubygems.org:443 (getaddrinfo: Temporary failure in name resolution) (https://rubygems.org/specs.4.8.gz)
make: Leaving directory '/builddir/build/BUILD/ruby-3.2.0/redhat-linux-build'
make: *** [uncommon.mk:1464: yes-test-syntax-suggest-prepare] Error 2
~~~
This is obviously due to the test suite trying to download `rspec` from the internet, while Fedora builders does not have internet access (and won't ever have for security reasons). If I am not mistaken, this is caused by commit:git|cae53842735237ccf71a13873fd0d1ae7f165582. Now
1) Can this be fixed?
2) Can the tarball be always self contained?
[1]: https://src.fedoraproject.org/rpms/ruby/blob/631163e3b8a51ed610528181aabe0d…
--
https://bugs.ruby-lang.org/
Issue #19281 has been reported by tompng (tomoya ishida).
----------------------------------------
Bug #19281: SyntaxError if first argument of command call has semicolon inside parenthesis
https://bugs.ruby-lang.org/issues/19281
* Author: tompng (tomoya ishida)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
These are syntax error
~~~ruby
p (1;2),(3),(4)
p (;),(),()
a.b (1;2),(3),(4)
a.b (;),(),()
~~~
I expect it to be syntax ok because the code below is syntax ok.
~~~ruby
p (1),(2;3),(4;5)
p (),(;),(;)
a.b (1),(2;3),(4;5)
a.b (),(;),(;)
~~~
It will be easy to traverse sexp if the sexp of first argument is same as others
~~~ruby
Ripper.sexp "p (),(),()"
# =>
[:program,
[[:command,
[:@ident, "p", [1, 0]],
[:args_add_block,
[[:paren, false], # [:paren, [[:void_stmt]]]
[:paren, [[:void_stmt]]],
[:paren, [[:void_stmt]]]],
false]]]]
Ripper.sexp "p (1),(2),(3)"
# =>
[:program,
[[:command,
[:@ident, "p", [1, 0]],
[:args_add_block,
[[:paren, [:@int, "1", [1, 3]]], # [:paren, [[:@int, "1", [1, 3]]]]
[:paren, [[:@int, "2", [1, 7]]]],
[:paren, [[:@int, "3", [1, 11]]]]],
false]]]]
~~~
--
https://bugs.ruby-lang.org/
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 #19740 has been reported by byroot (Jean Boussier).
----------------------------------------
Misc #19740: Block taking methods can't differentiate between a non-local return and a throw
https://bugs.ruby-lang.org/issues/19740
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Opening this as Misc, as at this stage I don't have a fully formed feature request.
Ref: https://github.com/ruby/ruby/commit/1a3bcf103c582b20e9ea70dfed0ee68b24243f55
Ref: https://github.com/ruby/timeout/pull/30
Ref: https://github.com/rails/rails/pull/29333
### Context
Rails has this problem in the Active Record transaction API.
The way it works is that it yields to a block, and if no error was raised the SQL transaction is committed, otherwise it's rolled back:
```ruby
User.transaction do
do_thing
end # COMMIT
```
or
```ruby
User.transaction do
raise SomeError
end # ROLLBACK
```
The problem is that there are more ways a method can be exited:
```ruby
User.transaction do
return # non-local exit
end
```
```ruby
User.transaction do
throw :something
end
```
In the case of a non-local return, we'd want to commit the transaction, but in the case of a throw, particularly since it's internally used by `Timeout.timeout` since Ruby 2.1, we'd rather consider that an error and rollback.
But as far as I'm aware, there is not way to distinguish the two cases.
```ruby
def transaction
returned = false
yield
returned = true
ensure
if $!
# error was raised
elsif returned
# no uniwnd
else
# non-local return or throw, don't know
end
end
```
I think it could be useful to have a way to access the currently thrown object, similar to `$!` for such cases, or some other way to tell what is going on.
There is some discussion going on in https://github.com/ruby/timeout/pull/30 about whether `Timeout` should throw or raise, and that may solve part of the problem, but regardless of where this leads, I think being able to check if something is being thrown would be valuable.
cc @matthewd
FYI @jeremyevans0 @Eregon
--
https://bugs.ruby-lang.org/
Issue #19436 has been reported by byroot (Jean Boussier).
----------------------------------------
Bug #19436: Call Cache for singleton methods can lead to "memory leaks"
https://bugs.ruby-lang.org/issues/19436
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Using "memory leaks" with quotes, because strictly speaking the memory isn't leaked, but it can nonetheless lead to large memory overheads.
### Minimal Reproduction
```ruby
module Foo
def bar
end
end
def call_bar(obj)
# Here the call cache we'll keep a ref on the method_entry
# which then keep a ref on the singleton_class, making that
# instance immortal until the method is called again with
# another instance.
# The reference chain is IMEMO(callcache) -> IMEMO(ment) -> ICLASS -> CLASS(singleton) -> OBJECT
obj.bar
end
obj = Object.new
obj.extend(Foo)
call_bar(obj)
id = obj.object_id
obj = nil
4.times { GC.start }
p ObjectSpace._id2ref(id)
```
### Explanation
Call caches keep a strong reference onto the "callable method entry" (CME), which itself keeps a strong reference on the called object class
and in the cache of a singleton class, it keeps a strong reference onto the `attached_object` (instance).
This means that any call site that calls a singleton method, will effectively keep a strong reference onto the last receiver.
If the method is frequently called it's not too bad, but if it's infrequently called, it's effectively a (bounded) memory leak.
And if the `attached_object` is big, the wasted memory can be very substantial.
### Practical Implications
Once relative common API impacted by this is [Rails' `extending` API](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#met…. This API allow to extend a "query result set" with a module.
These query results set can sometimes be very big, especially since they keep references to the instantiated `ActiveRecord::Base` instances etc.
### Possible Solutions
#### Only keep a weak reference to the CME
The fairly "obvious" solution is to keep a weak reference to the CME, that's what I explored in https://github.com/ruby/ruby/pull/7272, and it seems to work.
However in debug mode It does fail on an assertion during compaction, but it's isn't quite clear to me what the impact is.
Additionally, something that makes me think this would be the right solution, is that call caches already try to avoid marking the class:
```c
# vm_callinfo.h:275
struct rb_callcache {
const VALUE flags;
/* inline cache: key */
const VALUE klass; // should not mark it because klass can not be free'd
// because of this marking. When klass is collected,
// cc will be cleared (cc->klass = 0) at vm_ccs_free().
```
So it appears that the class being also marked through the CME is some kind of oversight?
#### Don't cache based on some heuristics
If the above isn't possible or too complicated, an alternative would be to not cache CMEs found in singleton classes, except if it's the the singleton class of a `Class` or `Module`.
It would make repeated calls to such methods slower, but the assumption is that it's unlikely that these CME would live very long.
#### Make `Class#attached_object` a weak reference
Alternatively we could make the `attached_object` a weak reference, which would drastically limit the amount of memory that may be leaked in such scenario.
The downside is that `Class#attached_object` was very recently exposed in Ruby 3.2.0, so it means changing its semantic a bit.
cc @peterzhu2118 @ko1
--
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 #19572 has been reported by st0012 (Stan Lo).
----------------------------------------
Feature #19572: Proposal: New TracePoint event for rescued exceptions
https://bugs.ruby-lang.org/issues/19572
* Author: st0012 (Stan Lo)
* Status: Open
* Priority: Normal
----------------------------------------
**Summary**
Support a new `rescue` event type in TracePoint. When the event is triggered, `TracePoint#rescued_exception` can be used to access the exception.
**Reason**
Currently, TracePoint supports `raise` events, which can be helpful for debugging by showing which exception occurs at which location. By adding a `rescue` event type, we can improve the developer's debugging experience by making it easier to check where an exception is rescued.
Currently, the most effective way to check where an exception is rescued involves setting a breakpoint at the exception's raised location and stepping through the code to see whether the debugger stops inside a rescue block. However, this can be a tedious process, especially in large applications with deep call stacks. By using a TracePoint event for rescue, developers can easily track exceptions as they are rescued by adding a few lines of code:
```
TracePoint.trace(:rescue) do |tp|
puts "Exception rescued: #{tp.rescued_exception} at #{tp.path}:#{tp.lineno}"
end
```
This new TracePoint event will also improve the `ruby/debug`'s [`ExceptionTracer`](https://github.com/ruby/debug/blob/master/lib/debug/tracer.rb#L150-L166) and provide users with a better debugging experience.
--
https://bugs.ruby-lang.org/