440 Commits
Author SHA1 Message Date
Nobuyoshi Nakada 9cffa03aef Substite with NIL_OR_UNDEF_P more 2026-10-11 22:40:45 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 ee3d6c987b Use rb_len_t for the lengths and indices left in long
These still held String and Array lengths and indices in long, or cast them to long. rb_len_t is still long everywhere, so the generated code does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:45:25 +09:00
Hiroshi SHIBATAandClaude Opus 5 94f16320f7 Use rb_len_t for buffer lengths in transcode.c
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Hiroshi SHIBATAandClaude Opus 5 cc3ba11012 Use rb_len_t in the C API for lengths and indices
Once rb_len_t widens this changes the `long *` output parameters of rb_range_beg_len(), rb_str_subpos(), rb_arithmetic_sequence_beg_len_step(), ruby_enc_find_basename() and ruby_enc_find_extname(), so extensions passing `long *` to them will need to be updated. The extension guides list these signatures verbatim and follow along.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Peter Zhu c914aeb622 Fix use-after-free in String#encode when string modified
[Bug #22330]

The following script demonstrates a use-afer-free where we see corruption:

    s = "あ" * 10_000
    s.encode("US-ASCII", fallback: proc { |c| s.clear; "?" })

Raises may different errors such as:

    "\xCB" followed by "\xF5" on UTF-8 (Encoding::InvalidByteSequenceError)
    "\xF4" followed by "r" on UTF-8 (Encoding::InvalidByteSequenceError)
    "\x8B" on UTF-8 (Encoding::InvalidByteSequenceError)
2026-09-18 12:11:38 +09:00
Nobuyoshi Nakada 20ca4e1f64 [Bug #22322] Take transcoder names from declared transcoders
Fix use-after-free of dangling pointers.
2026-09-16 20:27:27 +09:00
Koichi SasadaandClaude Opus 5 aa33db6903 Pass the buffer's size to ruby_xrealloc_sized, not the field distance
rb_econv_insert_output() grew the insertion buffer with

    ruby_xrealloc_sized(*buf_start_p, s, buf_end_p - buf_start_p);

The old-size argument subtracts the two local pointer variables instead
of the pointers they point at, so the allocator's size accounting gets a
small constant rather than the buffer's size.  Present since the sized
variant was introduced; the memory itself was never corrupted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 02:21:31 +09:00
Koichi SasadaandClaude Opus 5 6804addeec Keep the fallback string alive across rb_econv_insert_output
transcode_loop() passed the fallback result to rb_econv_insert_output()
as a bare pointer and length.  Nothing roots the string during that call:
args.rep still holds the pre-fallback error-bytes string, and with
clang -O3 the VALUE itself lives in no stack slot the conservative scan
can see -- only the raw data pointer survives in a register, and for an
embedded string that is an interior pointer the scanner rejects.

rb_econv_insert_output() can run a GC: when the fallback string's
encoding differs from the converter's insert encoding it calls
allocate_converted_string(), which opens a fresh econv and allocates the
destination buffer.  The fallback string is then swept mid-call and the
sub-conversion reads its freed bytes.

On an ASAN build this reports use-after-poison at the 1-byte input read
in transcode_restartable0(); CI hit it about once in two hundred runs of
test_fallback_proc, and GC.stress reproduces it in a few hundred
iterations on a clang -O3 ASAN build.  With RB_GC_GUARD the same loop is
clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 02:21:31 +09:00
Peter Zhu d85f82c194 Use rb_econv_memsize for econv_memsize
econv_memsize only counted the rb_econv_t struct, but it should use
rb_econv_memsize.
2026-08-20 07:58:20 +09:00
John HawthornandLuke Gruber daffaaee73 Mark most TypedData types as THREAD_SAFE_FREE
Set RUBY_TYPED_THREAD_SAFE_FREE on TypedData types whose dfree function
is trivially safe, and only frees its own memory

Types not yet marked as THREAD_SAFE_FREE:
- id2ref_tbl_type: sets the process-global id2ref_tbl to NULL.
- mutex_data_type: unlinks itself from another thread's keeping_mutexes list.
- autoload_data_type: deletes nodes from a shared intrusive list.
- autoload_const_type: deletes itself from a shared list.
- rb_cont_data_type: mutates the shared fiber pool and the global first_jit_cont list.
- rb_fiber_data_type: delegates to cont_free.
- FiberPoolDataType: mutates shared fiber pool free-lists.
- ractor_data_type: reconfigures global VM event-hook flags and call caches.
- exported_object_registry: frees a global table under the VM lock.
- rb_box_data_type (Box::Entry): unlinks classext from other live class and module objects.
- box_ext_cleanup_type: dereferences another String object and calls unlink.
- monitor_data_type: uses the default free, so the flag has no effect.

Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
2026-06-23 13:30:26 -07:00
Yusuke EndohandClaude Opus 4.8 810219ee58 Free the converted replacement string with its buffer size
rb_econv_close freed ec->replacement_str using replacement_len, but when
the replacement is converted to the destination encoding its allocated
size is replacement_bufsize, which can be larger. Free it with bufsize,
as rb_econv_set_replacement already does.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:41:32 +02:00
Jean Boussier 53099633e2 Make ruby_xfree_sized and ruby_xrealloc_sized public
[Feature #21861]
2026-04-01 08:10:07 +01:00
Jean Boussier 24bdf6a40e transcode.c: Use ruby_sized_xfree 2026-02-01 15:32:28 +01:00
Peter Zhu 390d77ba00 Fix memory leak in String#encode when StringValue raises
The following script leaks memory:

    10.times do
      100_000.times do
        "\ufffd".encode(Encoding::US_ASCII, fallback: proc { Object.new })
      rescue
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    450244
    887748
    1325124
    1762756
    2200260
    2637508
    3075012
    3512516
    3950020
    4387524

After:

    12236
    12364
    12748
    13004
    13388
    13516
    13772
    13772
    13772
    13772
2025-11-01 10:47:39 -04:00
Peter Zhu b8c82a99a0 Fix memory leak in String#encode when fallback too big
The following script leaks memory:

    10.times do
      100_000.times do
        "\ufffd".encode(Encoding::US_ASCII, fallback: proc { "\uffee" })
      rescue
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    451196
    889596
    1328252
    1766524
    2204668
    2643068
    3081724
    3520124
    3958524
    4396796

After:

    12800
    13056
    13184
    13312
    13312
    13312
    13312
    13312
    13312
    13312
2025-10-29 20:18:38 -04:00
Peter Zhu cb30288162 Fix memory leak of transcoding when fallback raises
When the fallback function in transcode_loop raises, it will leak the memory
in rb_econv_t. The following script reproduces the leak:

    10.times do
      100_000.times do
        "\ufffd".encode(Encoding::US_ASCII, fallback: proc { raise })
      rescue
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    451196
    889980
    1328508
    1767676
    2206460
    2645372
    3083900
    3522428
    3960956
    4399484

After:

    12508
    12636
    12892
    12892
    13148
    13404
    13532
    13788
    13916
    13916
2025-10-24 18:34:13 -04:00
Luke Gruber 9db54a1a98 Fixes to encoding/transcoding for ractors.
Not all ractor-related encoding issues were fixed by 1afc07e815.
I found more by running my test-all branch with 3 ractors for each test.
2025-08-22 10:49:44 -07:00
Luke Gruber 1afc07e815 Allow encodings to be autoloaded through transcoding functions
Make sure VM lock is not held when calling `load_transcoder_entry`, as
that causes deadlock inside ractors. `String#encode` now works inside
ractors, among others.

Atomic load the rb_encoding_list

Without this, wbcheck would sometimes hit a missing write barrier.

Co-authored-by: John Hawthorn <john.hawthorn@shopify.com>

Hold VM lock when iterating over global_enc_table.names

This st_table can be inserted into at runtime when autoloading
encodings.

minor optimization when calling Encoding.list
2025-08-12 15:19:02 -07:00
BurdetteLamar ed22e15acb [DOC] Tweak for String#encode! 2025-07-24 15:57:28 -04:00
Luke Gruber 4f4408e989 Get transcoding to work across ractors by locking certain operations
Ex: `str.encode` and `str.encode!` work across ractors now.

The global table `transcoder_table` needs a lock around each st_lookup/st_insert, and it's a two-level
table so the second level also needs to be locked around insertion/deletion. In addition to this, the
transcoder entries (values in the second-level hash table) need to be locked around retrieving them and
loading them as they are loaded lazily.

The transcoding objects (`Encoding::Converter`) can't be made shareable, so their operations don't need to be locked.
2025-07-03 13:20:34 -07:00
Soutaro Matsumoto c7a638747a Fix constant documents (#12357)
Delete duplicated `Document-const:` directives

Those directives are attached to `rb_define_const` and `rb_file_const` where we don’t need them because the functions are supported by RDoc.
2024-12-17 11:58:00 +09:00
6816e8efcf Free everything at shutdown
when the RUBY_FREE_ON_SHUTDOWN environment variable is set, manually free memory at shutdown.

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Peter Zhu <peter@peterzhu.ca>
2023-12-07 15:52:35 -05:00
Nobuyoshi Nakada 9c5b084c0a Adjust indent [ci skip] 2023-10-27 17:01:44 +09:00
Peter Zhu 58386814a7 Don't check for null pointer in calls to free
According to the C99 specification section 7.20.3.2 paragraph 2:

> If ptr is a null pointer, no action occurs.

So we do not need to check that the pointer is a null pointer.
2023-06-30 09:13:31 -04:00
Peter Zhu 1da2e7fca3 [Feature #19579] Remove !USE_RVARGC code (#7655)
Remove !USE_RVARGC code

[Feature #19579]

The Variable Width Allocation feature was turned on by default in Ruby
3.2. Since then, we haven't received bug reports or backports to the
non-Variable Width Allocation code paths, so we assume that nobody is
using it. We also don't plan on maintaining the non-Variable Width
Allocation code, so we are going to remove it.
2023-04-04 17:30:06 -04:00
Nobuyoshi Nakada 468ce1488d [DOC] Use RDoc inclusions in transcode.c 2023-01-16 13:38:58 +09:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
S-H-GAMELINKS 79f50b9d02 Using is_broken_string function 2022-09-10 09:32:51 +09:00
Jeremy Evans 6f3857f6a7 Support Encoding::Converter newline: :lf and :lf_newline options
Previously, newline: :lf was accepted but ignored.  Where it
should have been used was commented out code that didn't work,
but unlike all other invalid values, using newline: :lf did
not raise an error.

This adds support for newline: :lf and :lf_newline, for consistency
with newline: :cr and :cr_newline.  This is basically the same as
universal_newline, except that it only affects writing and not
reading due to RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK.

Add tests for the File.open :newline option while here.

Fixes [Bug #12436]
2022-08-19 20:23:36 -07:00
Nobuyoshi Nakada 725626d890 [Bug #18964] Update the code range of appended portion 2022-08-18 14:57:08 +09:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
S-H-GAMELINKS 420f3ced4d Using is_ascii_string to check encoding 2022-06-17 12:02:50 +09:00
Nobuyoshi Nakada 62c1583353 [DOC] Place a non-US-ASCII document in a document-specific script 2022-02-26 16:23:04 +09:00
Burdette Lamar 26ffda2fd2 [DOC] Enhanced RDoc for some encoding methods (#5598)
In String, treats:

    #b
    #scrub
    #scrub!
    #unicode_normalize
    #unicode_normalize!
    #encode
    #encode!

Also adds a note to IO.new (suggested by @jeremyevans).
2022-02-25 13:12:59 -06:00
S.H af10771045 Add econv_get_encoding function 2022-02-02 22:52:55 +09:00
Peter Zhu a5b6598192 [Feature #18239] Implement VWA for strings
This commit adds support for embedded strings with variable capacity and
uses Variable Width Allocation to allocate strings.
2021-10-25 13:26:23 -04:00
S.H dc9112cf10 Using NIL_P macro instead of == Qnil 2021-10-03 22:34:45 +09:00
Jeremy Evans 3f7da458a7 Make encoding loading not issue warning
Instead of relying on setting an unsetting ruby_verbose, which is
not thread-safe, restructure require_internal and load_lock to
accept a warn argument for whether to warn, and add
rb_require_internal_silent to require without warnings.  Use
rb_require_internal_silent when loading encoding.

Note this does not modify ruby_debug and errinfo handling, those
remain thread-unsafe.

Also silent requires when loading transcoders.
2021-10-02 05:51:29 -09:00
S-H-GAMELINKS 56065f0686 Using SYMBOL_P macro 2021-09-11 08:48:56 +09:00
S-H-GAMELINKS bdd6d8746f Replace RBOOL macro 2021-09-05 23:01:27 +09:00
Nobuyoshi Nakada 03e7fc895e Extracted repeatedly defined IDs 2021-07-27 15:40:27 +09:00
Nobuyoshi Nakada 537e824561 Don't redefine #rb_intern over and over again 2021-07-27 15:40:27 +09:00
Jeremy EvansandNobuyoshi Nakada e86c1f6fc5 Work around issue transcoding issue with non-ASCII compatible encodings and xml escaping
When using a non-ASCII compatible source and destination encoding
and xml escaping (the :xml option to String#encode), the resulting
string was broken, as it used the correct non-ASCII compatible
encoding, but contained data that was ASCII-compatible instead of
compatible with the string's encoding.

Work around this issue by detecting the case where both the
source and destination encoding are non-ASCII compatible, and
transcoding the source string from the non-ASCII compatible
encoding to UTF-8. The xml escaping code will correctly handle
the UTF-8 source string and the return the correctly encoded
and escaped value.

Fixes [Bug #12052]

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2021-06-26 12:32:39 -07:00
Ryuta Kamizono 33f2ff3bab Fix some typos by spell checker 2021-04-26 10:07:41 +09:00
Nobuhiro IMAI 939729dd82 fix result of example [ci skip] 2021-01-06 21:58:34 +09:00
卜部昌平 c30f03d328 Data: delete
Has been deprecated since 684bdf6171.

Matz says in [ruby-core:83954] that Data should be an alias of Object.
Because rb_cData has not been deprecated, let us deprecate the constant
to make it a C-level synonym of rb_cObject.
2020-12-22 02:51:49 +09:00
Jeremy Evans 9195310168 Update documentation for String#encode{,!} [ci skip]
These methods take keywords, not a hash.

From tjschuck (T.J. Schuck)

Fixes [Bug #17364]
2020-12-03 12:47:34 -08:00
卜部昌平 ff30358d13 RARRAY_AREF: convert into an inline function
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.
2020-08-15 12:09:26 +09:00
卜部昌平 3d636eccfc make_econv_exception: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00