mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
merge revision(s) 7e8a9af9db
: [Backport #17732]
rb_enc_interned_str: handle autoloaded encodings If called with an autoloaded encoding that was not yet initialized, `rb_enc_interned_str` would crash with a NULL pointer exception. See: https://github.com/ruby/ruby/pull/4119#issuecomment-800189841 --- encoding.c | 28 ++++++++++++---------------- ext/-test-/string/depend | 3 +++ ext/-test-/string/fstring.c | 15 +++++++++++++++ internal/encoding.h | 3 +++ string.c | 4 ++++ test/-ext-/string/test_fstring.rb | 16 ++++++++++++++++ 6 files changed, 53 insertions(+), 16 deletions(-)
This commit is contained in:
parent
855401da49
commit
4e2738f477
7 changed files with 54 additions and 17 deletions
28
encoding.c
28
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)" : "");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
4
string.c
4
string.c
|
@ -11505,6 +11505,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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||
#define RUBY_VERSION_TEENY 0
|
||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||
#define RUBY_PATCHLEVEL 60
|
||||
#define RUBY_PATCHLEVEL 61
|
||||
|
||||
#define RUBY_RELEASE_YEAR 2021
|
||||
#define RUBY_RELEASE_MONTH 4
|
||||
|
|
Loading…
Reference in a new issue