From 012691279d213f249c167fd5af5850ac5e91a54e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 26 May 2026 23:10:45 +0900 Subject: [PATCH] mruby-string-ext: skip scrub UTF-8 assertions on non-UTF-8 builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When MRB_UTF8_STRING is undefined, String#scrub is a no-op that returns the receiver as-is (the #else branch added in ccb62ceb57). The unit tests assumed UTF-8 semantics unconditionally, so a build of just mruby-string-ext without UTF-8 strings failed all five scrub tests. Guard the UTF-8-dependent assertions with `skip unless "あ".length == 1`, and add a paired test that asserts the no-op behaviour on the non-UTF-8 build (skipped on UTF-8 builds). Verified against the build config from the report: - UTF-8 (host-debug): 5 tests pass, 1 skip - non-UTF-8 (noutf8): 5 skip, 1 test pass Closes #6860. Co-authored-by: Claude --- mrbgems/mruby-string-ext/test/string.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index c76a7ef15..c0fd381db 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -793,6 +793,9 @@ assert('String#-@') do end assert('String#scrub default replacement (U+FFFD)') do + # scrub has UTF-8 semantics; on builds without MRB_UTF8_STRING it + # degrades to a no-op (verified separately below). + skip unless "あ".length == 1 assert_equal "\u{FFFD}", "\xE3\x81".scrub assert_equal "abc\u{FFFD}def", "abc\x80def".scrub assert_equal "\u{FFFD}", "\x80\x81\x82".scrub # run collapsed @@ -802,6 +805,7 @@ assert('String#scrub default replacement (U+FFFD)') do end assert('String#scrub rejects malformed sequences') do + skip unless "あ".length == 1 # overlong, UTF-16 surrogate, codepoint above U+10FFFF assert_equal "\u{FFFD}", "\xC0\xAF".scrub # overlong "/" assert_equal "\u{FFFD}", "\xED\xA0\x80".scrub # surrogate U+D800 @@ -809,16 +813,19 @@ assert('String#scrub rejects malformed sequences') do end assert('String#scrub with replacement string') do + skip unless "あ".length == 1 assert_equal "abc?def", "abc\x80def".scrub("?") assert_equal "abcdef", "abc\x80def".scrub("") assert_equal "abcdef", "abc\x80def".scrub("") end assert('String#scrub raises on invalid replacement') do + skip unless "あ".length == 1 assert_raise(ArgumentError) { "abc\x80".scrub("\xFF") } end assert('String#scrub with block') do + skip unless "あ".length == 1 assert_equal "abc<80>def", "abc\x80def".scrub { |b| "<" + b.bytes.first.to_s(16) + ">" } # Block not called when string is already valid @@ -833,3 +840,11 @@ assert('String#scrub with block') do # explicit and doesn't drift accidentally. assert_equal "abc42def", "abc\x80def".scrub { 42 } end + +assert('String#scrub is a no-op without MRB_UTF8_STRING') do + skip if "あ".length == 1 + # Method is still defined and returns a (string-equal) copy. + assert_equal "abc\x80def", "abc\x80def".scrub + assert_equal "abc\x80def", "abc\x80def".scrub("?") + assert_equal "abc\x80def", "abc\x80def".scrub { |_| "?" } +end