Ruby 1.9.1 dropped DJGPP, Windows CE and VMS, NeXTSTEP, OpenStep and Rhapsody went in 2011, and Ruby 2.3 dropped OS/2, BeOS and Borland C. None of these names appears in RUBY_PLATFORM or host_os on a supported platform.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If the format string is modified during Array#pack (by conversion such
as to_str, to_int, etc.), it can cause an use-after-free since reading
p[-1] may be an use-after-free. We should read that byte before performing
the conversion.
The following script crashes:
fmt = "a" + " " * 1_000_000
evil = Object.new
evil.define_singleton_method(:to_str) { fmt.clear; "A" }
[evil].pack(fmt)
If the source string is modified in the block of String#unpack, it can
cause an use-after-free. For example, the following script crashes:
fmt = "A" * 1_000_000
str = "C" * 1_000_000
str.unpack(fmt) { fmt.clear }
When the string buffer is modified during the to_int call in Array#pack
with the r/R directive, it can cause an out-of-bounds write. For example,
the following script crashes:
str = "x" * 10000
obj = Object.new
obj.define_singleton_method(:to_int) do
str.clear
1
end
[obj].pack("R", buffer: str)
[Bug #22315]
The following script crashes because there is a use-after-free on the
source string during String#unpack:
s = "C" * 4000000
s.unpack("L*") { s.clear }
String#unpack will now instead raise RuntimeError with message "string modified".
* remove the temporary buffer object.
* simplify the condition under which an extra byte is required for
sign extension.
* in the case of `R`, raise an error earlier before packing for the
negative number.
The 'w' format (BER compressed integer) was allocating an empty
string with rb_str_new(0, 0) then immediately overwriting it with
the correctly-sized allocation. Remove the wasted first allocation.
~50% improvement on BER pack benchmarks.
This commit adds a new pack format command `R` and `r` for unsigned and
signed LEB128 encoding. The "r" mnemonic is because this is a
"vaRiable" length encoding scheme.
LEB128 is used in various formats including DWARF, WebAssembly, MQTT,
and Protobuf.
[Feature #21785]
Fixes a compiler warning about the function unknown_directive:
pack.c:160:1: warning: function 'unknown_directive' could be declared with attribute 'noreturn' [-Wmissing-noreturn]
s/S, i/I, l/L, and q/Q had the same code in both cases, so
combine the cases.
Alternatively, we could actually the size of the unsigned type,
but I doubt there are any platforms where the unsigned type is
a different size than the signed type.
RARRAY_AREF has been a macro for reasons. We might not be able to
change that for public APIs, but why not relax the situation internally
to make it an inline function.
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.