[前][次][番号順一覧][スレッド一覧]

ruby-changes:72958

From: Jean <ko1@a...>
Date: Thu, 18 Aug 2022 17:09:18 +0900 (JST)
Subject: [ruby-changes:72958] b0b9f7201a (master): rb_str_resize: Only clear coderange on truncation

https://git.ruby-lang.org/ruby.git/commit/?id=b0b9f7201a

From b0b9f7201acab05c2a3ad92c3043a1f01df3e17f Mon Sep 17 00:00:00 2001
From: Jean Boussier <jean.boussier@g...>
Date: Mon, 25 Jul 2022 10:21:38 +0200
Subject: 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.
---
 file.c                    |  3 +++
 sprintf.c                 |  5 ++++-
 string.c                  | 13 ++++++-------
 test/ruby/test_sprintf.rb | 10 ++++++++++
 4 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/file.c b/file.c
index 5265d3a3a5..92338bb754 100644
--- a/file.c
+++ b/file.c
@@ -4090,6 +4090,9 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/file.c#L4090
 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;
 }
 
diff --git a/sprintf.c b/sprintf.c
index 2b2b34b5b4..1ee293b6d9 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -937,6 +937,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/sprintf.c#L937
         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) https://github.com/ruby/ruby/blob/trunk/sprintf.c#L1165
     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) https://github.com/ruby/ruby/blob/trunk/sprintf.c#L1187
         rb_enc_associate(result, enc);
     }
     ruby_vsprintf0(result, RSTRING_PTR(result), fmt, ap);
-
     return result;
 }
 
diff --git a/string.c b/string.c
index e74783cf92..6f211b2005 100644
--- a/string.c
+++ b/string.c
@@ -2498,7 +2498,6 @@ rb_str_modify_expand(VALUE str, long expand) https://github.com/ruby/ruby/blob/trunk/string.c#L2498
     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) https://github.com/ruby/ruby/blob/trunk/string.c#L3072
 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;
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index f2e73eb58d..b05f4f3e44 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -507,6 +507,16 @@ class TestSprintf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_sprintf.rb#L507
     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)
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]