summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--encoding.c28
-rw-r--r--ext/-test-/string/depend3
-rw-r--r--ext/-test-/string/fstring.c15
-rw-r--r--internal/encoding.h3
-rw-r--r--string.c4
-rw-r--r--test/-ext-/string/test_fstring.rb16
6 files changed, 53 insertions, 16 deletions
diff --git a/encoding.c b/encoding.c
index 330be29f4b..32d5a349eb 100644
--- a/encoding.c
+++ b/encoding.c
@@ -101,8 +101,6 @@ static rb_encoding *global_enc_ascii,
#define ENCODING_NAMELEN_MAX 63
#define valid_encoding_name_p(name) ((name) && strlen(name) <= ENCODING_NAMELEN_MAX)
-#define enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
-
static const rb_data_type_t encoding_data_type = {
"encoding",
{0, 0, 0,},
@@ -207,16 +205,14 @@ rb_enc_dummy_p(rb_encoding *enc)
return ENC_DUMMY_P(enc) != 0;
}
-static int enc_autoload(rb_encoding *);
-
static int
check_encoding(rb_encoding *enc)
{
int index = rb_enc_to_index(enc);
if (rb_enc_from_index(index) != enc)
return -1;
- if (enc_autoload_p(enc)) {
- index = enc_autoload(enc);
+ if (rb_enc_autoload_p(enc)) {
+ index = rb_enc_autoload(enc);
}
return index;
}
@@ -260,7 +256,7 @@ must_encindex(int index)
rb_raise(rb_eEncodingError, "wrong encoding index %d for %s (expected %d)",
index, rb_enc_name(enc), ENC_TO_ENCINDEX(enc));
}
- if (enc_autoload_p(enc) && enc_autoload(enc) == -1) {
+ if (rb_enc_autoload_p(enc) && rb_enc_autoload(enc) == -1) {
rb_loaderror("failed to load encoding (%s)",
rb_enc_name(enc));
}
@@ -444,7 +440,7 @@ rb_enc_register(const char *name, rb_encoding *encoding)
if (STRCASECMP(name, rb_enc_name(oldenc))) {
index = enc_register(enc_table, name, encoding);
}
- else if (enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
+ else if (rb_enc_autoload_p(oldenc) || !ENC_DUMMY_P(oldenc)) {
enc_register_at(enc_table, index, name, encoding);
}
else {
@@ -834,7 +830,7 @@ load_encoding(const char *name)
else if ((idx = enc_registered(enc_table, name)) < 0) {
idx = -1;
}
- else if (enc_autoload_p(enc_table->list[idx].enc)) {
+ else if (rb_enc_autoload_p(enc_table->list[idx].enc)) {
idx = -1;
}
}
@@ -853,8 +849,8 @@ enc_autoload_body(struct enc_table *enc_table, rb_encoding *enc)
do {
if (i >= enc_table->count) return -1;
} while (enc_table->list[i].enc != base && (++i, 1));
- if (enc_autoload_p(base)) {
- if (enc_autoload(base) < 0) return -1;
+ if (rb_enc_autoload_p(base)) {
+ if (rb_enc_autoload(base) < 0) return -1;
}
i = enc->ruby_encoding_index;
enc_register_at(enc_table, i & ENC_INDEX_MASK, rb_enc_name(enc), base);
@@ -867,8 +863,8 @@ enc_autoload_body(struct enc_table *enc_table, rb_encoding *enc)
}
}
-static int
-enc_autoload(rb_encoding *enc)
+int
+rb_enc_autoload(rb_encoding *enc)
{
int i;
GLOBAL_ENC_TABLE_EVAL(enc_table, i = enc_autoload_body(enc_table, enc));
@@ -895,8 +891,8 @@ rb_enc_find_index(const char *name)
rb_raise(rb_eArgError, "encoding %s is not registered", name);
}
}
- else if (enc_autoload_p(enc)) {
- if (enc_autoload(enc) < 0) {
+ else if (rb_enc_autoload_p(enc)) {
+ if (rb_enc_autoload(enc) < 0) {
rb_warn("failed to load encoding (%s); use ASCII-8BIT instead",
name);
return 0;
@@ -1340,7 +1336,7 @@ enc_inspect(VALUE self)
"#<%"PRIsVALUE":%s%s%s>", rb_obj_class(self),
rb_enc_name(enc),
(ENC_DUMMY_P(enc) ? " (dummy)" : ""),
- enc_autoload_p(enc) ? " (autoload)" : "");
+ rb_enc_autoload_p(enc) ? " (autoload)" : "");
}
/*
diff --git a/ext/-test-/string/depend b/ext/-test-/string/depend
index 67dfd2289f..7db4465bf9 100644
--- a/ext/-test-/string/depend
+++ b/ext/-test-/string/depend
@@ -1000,6 +1000,7 @@ fstring.o: $(hdrdir)/ruby/backward/2/long_long.h
fstring.o: $(hdrdir)/ruby/backward/2/stdalign.h
fstring.o: $(hdrdir)/ruby/backward/2/stdarg.h
fstring.o: $(hdrdir)/ruby/defines.h
+fstring.o: $(hdrdir)/ruby/encoding.h
fstring.o: $(hdrdir)/ruby/intern.h
fstring.o: $(hdrdir)/ruby/internal/anyargs.h
fstring.o: $(hdrdir)/ruby/internal/arithmetic.h
@@ -1142,6 +1143,8 @@ fstring.o: $(hdrdir)/ruby/internal/variable.h
fstring.o: $(hdrdir)/ruby/internal/warning_push.h
fstring.o: $(hdrdir)/ruby/internal/xmalloc.h
fstring.o: $(hdrdir)/ruby/missing.h
+fstring.o: $(hdrdir)/ruby/onigmo.h
+fstring.o: $(hdrdir)/ruby/oniguruma.h
fstring.o: $(hdrdir)/ruby/ruby.h
fstring.o: $(hdrdir)/ruby/st.h
fstring.o: $(hdrdir)/ruby/subst.h
diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c
index 30120b42f6..2374319fe3 100644
--- a/ext/-test-/string/fstring.c
+++ b/ext/-test-/string/fstring.c
@@ -1,4 +1,5 @@
#include "ruby.h"
+#include "ruby/encoding.h"
VALUE rb_fstring(VALUE str);
@@ -8,8 +9,22 @@ bug_s_fstring(VALUE self, VALUE str)
return rb_fstring(str);
}
+VALUE
+bug_s_rb_enc_interned_str(VALUE self, VALUE encoding)
+{
+ return rb_enc_interned_str("foo", 3, RDATA(encoding)->data);
+}
+
+VALUE
+bug_s_rb_enc_str_new(VALUE self, VALUE encoding)
+{
+ return rb_enc_str_new("foo", 3, RDATA(encoding)->data);
+}
+
void
Init_string_fstring(VALUE klass)
{
rb_define_singleton_method(klass, "fstring", bug_s_fstring, 1);
+ rb_define_singleton_method(klass, "rb_enc_interned_str", bug_s_rb_enc_interned_str, 1);
+ rb_define_singleton_method(klass, "rb_enc_str_new", bug_s_rb_enc_str_new, 1);
}
diff --git a/internal/encoding.h b/internal/encoding.h
index af236daeaf..c0cf061bd4 100644
--- a/internal/encoding.h
+++ b/internal/encoding.h
@@ -12,12 +12,15 @@
#include "ruby/ruby.h" /* for ID */
#include "ruby/encoding.h" /* for rb_encoding */
+#define rb_enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
+
/* encoding.c */
ID rb_id_encoding(void);
rb_encoding *rb_enc_get_from_index(int index);
rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
int rb_encdb_replicate(const char *alias, const char *orig);
int rb_encdb_alias(const char *alias, const char *orig);
+int rb_enc_autoload(rb_encoding *enc);
int rb_encdb_dummy(const char *name);
void rb_encdb_declare(const char *name);
void rb_enc_set_base(const char *name, const char *orig);
diff --git a/string.c b/string.c
index 7605c225b9..90f6bca34f 100644
--- a/string.c
+++ b/string.c
@@ -11498,6 +11498,10 @@ 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))) {
+ rb_enc_autoload(enc);
+ }
+
struct RString fake_str;
return register_fstring(rb_setup_fake_str(&fake_str, ptr, len, enc), TRUE);
}
diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb
index 76afa30e14..9b4956ecef 100644
--- a/test/-ext-/string/test_fstring.rb
+++ b/test/-ext-/string/test_fstring.rb
@@ -12,6 +12,22 @@ class Test_String_Fstring < Test::Unit::TestCase
yield fstr
end
+ def test_rb_enc_interned_str_autoloaded_encoding
+ assert_separately([], <<~RUBY)
+ require '-test-/string'
+ assert_include(Encoding::Windows_31J.inspect, 'autoload')
+ Bug::String.rb_enc_interned_str(Encoding::Windows_31J)
+ RUBY
+ end
+
+ def test_rb_enc_str_new_autoloaded_encoding
+ assert_separately([], <<~RUBY)
+ require '-test-/string'
+ assert_include(Encoding::Windows_31J.inspect, 'autoload')
+ Bug::String.rb_enc_str_new(Encoding::Windows_31J)
+ RUBY
+ end
+
def test_instance_variable
str = __method__.to_s * 3
str.instance_variable_set(:@test, 42)