summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2020-02-13 09:34:49 +0900
committerNobuyoshi Nakada <[email protected]>2020-02-13 12:46:48 +0900
commitfce667ed08f25fa7ce43c9b07be170f341a04c4e (patch)
tree56afed76806c5c6793040de5c00f7acc72c30a59
parentb1b155ff03634ade5cc0e724529841d354d54033 (diff)
Get rid of warnings/exceptions at cleanup
After the encoding index instance variable is removed when all instance variables are removed in `obj_free`, then `rb_str_free` causes uninitialized instance variable warning and nil-to-integer conversion exception. Both cases result in object allocation during GC, and crashes.
-rw-r--r--encoding.c10
-rw-r--r--string.c1
-rw-r--r--test/ruby/test_encoding.rb3
3 files changed, 14 insertions, 0 deletions
diff --git a/encoding.c b/encoding.c
index f2e67ff508..e713b0a922 100644
--- a/encoding.c
+++ b/encoding.c
@@ -779,8 +779,18 @@ enc_get_index_str(VALUE str)
if (i == ENCODING_INLINE_MAX) {
VALUE iv;
+#if 0
iv = rb_ivar_get(str, rb_id_encoding());
i = NUM2INT(iv);
+#else
+ /*
+ * Tentatively, assume ASCII-8BIT, if encoding index instance
+ * variable is not found. This can happen when freeing after
+ * all instance variables are removed in `obj_free`.
+ */
+ iv = rb_attr_get(str, rb_id_encoding());
+ i = NIL_P(iv) ? ENCINDEX_ASCII : NUM2INT(iv);
+#endif
}
return i;
}
diff --git a/string.c b/string.c
index 3cfe3adcac..28a1b293d6 100644
--- a/string.c
+++ b/string.c
@@ -181,6 +181,7 @@ VALUE rb_cSymbol;
#define STR_HEAP_PTR(str) (RSTRING(str)->as.heap.ptr)
#define STR_HEAP_SIZE(str) ((size_t)RSTRING(str)->as.heap.aux.capa + TERM_LEN(str))
+/* TODO: include the terminator size in capa. */
#define STR_ENC_GET(str) get_encoding(str)
diff --git a/test/ruby/test_encoding.rb b/test/ruby/test_encoding.rb
index 80bed39936..6fc5c48179 100644
--- a/test/ruby/test_encoding.rb
+++ b/test/ruby/test_encoding.rb
@@ -76,6 +76,9 @@ class TestEncoding < Test::Unit::TestCase
assert_equal("0", format % 0)
assert_equal(e, format.dup.encoding)
assert_equal(e, (format*1).encoding)
+
+ assert_equal(e, (("x"*30).force_encoding(e)*1).encoding)
+ GC.start
end;
end