diff --git a/ext/cool.io/buffer.c b/ext/cool.io/buffer.c index 8509c7e..cd3f345 100644 --- a/ext/cool.io/buffer.c +++ b/ext/cool.io/buffer.c @@ -352,6 +352,9 @@ Coolio_Buffer_read_frame(VALUE self, VALUE data, VALUE mark) TypedData_Get_Struct(self, struct buffer, &Coolio_Buffer_type, buf); + StringValue(data); + rb_str_modify(data); + if (buffer_read_frame(buf, data, mark_c)) { return Qtrue; } else { diff --git a/spec/iobuffer_spec.rb b/spec/iobuffer_spec.rb index a6cadf3..1f03c84 100644 --- a/spec/iobuffer_spec.rb +++ b/spec/iobuffer_spec.rb @@ -142,6 +142,25 @@ expect(data).to eq "foo\nbarbaz" expect(buffer.to_str).to eq "" end + + it "raises TypeError instead of crashing when data is not a String" do + buffer << "hello world" + expect { buffer.read_frame 12345, " ".ord }.to raise_error(TypeError) + expect { buffer.read_frame nil, " ".ord }.to raise_error(TypeError) + expect { buffer.read_frame [], " ".ord }.to raise_error(TypeError) + end + + it "raises FrozenError when data is a frozen String" do + buffer << "hello world" + expect { buffer.read_frame "frozen".freeze, " ".ord }.to raise_error(FrozenError) + end + + it "coerces objects responding to #to_str" do + buffer << "foo\nbar" + convertible = Object.new + def convertible.to_str; +""; end + expect(buffer.read_frame convertible, "\n".ord).to eq true + end end end