Skip to content

Commit

Permalink
[Bug #20322] Fix rb_enc_interned_str_cstr null encoding
Browse files Browse the repository at this point in the history
The documentation for `rb_enc_interned_str_cstr` notes that `enc` can be
a null pointer, but this currently causes a segmentation fault when
trying to autoload the encoding. This commit fixes the issue by checking
for NULL before calling `rb_enc_autoload`.
  • Loading branch information
thomasmarshall committed Mar 3, 2024
1 parent 93556d4 commit 7e4b1f8
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 4 deletions.
4 changes: 2 additions & 2 deletions ext/-test-/string/fstring.c
Expand Up @@ -19,13 +19,13 @@ bug_s_fstring_fake_str(VALUE self)
VALUE
bug_s_rb_enc_interned_str(VALUE self, VALUE encoding)
{
return rb_enc_interned_str("foo", 3, RDATA(encoding)->data);
return rb_enc_interned_str("foo", 3, NIL_P(encoding) ? NULL : RDATA(encoding)->data);
}

VALUE
bug_s_rb_enc_str_new(VALUE self, VALUE encoding)
{
return rb_enc_str_new("foo", 3, RDATA(encoding)->data);
return rb_enc_str_new("foo", 3, NIL_P(encoding) ? NULL : RDATA(encoding)->data);
}

void
Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/optional/capi/ext/string_spec.c
Expand Up @@ -573,7 +573,7 @@ static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
}

static VALUE string_spec_rb_enc_interned_str_cstr(VALUE self, VALUE str, VALUE enc) {
rb_encoding *e = rb_to_encoding(enc);
rb_encoding *e = NIL_P(enc) ? 0 : rb_to_encoding(enc);
return rb_enc_interned_str_cstr(RSTRING_PTR(str), e);
}

Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/optional/capi/string_spec.rb
Expand Up @@ -1236,6 +1236,14 @@ def inspect
it "returns the same string as String#-@" do
@s.rb_enc_interned_str_cstr("hello", Encoding::UTF_8).should.equal?(-"hello")
end

ruby_bug "#20322", ""..."3.4" do
it "uses the default encoding if encoding is null" do
str = "hello"
val = @s.rb_enc_interned_str_cstr(str, nil)
val.encoding.should == Encoding::ASCII_8BIT
end
end
end

describe "rb_str_to_interned_str" do
Expand Down
2 changes: 1 addition & 1 deletion string.c
Expand Up @@ -12122,7 +12122,7 @@ rb_interned_str_cstr(const char *ptr)
VALUE
rb_enc_interned_str(const char *ptr, long len, rb_encoding *enc)
{
if (UNLIKELY(rb_enc_autoload_p(enc))) {
if (enc != NULL && UNLIKELY(rb_enc_autoload_p(enc))) {
rb_enc_autoload(enc);
}

Expand Down
8 changes: 8 additions & 0 deletions test/-ext-/string/test_fstring.rb
Expand Up @@ -20,6 +20,10 @@ def test_rb_enc_interned_str_autoloaded_encoding
RUBY
end

def test_rb_enc_interned_str_null_encoding
assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_interned_str(nil).encoding
end

def test_rb_enc_str_new_autoloaded_encoding
assert_separately([], <<~RUBY)
require '-test-/string'
Expand All @@ -28,6 +32,10 @@ def test_rb_enc_str_new_autoloaded_encoding
RUBY
end

def test_rb_enc_str_new_null_encoding
assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_str_new(nil).encoding
end

def test_instance_variable
str = __method__.to_s * 3
str.instance_variable_set(:@test, 42)
Expand Down

0 comments on commit 7e4b1f8

Please sign in to comment.