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:
Jean Boussier 2022-07-25 10:21:38 +02:00
Родитель fe61cad749
Коммит b0b9f7201a
4 изменённых файлов: 23 добавлений и 8 удалений

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;
}

Просмотреть файл

@ -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)