mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
rb_str_resize: Only clear coderange on truncation
If we are expanding the string or only stripping extra capacity then coderange won't change, so clearing it is wasteful.
This commit is contained in:
parent
fe61cad749
commit
b0b9f7201a
Notes:
git
2022-08-18 17:09:28 +09:00
4 changed files with 23 additions and 8 deletions
3
file.c
3
file.c
|
@ -4090,6 +4090,9 @@ static VALUE
|
|||
str_shrink(VALUE str)
|
||||
{
|
||||
rb_str_resize(str, RSTRING_LEN(str));
|
||||
// expand_path on Windows can sometimes mutate the string
|
||||
// without clearing its coderange
|
||||
ENC_CODERANGE_CLEAR(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -937,6 +937,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
|
|||
if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
|
||||
}
|
||||
rb_str_resize(result, blen);
|
||||
// rb_str_format mutates the string without updating coderange
|
||||
ENC_CODERANGE_CLEAR(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1163,6 +1165,8 @@ ruby_vsprintf0(VALUE result, char *p, const char *fmt, va_list ap)
|
|||
buffer.value = 0;
|
||||
BSD_vfprintf(&f, fmt, ap);
|
||||
RBASIC_SET_CLASS_RAW(result, klass);
|
||||
// vfprintf mutates the string without updating coderange
|
||||
ENC_CODERANGE_CLEAR(result);
|
||||
rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
|
||||
#undef f
|
||||
}
|
||||
|
@ -1183,7 +1187,6 @@ rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
|
|||
rb_enc_associate(result, enc);
|
||||
}
|
||||
ruby_vsprintf0(result, RSTRING_PTR(result), fmt, ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
13
string.c
13
string.c
|
@ -2498,7 +2498,6 @@ rb_str_modify_expand(VALUE str, long expand)
|
|||
else if (expand > 0) {
|
||||
RESIZE_CAPA_TERM(str, len + expand, termlen);
|
||||
}
|
||||
ENC_CODERANGE_CLEAR(str);
|
||||
}
|
||||
|
||||
/* As rb_str_modify(), but don't clear coderange */
|
||||
|
@ -3073,16 +3072,16 @@ rb_str_set_len(VALUE str, long len)
|
|||
VALUE
|
||||
rb_str_resize(VALUE str, long len)
|
||||
{
|
||||
long slen;
|
||||
int independent;
|
||||
|
||||
if (len < 0) {
|
||||
rb_raise(rb_eArgError, "negative string size (or size too big)");
|
||||
}
|
||||
|
||||
independent = str_independent(str);
|
||||
ENC_CODERANGE_CLEAR(str);
|
||||
slen = RSTRING_LEN(str);
|
||||
int independent = str_independent(str);
|
||||
long slen = RSTRING_LEN(str);
|
||||
|
||||
if (slen > len && ENC_CODERANGE(str) != ENC_CODERANGE_7BIT) {
|
||||
ENC_CODERANGE_CLEAR(str);
|
||||
}
|
||||
|
||||
{
|
||||
long capa;
|
||||
|
|
|
@ -507,6 +507,16 @@ class TestSprintf < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_coderange
|
||||
format_str = "wrong constant name %s"
|
||||
interpolated_str = "\u3042"
|
||||
assert_predicate format_str, :ascii_only?
|
||||
refute_predicate interpolated_str, :ascii_only?
|
||||
|
||||
str = format_str % interpolated_str
|
||||
refute_predicate str, :ascii_only?
|
||||
end
|
||||
|
||||
def test_named_default
|
||||
h = Hash.new('world')
|
||||
assert_equal("hello world", "hello %{location}" % h)
|
||||
|
|
Loading…
Reference in a new issue