From 4ee1a687768338a1928014fc6042c320a1a1af3e Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Mon, 29 Aug 2022 15:36:29 +0200 Subject: Update to ruby/spec@d01709f --- spec/ruby/optional/capi/encoding_spec.rb | 42 +++++++++++++++++++++++++++++ spec/ruby/optional/capi/ext/encoding_spec.c | 9 +++++++ spec/ruby/optional/capi/ext/string_spec.c | 7 +++++ spec/ruby/optional/capi/ext/util_spec.c | 21 ++++++++------- spec/ruby/optional/capi/string_spec.rb | 32 ++++++++++++++++++++++ spec/ruby/optional/capi/util_spec.rb | 5 ++-- 6 files changed, 105 insertions(+), 11 deletions(-) (limited to 'spec/ruby/optional') diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb index ae557b03d7..aa632b963b 100644 --- a/spec/ruby/optional/capi/encoding_spec.rb +++ b/spec/ruby/optional/capi/encoding_spec.rb @@ -63,6 +63,48 @@ describe "C-API Encoding function" do end end + describe "rb_enc_strlen" do + before :each do + @str = 'こにちわ' # Each codepoint in this string is 3 bytes in UTF-8 + end + + it "returns the correct string length for the encoding" do + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::UTF_8).should == 4 + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::BINARY).should == 12 + end + + it "returns the string length based on a fixed-width encoding's character length, even if the encoding is incompatible" do + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::UTF_16BE).should == 6 + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::UTF_16LE).should == 6 + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::UTF_32BE).should == 3 + @s.rb_enc_strlen(@str, @str.bytesize, Encoding::UTF_32LE).should == 3 + end + + it "does not consider strings to be NUL-terminated" do + s = "abc\0def" + @s.rb_enc_strlen(s, s.bytesize, Encoding::US_ASCII).should == 7 + @s.rb_enc_strlen(s, s.bytesize, Encoding::UTF_8).should == 7 + end + + describe "handles broken strings" do + it "combines valid character and invalid character counts in UTF-8" do + # The result is 3 because `rb_enc_strlen` counts the first valid character and then adds + # the byte count for the invalid character that follows for 1 + 2. + @s.rb_enc_strlen(@str, 5, Encoding::UTF_8).should == 3 + end + + it "combines valid character and invalid character counts in UTF-16" do + @s.rb_enc_strlen(@str, 5, Encoding::UTF_16BE).should == 3 + end + + it "rounds up for fixed-width encodings" do + @s.rb_enc_strlen(@str, 7, Encoding::UTF_32BE).should == 2 + @s.rb_enc_strlen(@str, 7, Encoding::UTF_32LE).should == 2 + @s.rb_enc_strlen(@str, 5, Encoding::BINARY).should == 5 + end + end + end + describe "rb_enc_find" do it "returns the encoding of an Encoding" do @s.rb_enc_find("UTF-8").should == "UTF-8" diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c index c49f6cde7e..865fc484be 100644 --- a/spec/ruby/optional/capi/ext/encoding_spec.c +++ b/spec/ruby/optional/capi/ext/encoding_spec.c @@ -301,6 +301,14 @@ static VALUE encoding_spec_rb_enc_codelen(VALUE self, VALUE code, VALUE encoding return INT2FIX(rb_enc_codelen(c, enc)); } +static VALUE encoding_spec_rb_enc_strlen(VALUE self, VALUE str, VALUE length, VALUE encoding) { + int l = FIX2INT(length); + char *p = RSTRING_PTR(str); + char *e = p + l; + + return LONG2FIX(rb_enc_strlen(p, e, rb_to_encoding(encoding))); +} + void Init_encoding_spec(void) { VALUE cls; native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*)); @@ -335,6 +343,7 @@ void Init_encoding_spec(void) { rb_define_method(cls, "rb_enc_compatible", encoding_spec_rb_enc_compatible, 2); rb_define_method(cls, "rb_enc_copy", encoding_spec_rb_enc_copy, 2); rb_define_method(cls, "rb_enc_codelen", encoding_spec_rb_enc_codelen, 2); + rb_define_method(cls, "rb_enc_strlen", encoding_spec_rb_enc_strlen, 3); rb_define_method(cls, "rb_enc_find", encoding_spec_rb_enc_find, 1); rb_define_method(cls, "rb_enc_find_index", encoding_spec_rb_enc_find_index, 1); rb_define_method(cls, "rb_enc_isalnum", encoding_spec_rb_enc_isalnum, 2); diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c index b9a4a55853..9cbb50484d 100644 --- a/spec/ruby/optional/capi/ext/string_spec.c +++ b/spec/ruby/optional/capi/ext/string_spec.c @@ -437,6 +437,12 @@ VALUE string_spec_RSTRING_PTR_read(VALUE self, VALUE str, VALUE path) { return capacities; } +VALUE string_spec_RSTRING_PTR_null_terminate(VALUE self, VALUE str, VALUE min_length) { + char* ptr = RSTRING_PTR(str); + char* end = ptr + RSTRING_LEN(str); + return rb_str_new(end, FIX2LONG(min_length)); +} + VALUE string_spec_StringValue(VALUE self, VALUE str) { return StringValue(str); } @@ -662,6 +668,7 @@ void Init_string_spec(void) { rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2); rb_define_method(cls, "RSTRING_PTR_after_yield", string_spec_RSTRING_PTR_after_yield, 1); rb_define_method(cls, "RSTRING_PTR_read", string_spec_RSTRING_PTR_read, 2); + rb_define_method(cls, "RSTRING_PTR_null_terminate", string_spec_RSTRING_PTR_null_terminate, 2); rb_define_method(cls, "StringValue", string_spec_StringValue, 1); rb_define_method(cls, "SafeStringValue", string_spec_SafeStringValue, 1); rb_define_method(cls, "rb_str_hash", string_spec_rb_str_hash, 1); diff --git a/spec/ruby/optional/capi/ext/util_spec.c b/spec/ruby/optional/capi/ext/util_spec.c index a7269353c2..95ba71ea9d 100644 --- a/spec/ruby/optional/capi/ext/util_spec.c +++ b/spec/ruby/optional/capi/ext/util_spec.c @@ -7,15 +7,18 @@ extern "C" { #endif VALUE util_spec_rb_scan_args(VALUE self, VALUE argv, VALUE fmt, VALUE expected, VALUE acc) { - int i, result, argc = (int)RARRAY_LEN(argv); - VALUE args[6], failed, a1, a2, a3, a4, a5, a6; - - failed = rb_intern("failed"); - a1 = a2 = a3 = a4 = a5 = a6 = failed; - - for(i = 0; i < argc; i++) { - args[i] = rb_ary_entry(argv, i); - } + int result, argc; + VALUE a1, a2, a3, a4, a5, a6; + + argc = (int) RARRAY_LEN(argv); + VALUE* args = RARRAY_PTR(argv); + /* the line above can be replaced with this for Ruby implementations which do not support RARRAY_PTR() yet + VALUE args[6]; + for(int i = 0; i < argc; i++) { + args[i] = rb_ary_entry(argv, i); + } */ + + a1 = a2 = a3 = a4 = a5 = a6 = INT2FIX(-1); #ifdef RB_SCAN_ARGS_KEYWORDS if (*RSTRING_PTR(fmt) == 'k') { diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index 7ad4d10ee4..0558fc9f7d 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -97,6 +97,32 @@ describe "C-API String function" do end end + describe "rb_str_set_len on a UTF-16 String" do + before :each do + @str = "abcdefghij".force_encoding(Encoding::UTF_16BE) + # Make sure to unshare the string + @s.rb_str_modify(@str) + end + + it "inserts two NULL bytes at the length" do + @s.rb_str_set_len(@str, 4).b.should == "abcd".b + @s.rb_str_set_len(@str, 8).b.should == "abcd\x00\x00gh".b + end + end + + describe "rb_str_set_len on a UTF-32 String" do + before :each do + @str = "abcdefghijkl".force_encoding(Encoding::UTF_32BE) + # Make sure to unshare the string + @s.rb_str_modify(@str) + end + + it "inserts four NULL bytes at the length" do + @s.rb_str_set_len(@str, 4).b.should == "abcd".b + @s.rb_str_set_len(@str, 12).b.should == "abcd\x00\x00\x00\x00ijkl".b + end + end + describe "rb_str_buf_new" do it "returns the equivalent of an empty string" do buf = @s.rb_str_buf_new(10, nil) @@ -592,6 +618,12 @@ describe "C-API String function" do capacities[0].should < capacities[1] str.should == "fixture file contents to test read() with RSTRING_PTR" end + + it "terminates the string with at least (encoding min length) \\0 bytes" do + @s.RSTRING_PTR_null_terminate("abc", 1).should == "\x00" + @s.RSTRING_PTR_null_terminate("abc".encode("UTF-16BE"), 2).should == "\x00\x00" + @s.RSTRING_PTR_null_terminate("abc".encode("UTF-32BE"), 4).should == "\x00\x00\x00\x00" + end end describe "RSTRING_LEN" do diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb index 64b0894087..38f6f47b1a 100644 --- a/spec/ruby/optional/capi/util_spec.rb +++ b/spec/ruby/optional/capi/util_spec.rb @@ -15,8 +15,9 @@ describe "C-API Util function" do end it "assigns the required arguments scanned" do - @o.rb_scan_args([1, 2], "2", 2, @acc).should == 2 - ScratchPad.recorded.should == [1, 2] + obj = Object.new + @o.rb_scan_args([obj, 2], "2", 2, @acc).should == 2 + ScratchPad.recorded.should == [obj, 2] end it "raises an ArgumentError if there are insufficient arguments" do -- cgit v1.2.3