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));
|
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
|
VALUE
|
||||||
rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
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;
|
blen = 0;
|
||||||
bsiz = 120;
|
bsiz = 120;
|
||||||
result = rb_str_buf_new(bsiz);
|
result = rb_str_buf_new(bsiz);
|
||||||
rb_enc_associate(result, enc);
|
buf = reassoc_enc(result, enc);
|
||||||
buf = RSTRING_PTR(result);
|
|
||||||
memset(buf, 0, bsiz);
|
memset(buf, 0, bsiz);
|
||||||
ENC_CODERANGE_SET(result, coderange);
|
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)) {
|
if (encidx >= 0 && encidx != rb_enc_to_index(enc)) {
|
||||||
/* special case */
|
/* special case */
|
||||||
rb_enc_associate_index(result, encidx);
|
buf = reassoc_enc_index(result, encidx);
|
||||||
enc = rb_enc_from_index(encidx);
|
enc = rb_enc_from_index(encidx);
|
||||||
coderange = ENC_CODERANGE_VALID;
|
coderange = ENC_CODERANGE_VALID;
|
||||||
}
|
}
|
||||||
@@ -550,13 +561,13 @@ rb_str_format_ary(int argc, const VALUE *argv, VALUE fmt, VALUE ary)
|
|||||||
if (flags&FMINUS) {
|
if (flags&FMINUS) {
|
||||||
FILL_(' ', width);
|
FILL_(' ', width);
|
||||||
}
|
}
|
||||||
rb_enc_associate(result, enc);
|
buf = reassoc_enc(result, enc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PUSH(RSTRING_PTR(str), len);
|
PUSH(RSTRING_PTR(str), len);
|
||||||
RB_GC_GUARD(str);
|
RB_GC_GUARD(str);
|
||||||
rb_enc_associate(result, enc);
|
buf = reassoc_enc(result, enc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -574,4 +574,16 @@ class TestSprintf < Test::Unit::TestCase
|
|||||||
assert_equal i, str.bytesize
|
assert_equal i, str.bytesize
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
Reference in new issue
Block a user