summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Marshall <[email protected]>2024-03-03 10:43:35 +0000
committerGitHub <[email protected]>2024-03-03 10:43:35 +0000
commit7e4b1f8e1935a10df3c41ee60ca0987d73281126 (patch)
tree4a03894e654e309606cbdd8dfe3fa7241be6ab03
parent93556d46203545bc2364b1c0dd1281ba098f3cc9 (diff)
[Bug #20322] Fix rb_enc_interned_str_cstr null encoding
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`.
-rw-r--r--ext/-test-/string/fstring.c4
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c2
-rw-r--r--spec/ruby/optional/capi/string_spec.rb8
-rw-r--r--string.c2
-rw-r--r--test/-ext-/string/test_fstring.rb8
5 files changed, 20 insertions, 4 deletions
diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c
index d3062224d8..71c4b7f97e 100644
--- a/ext/-test-/string/fstring.c
+++ b/ext/-test-/string/fstring.c
@@ -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
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index 070a88759b..cec3f65f45 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -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);
}
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index d9c20cf176..378bf7323f 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -1236,6 +1236,14 @@ end
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
diff --git a/string.c b/string.c
index d9182530ed..a756523c4b 100644
--- a/string.c
+++ b/string.c
@@ -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);
}
diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb
index f737c9a269..fcec6be543 100644
--- a/test/-ext-/string/test_fstring.rb
+++ b/test/-ext-/string/test_fstring.rb
@@ -20,6 +20,10 @@ class Test_String_Fstring < Test::Unit::TestCase
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'
@@ -28,6 +32,10 @@ class Test_String_Fstring < Test::Unit::TestCase
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)