Skip to content

Commit 41eaa06

Browse files
committed
Add specs for correct null termination with encoding min length \0 bytes
1 parent 6e38470 commit 41eaa06

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

spec/ruby/optional/capi/ext/string_spec.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ VALUE string_spec_RSTRING_PTR_read(VALUE self, VALUE str, VALUE path) {
437437
return capacities;
438438
}
439439

440+
VALUE string_spec_RSTRING_PTR_null_terminate(VALUE self, VALUE str, VALUE min_length) {
441+
char* ptr = RSTRING_PTR(str);
442+
char* end = ptr + RSTRING_LEN(str);
443+
return rb_str_new(end, FIX2LONG(min_length));
444+
}
445+
440446
VALUE string_spec_StringValue(VALUE self, VALUE str) {
441447
return StringValue(str);
442448
}
@@ -662,6 +668,7 @@ void Init_string_spec(void) {
662668
rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2);
663669
rb_define_method(cls, "RSTRING_PTR_after_yield", string_spec_RSTRING_PTR_after_yield, 1);
664670
rb_define_method(cls, "RSTRING_PTR_read", string_spec_RSTRING_PTR_read, 2);
671+
rb_define_method(cls, "RSTRING_PTR_null_terminate", string_spec_RSTRING_PTR_null_terminate, 2);
665672
rb_define_method(cls, "StringValue", string_spec_StringValue, 1);
666673
rb_define_method(cls, "SafeStringValue", string_spec_SafeStringValue, 1);
667674
rb_define_method(cls, "rb_str_hash", string_spec_rb_str_hash, 1);

spec/ruby/optional/capi/string_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ def inspect
9797
end
9898
end
9999

100+
describe "rb_str_set_len on a UTF-16 String" do
101+
before :each do
102+
@str = "abcdefghij".force_encoding(Encoding::UTF_16BE)
103+
# Make sure to unshare the string
104+
@s.rb_str_modify(@str)
105+
end
106+
107+
it "inserts two NULL bytes at the length" do
108+
@s.rb_str_set_len(@str, 4).b.should == "abcd".b
109+
@s.rb_str_set_len(@str, 8).b.should == "abcd\x00\x00gh".b
110+
end
111+
end
112+
113+
describe "rb_str_set_len on a UTF-32 String" do
114+
before :each do
115+
@str = "abcdefghijkl".force_encoding(Encoding::UTF_32BE)
116+
# Make sure to unshare the string
117+
@s.rb_str_modify(@str)
118+
end
119+
120+
it "inserts four NULL bytes at the length" do
121+
@s.rb_str_set_len(@str, 4).b.should == "abcd".b
122+
@s.rb_str_set_len(@str, 12).b.should == "abcd\x00\x00\x00\x00ijkl".b
123+
end
124+
end
125+
100126
describe "rb_str_buf_new" do
101127
it "returns the equivalent of an empty string" do
102128
buf = @s.rb_str_buf_new(10, nil)
@@ -592,6 +618,12 @@ def inspect
592618
capacities[0].should < capacities[1]
593619
str.should == "fixture file contents to test read() with RSTRING_PTR"
594620
end
621+
622+
it "terminates the string with at least (encoding min length) \\0 bytes" do
623+
@s.RSTRING_PTR_null_terminate("abc", 1).should == "\x00"
624+
@s.RSTRING_PTR_null_terminate("abc".encode("UTF-16BE"), 2).should == "\x00\x00"
625+
@s.RSTRING_PTR_null_terminate("abc".encode("UTF-32BE"), 4).should == "\x00\x00\x00\x00"
626+
end
595627
end
596628

597629
describe "RSTRING_LEN" do

0 commit comments

Comments
 (0)