summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hawthorn <[email protected]>2024-10-22 19:22:37 -0700
committerJohn Hawthorn <[email protected]>2024-11-08 17:39:19 -0800
commit1f6dd9071c7994dd639d2e1cf2fe04e944173f17 (patch)
treeac3f3a64b413d7bf6b0a6aa0fb9be5d7a8cd7e0d
parent51ffef281996727c60571771cd07c1459ba58cd2 (diff)
Fix update_coderange for binary strings
Although a binary (aka ASCII-8BIT) string will never have a broken coderange, it still has to differentiate between "valid" and "7bit". On Ruby 3.4/trunk this problem is masked because we now clear the coderange more agressively in rb_str_resize, and we happened to always be strinking this string, but we should not assume that. On Ruby 3.3 this created strings where `ascii_only?` was true in cases it shouldn't be as well as other problems. Fixes [Bug #20883] Co-authored-by: Daniel Colson <[email protected]> Co-authored-by: Matthew Draper <[email protected]>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/12029
-rw-r--r--sprintf.c3
-rw-r--r--test/ruby/test_sprintf.rb8
2 files changed, 9 insertions, 2 deletions
diff --git a/sprintf.c b/sprintf.c
index f1ae282123..9290ed726c 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -247,8 +247,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
}
#define update_coderange(partial) do { \
- if (coderange != ENC_CODERANGE_BROKEN && scanned < blen \
- && rb_enc_to_index(enc) /* != ENCINDEX_ASCII_8BIT */) { \
+ if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { \
int cr = coderange; \
scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr); \
ENC_CODERANGE_SET(result, \
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index 3bd3bc793c..1c7e89c265 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -546,4 +546,12 @@ class TestSprintf < Test::Unit::TestCase
sprintf("%*s", RbConfig::LIMITS["INT_MIN"], "")
end
end
+
+ def test_binary_format_coderange
+ 1.upto(500) do |i|
+ str = sprintf("%*s".b, i, "\xe2".b)
+ refute_predicate str, :ascii_only?
+ assert_equal i, str.bytesize
+ end
+ end
end