Negating INT_MIN overflows, so the compiler may drop the `width < 0` check that follows it. clang-cl does so, and `sprintf("%*s", INT_MIN, "")` does not raise ArgumentError.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BSD_vfprintf takes the length of a PRIsVALUE field as a long, which is narrower than a String length on mswin once rb_len_t widens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The %"PRIsVALUE" hook of BSD_vfprintf still returns the length as `long`, so it raises ArgumentError for a longer string once rb_len_t widens.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
If the array object passed into String#% is modified during conversion
(such as via to_s, to_i, to_f, etc.) then it can be a use-after-free if
the buffer of the array is freed.
This commit changes it to detect if the buffer has been changed and raises
an error when that happens.
The following script reproduces the crash:
count = 1_000
obj = Object.new
ary = [obj, *Array.new(count - 1) { "x" }]
obj.define_singleton_method(:to_s) do
ary.replace([])
"X"
end
str = "%s" * count
puts (str % ary).length
[Feature #22136]
This is as far as I can tell the only method that changes its behavior
in debug mode, and that's all but helpful because it might cause
the program to abort.
Usually when you run a program with $DEBUG set, it is to find some
error that may have been swallowed, so aside from the extra output
you would expect Ruby to behave the same than in normal mode.
Reject ASCII-incompatible result encodings, and avoid associating such
encodings from `PRIsVALUE` arguments; convert them to the existing
result encoding instead.
Initialize `c` and `encidx` to 0. They are assigned inside
`if (n >= 0)` and the following `if (n <= 0)` calls rb_raise, but the
compiler cannot see through the noreturn guarantee.
Although a binary (aka ASCII-8BIT) string will never have a broken
coderange, it still has to differentiate between "valid" and "7bit".
On Ruby 3.4/trunk this problem is masked because we now clear the
coderange more agressively in rb_str_resize, and we happened to always
be strinking this string, but we should not assume that.
On Ruby 3.3 this created strings where `ascii_only?` was true in cases
it shouldn't be as well as other problems.
Fixes [Bug #20883]
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
Co-authored-by: Matthew Draper <matthew@trebex.net>
[Bug #20593]
It's fairly common to use `format` to interpolate a number of values
into a user provided strings.
The arguments not matching are a problem when they are positional,
but when they are named, it's absolutely fine and we shouldn't
emit a warning.
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead. This would significantly
speed up incremental builds.
We take the following inclusion order in this changeset:
1. "ruby/config.h", where _GNU_SOURCE is defined (must be the very
first thing among everything).
2. RUBY_EXTCONF_H if any.
3. Standard C headers, sorted alphabetically.
4. Other system headers, maybe guarded by #ifdef
5. Everything else, sorted alphabetically.
Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
This removes the related tests, and puts the related specs behind
version guards. This affects all code in lib, including some
libraries that may want to support older versions of Ruby.
* sprintf.c (ruby_do_vsnprintf): pathologically, get rid of
negative value when the result length exceeds INT_MAX.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62328 b2dd03c8-39d4-4d8f-98ff-823fe69b080e