Skip to content

Commit 72b62e4

Browse files
aardvark179eregon
authored andcommitted
Add specs for memcpy bugs.
(cherry picked from commit f63f261)
1 parent 804ce37 commit 72b62e4

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,26 @@ VALUE string_spec_RSTRING_PTR_iterate(VALUE self, VALUE str) {
284284
return Qnil;
285285
}
286286

287+
VALUE string_spec_RSTRING_PTR_iterate_uint32(VALUE self, VALUE str) {
288+
int i;
289+
uint32_t* ptr;
290+
int l = RSTRING_LEN(str) / sizeof(uint32_t);
291+
292+
ptr = (uint32_t *)RSTRING_PTR(str);
293+
for(i = 0; i < l; i++) {
294+
rb_yield(UINT2NUM(ptr[i]));
295+
}
296+
return Qnil;
297+
}
298+
299+
VALUE string_spec_RSTRING_PTR_short_memcpy(VALUE self, VALUE str) {
300+
// Short memcpy operations may be optimised by the compiler to a single write.
301+
if (RSTRING_LEN(str) >= 8) {
302+
memcpy(RSTRING_PTR(str), "Infinity", 8);
303+
}
304+
return str;
305+
}
306+
287307
VALUE string_spec_RSTRING_PTR_assign(VALUE self, VALUE str, VALUE chr) {
288308
int i;
289309
char c;
@@ -477,6 +497,8 @@ void Init_string_spec(void) {
477497
rb_define_method(cls, "RSTRING_LEN", string_spec_RSTRING_LEN, 1);
478498
rb_define_method(cls, "RSTRING_LENINT", string_spec_RSTRING_LENINT, 1);
479499
rb_define_method(cls, "RSTRING_PTR_iterate", string_spec_RSTRING_PTR_iterate, 1);
500+
rb_define_method(cls, "RSTRING_PTR_iterate_uint32", string_spec_RSTRING_PTR_iterate_uint32, 1);
501+
rb_define_method(cls, "RSTRING_PTR_short_memcpy", string_spec_RSTRING_PTR_short_memcpy, 1);
480502
rb_define_method(cls, "RSTRING_PTR_assign", string_spec_RSTRING_PTR_assign, 2);
481503
rb_define_method(cls, "RSTRING_PTR_set", string_spec_RSTRING_PTR_set, 3);
482504
rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2);

spec/ruby/optional/capi/string_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,24 @@ def inspect
513513
end
514514
chars.should == [55, 48, 227, 131, 145, 227, 130, 175]
515515
end
516+
517+
it "returns a pointer which can be cast and used as another type" do
518+
s = "70パク".
519+
encode(Encoding::UTF_16LE).
520+
force_encoding(Encoding::UTF_16LE).
521+
encode(Encoding::UTF_8)
522+
523+
ints = []
524+
@s.RSTRING_PTR_iterate_uint32(s) do |i|
525+
ints << i
526+
end
527+
ints.should == s.unpack('LL')
528+
end
529+
530+
it "allows a short memcpy to the string which may be converted to a single write operation by the compiler" do
531+
str = " "
532+
@s.RSTRING_PTR_short_memcpy(str).should == "Infinity"
533+
end
516534
end
517535

518536
describe "RSTRING_LEN" do

0 commit comments

Comments
 (0)