Skip to content

Commit b0b9f72

Browse files
committed
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.
1 parent fe61cad commit b0b9f72

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

file.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4090,6 +4090,9 @@ static VALUE
40904090
str_shrink(VALUE str)
40914091
{
40924092
rb_str_resize(str, RSTRING_LEN(str));
4093+
// expand_path on Windows can sometimes mutate the string
4094+
// without clearing its coderange
4095+
ENC_CODERANGE_CLEAR(str);
40934096
return str;
40944097
}
40954098

sprintf.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
937937
if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
938938
}
939939
rb_str_resize(result, blen);
940+
// rb_str_format mutates the string without updating coderange
941+
ENC_CODERANGE_CLEAR(result);
940942

941943
return result;
942944
}
@@ -1163,6 +1165,8 @@ ruby_vsprintf0(VALUE result, char *p, const char *fmt, va_list ap)
11631165
buffer.value = 0;
11641166
BSD_vfprintf(&f, fmt, ap);
11651167
RBASIC_SET_CLASS_RAW(result, klass);
1168+
// vfprintf mutates the string without updating coderange
1169+
ENC_CODERANGE_CLEAR(result);
11661170
rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
11671171
#undef f
11681172
}
@@ -1183,7 +1187,6 @@ rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
11831187
rb_enc_associate(result, enc);
11841188
}
11851189
ruby_vsprintf0(result, RSTRING_PTR(result), fmt, ap);
1186-
11871190
return result;
11881191
}
11891192

string.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,6 @@ rb_str_modify_expand(VALUE str, long expand)
24982498
else if (expand > 0) {
24992499
RESIZE_CAPA_TERM(str, len + expand, termlen);
25002500
}
2501-
ENC_CODERANGE_CLEAR(str);
25022501
}
25032502

25042503
/* As rb_str_modify(), but don't clear coderange */
@@ -3073,16 +3072,16 @@ rb_str_set_len(VALUE str, long len)
30733072
VALUE
30743073
rb_str_resize(VALUE str, long len)
30753074
{
3076-
long slen;
3077-
int independent;
3078-
30793075
if (len < 0) {
30803076
rb_raise(rb_eArgError, "negative string size (or size too big)");
30813077
}
30823078

3083-
independent = str_independent(str);
3084-
ENC_CODERANGE_CLEAR(str);
3085-
slen = RSTRING_LEN(str);
3079+
int independent = str_independent(str);
3080+
long slen = RSTRING_LEN(str);
3081+
3082+
if (slen > len && ENC_CODERANGE(str) != ENC_CODERANGE_7BIT) {
3083+
ENC_CODERANGE_CLEAR(str);
3084+
}
30863085

30873086
{
30883087
long capa;

test/ruby/test_sprintf.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,16 @@ def test_named_typed_enc
507507
end
508508
end
509509

510+
def test_coderange
511+
format_str = "wrong constant name %s"
512+
interpolated_str = "\u3042"
513+
assert_predicate format_str, :ascii_only?
514+
refute_predicate interpolated_str, :ascii_only?
515+
516+
str = format_str % interpolated_str
517+
refute_predicate str, :ascii_only?
518+
end
519+
510520
def test_named_default
511521
h = Hash.new('world')
512522
assert_equal("hello world", "hello %{location}" % h)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy