diff --git a/ext/zstdruby/skippable_frame.c b/ext/zstdruby/skippable_frame.c index 73534b8..c22be85 100644 --- a/ext/zstdruby/skippable_frame.c +++ b/ext/zstdruby/skippable_frame.c @@ -36,6 +36,7 @@ static VALUE rb_write_skippable_frame(int argc, VALUE *argv, VALUE self) static VALUE rb_read_skippable_frame(VALUE self, VALUE input_value) { + StringValue(input_value); char* input_data = RSTRING_PTR(input_value); size_t input_size = RSTRING_LEN(input_value); diff --git a/spec/zstd-skippable_frame_spec.rb b/spec/zstd-skippable_frame_spec.rb index c5c882e..7d1c8c9 100644 --- a/spec/zstd-skippable_frame_spec.rb +++ b/spec/zstd-skippable_frame_spec.rb @@ -30,5 +30,22 @@ end end + context 'non-String argument' do + [nil, 123456789, :symbol, [1, 2, 3], Object.new].each do |arg| + it "raises TypeError for #{arg.class}" do + expect { Zstd.read_skippable_frame(arg) }.to raise_error(TypeError) + end + end + end + + context 'String-convertible argument' do + it 'accepts objects responding to #to_str' do + compressed_data = Zstd.compress(SecureRandom.hex(150)) + frame = Zstd.write_skippable_frame(compressed_data, "sample data") + convertible = Object.new + convertible.define_singleton_method(:to_str) { frame } + expect(Zstd.read_skippable_frame(convertible)).to eq "sample data" + end + end end end