ruby-changes:66310
From: nagachika <ko1@a...>
Date: Sun, 23 May 2021 16:09:49 +0900 (JST)
Subject: [ruby-changes:66310] 5af5ea7f86 (ruby_3_0): merge revision(s) cfd162d535c7a4f8b1f95255cc6be696a8b75557: [Backport #17467]
https://git.ruby-lang.org/ruby.git/commit/?id=5af5ea7f86 From 5af5ea7f860ed64062796e54e73274e7a56c7280 Mon Sep 17 00:00:00 2001 From: nagachika <nagachika@r...> Date: Sun, 23 May 2021 16:09:17 +0900 Subject: merge revision(s) cfd162d535c7a4f8b1f95255cc6be696a8b75557: [Backport #17467] Make String#{strip,lstrip}{,!} strip leading NUL bytes The documentation already specifies that they strip whitespace and defines whitespace to include null. This wraps the new behavior in the appropriate guards in the specs, but does not specify behavior for previous versions, because this is a bug that could be backported. Fixes [Bug #17467] --- spec/ruby/core/string/lstrip_spec.rb | 18 ++++++++++++------ spec/ruby/core/string/strip_spec.rb | 22 ++++++++++------------ string.c | 4 ++-- test/ruby/test_string.rb | 16 ++++++++++++++++ 4 files changed, 40 insertions(+), 20 deletions(-) --- spec/ruby/core/string/lstrip_spec.rb | 18 ++++++++++++------ spec/ruby/core/string/strip_spec.rb | 22 ++++++++++------------ string.c | 4 ++-- test/ruby/test_string.rb | 16 ++++++++++++++++ version.h | 2 +- 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/spec/ruby/core/string/lstrip_spec.rb b/spec/ruby/core/string/lstrip_spec.rb index 12c7b13..6b40189 100644 --- a/spec/ruby/core/string/lstrip_spec.rb +++ b/spec/ruby/core/string/lstrip_spec.rb @@ -7,11 +7,13 @@ describe "String#lstrip" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/lstrip_spec.rb#L7 " hello world ".lstrip.should == "hello world " "\n\r\t\n\v\r hello world ".lstrip.should == "hello world " "hello".lstrip.should == "hello" - "\000 \000hello\000 \000".lstrip.should == "\000 \000hello\000 \000" end - it "does not strip leading \\0" do - "\x00hello".lstrip.should == "\x00hello" + ruby_version_is '3.1' do + it "strips leading \\0" do + "\x00hello".lstrip.should == "hello" + "\000 \000hello\000 \000".lstrip.should == "hello\000 \000" + end end ruby_version_is ''...'2.7' do @@ -28,10 +30,14 @@ describe "String#lstrip!" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/lstrip_spec.rb#L30 a = " hello " a.lstrip!.should equal(a) a.should == "hello " + end - a = "\000 \000hello\000 \000" - a.lstrip! - a.should == "\000 \000hello\000 \000" + ruby_version_is '3.1' do + it "strips leading \\0" do + a = "\000 \000hello\000 \000" + a.lstrip! + a.should == "hello\000 \000" + end end it "returns nil if no modifications were made" do diff --git a/spec/ruby/core/string/strip_spec.rb b/spec/ruby/core/string/strip_spec.rb index 252d4a9..463a9fe 100644 --- a/spec/ruby/core/string/strip_spec.rb +++ b/spec/ruby/core/string/strip_spec.rb @@ -6,11 +6,12 @@ describe "String#strip" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/strip_spec.rb#L6 " hello ".strip.should == "hello" " hello world ".strip.should == "hello world" "\tgoodbye\r\v\n".strip.should == "goodbye" - "\x00 goodbye \x00".strip.should == "\x00 goodbye" end - it "returns a copy of self with trailing NULL bytes and whitespace" do - " \x00 goodbye \x00 ".strip.should == "\x00 goodbye" + ruby_version_is '3.1' do + it "returns a copy of self without leading and trailing NULL bytes and whitespace" do + " \x00 goodbye \x00 ".strip.should == "goodbye" + end end ruby_version_is ''...'2.7' do @@ -31,11 +32,6 @@ describe "String#strip!" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/strip_spec.rb#L32 a = "\tgoodbye\r\v\n" a.strip! a.should == "goodbye" - - a = "\000 goodbye \000" - a.strip! - a.should == "\000 goodbye" - end it "returns nil if no modifications where made" do @@ -44,10 +40,12 @@ describe "String#strip!" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/string/strip_spec.rb#L40 a.should == "hello" end - it "modifies self removing trailing NULL bytes and whitespace" do - a = " \x00 goodbye \x00 " - a.strip! - a.should == "\x00 goodbye" + ruby_version_is '3.1' do + it "removes leading and trailing NULL bytes and whitespace" do + a = "\000 goodbye \000" + a.strip! + a.should == "goodbye" + end end it "raises a FrozenError on a frozen instance that is modified" do diff --git a/string.c b/string.c index 8285057..c2919ab 100644 --- a/string.c +++ b/string.c @@ -9265,14 +9265,14 @@ lstrip_offset(VALUE str, const char *s, const char *e, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/string.c#L9265 /* remove spaces at head */ if (single_byte_optimizable(str)) { - while (s < e && ascii_isspace(*s)) s++; + while (s < e && (*s == '\0' || ascii_isspace(*s))) s++; } else { while (s < e) { int n; unsigned int cc = rb_enc_codepoint_len(s, e, &n, enc); - if (!rb_isspace(cc)) break; + if (cc && !rb_isspace(cc)) break; s += n; } } diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 4814872..29ad98b 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -1852,6 +1852,7 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L1852 def test_strip assert_equal(S("x"), S(" x ").strip) assert_equal(S("x"), S(" \n\r\t x \t\r\n\n ").strip) + assert_equal(S("x"), S("\x00x\x00").strip) assert_equal("0b0 ".force_encoding("UTF-16BE"), "\x00 0b0 ".force_encoding("UTF-16BE").strip) @@ -1870,6 +1871,10 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L1871 assert_equal(S("x"), a.strip!) assert_equal(S("x"), a) + a = S("\x00x\x00") + assert_equal(S("x"), a.strip!) + assert_equal(S("x"), a) + a = S("x") assert_nil(a.strip!) assert_equal(S("x") ,a) @@ -2703,6 +2708,7 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2708 def test_rstrip assert_equal(" hello", " hello ".rstrip) assert_equal("\u3042", "\u3042 ".rstrip) + assert_equal("\u3042", "\u3042\u0000".rstrip) assert_raise(Encoding::CompatibilityError) { "\u3042".encode("ISO-2022-JP").rstrip } end @@ -2723,12 +2729,17 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2729 assert_equal(nil, s4.rstrip!) assert_equal("\u3042", s4) + s5 = S("\u3042\u0000") + assert_equal("\u3042", s5.rstrip!) + assert_equal("\u3042", s5) + assert_raise(Encoding::CompatibilityError) { "\u3042".encode("ISO-2022-JP").rstrip! } end def test_lstrip assert_equal("hello ", " hello ".lstrip) assert_equal("\u3042", " \u3042".lstrip) + assert_equal("hello ", "\x00hello ".lstrip) end def test_lstrip_bang @@ -2747,6 +2758,11 @@ CODE https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2758 s4 = S("\u3042") assert_equal(nil, s4.lstrip!) assert_equal("\u3042", s4) + + s5 = S("\u0000\u3042") + assert_equal("\u3042", s5.lstrip!) + assert_equal("\u3042", s5) + end def test_delete_prefix diff --git a/version.h b/version.h index de064cc..4496d69 100644 --- a/version.h +++ b/version.h @@ -12,7 +12,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L12 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 87 +#define RUBY_PATCHLEVEL 88 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 5 -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/