mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 08:25:20 +08:00
[Bug #22461] Fix dangling pointers after associating encoding
`rb_enc_associate` may re-allocate the string buffer because of the terminator length change.
This commit is contained in:
2 files changed
+28
-5
Notes:
git
2026-10-22 02:58:06 +00:00
No files matched your search
@@ -234,6 +234,18 @@ rb_f_sprintf(int argc, const VALUE *argv)
|
||||
return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
|
||||
}
|
||||
|
||||
static char *
|
||||
reassoc_enc(VALUE result, rb_encoding *enc)
|
||||
{
|
||||
return RSTRING_PTR(rb_enc_associate(result, enc));
|
||||
}
|
||||
|
||||
static char *
|
||||
reassoc_enc_index(VALUE result, int encidx)
|
||||
{
|
||||
return RSTRING_PTR(rb_enc_associate_index(result, encidx));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
||||
{
|
||||
@@ -295,8 +307,7 @@ rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
||||
blen = 0;
|
||||
bsiz = 120;
|
||||
result = rb_str_buf_new(bsiz);
|
||||
rb_enc_associate(result, enc);
|
||||
buf = RSTRING_PTR(result);
|
||||
buf = reassoc_enc(result, enc);
|
||||
memset(buf, 0, bsiz);
|
||||
ENC_CODERANGE_SET(result, coderange);
|
||||
|
||||
@@ -487,7 +498,7 @@ rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
||||
}
|
||||
if (encidx >= 0 && encidx != rb_enc_to_index(enc)) {
|
||||
/* special case */
|
||||
rb_enc_associate_index(result, encidx);
|
||||
buf = reassoc_enc_index(result, encidx);
|
||||
enc = rb_enc_from_index(encidx);
|
||||
coderange = ENC_CODERANGE_VALID;
|
||||
}
|
||||
@@ -550,13 +561,13 @@ rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
||||
if (flags&FMINUS) {
|
||||
FILL_(' ', width);
|
||||
}
|
||||
rb_enc_associate(result, enc);
|
||||
buf = reassoc_enc(result, enc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
PUSH(RSTRING_PTR(str), len);
|
||||
RB_GC_GUARD(str);
|
||||
rb_enc_associate(result, enc);
|
||||
buf = reassoc_enc(result, enc);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -574,4 +574,16 @@ class TestSprintf < Test::Unit::TestCase
|
||||
assert_equal i, str.bytesize
|
||||
end
|
||||
end
|
||||
|
||||
def test_dangling_pointer_after_encoding_set
|
||||
str = "\u0141" * 61
|
||||
wide_encodings = [
|
||||
Encoding::UTF_16BE, Encoding::UTF_16LE,
|
||||
Encoding::UTF_32BE, Encoding::UTF_32LE,
|
||||
]
|
||||
all_assertions_foreach(nil, *wide_encodings) do |enc|
|
||||
s = str.encode(enc)
|
||||
assert_equal(s, ("%s" % s), enc.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user