diff options
| -rw-r--r-- | io_buffer.c | 25 | ||||
| -rw-r--r-- | test/ruby/test_io_buffer.rb | 4 | ||||
| -rw-r--r-- | version.h | 2 |
3 files changed, 16 insertions, 15 deletions
diff --git a/io_buffer.c b/io_buffer.c index 115e5e7a58..d981fd26c7 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -299,20 +299,22 @@ rb_io_buffer_type_allocate(VALUE self) return instance; } -static VALUE -io_buffer_for_make_instance(VALUE klass, VALUE string) +static VALUE io_buffer_for_make_instance(VALUE klass, VALUE string, enum rb_io_buffer_flags flags) { VALUE instance = rb_io_buffer_type_allocate(klass); - struct rb_io_buffer *data = NULL; - TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, data); + struct rb_io_buffer *buffer = NULL; + TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, buffer); - enum rb_io_buffer_flags flags = RB_IO_BUFFER_EXTERNAL; + flags |= RB_IO_BUFFER_EXTERNAL; if (RB_OBJ_FROZEN(string)) flags |= RB_IO_BUFFER_READONLY; - io_buffer_initialize(data, RSTRING_PTR(string), RSTRING_LEN(string), flags, string); + if (!(flags & RB_IO_BUFFER_READONLY)) + rb_str_modify(string); + + io_buffer_initialize(buffer, RSTRING_PTR(string), RSTRING_LEN(string), flags, string); return instance; } @@ -321,6 +323,7 @@ struct io_buffer_for_yield_instance_arguments { VALUE klass; VALUE string; VALUE instance; + enum rb_io_buffer_flags flags; }; static VALUE @@ -328,9 +331,9 @@ io_buffer_for_yield_instance(VALUE _arguments) { struct io_buffer_for_yield_instance_arguments *arguments = (struct io_buffer_for_yield_instance_arguments *)_arguments; - rb_str_locktmp(arguments->string); + arguments->instance = io_buffer_for_make_instance(arguments->klass, arguments->string, arguments->flags); - arguments->instance = io_buffer_for_make_instance(arguments->klass, arguments->string); + rb_str_locktmp(arguments->string); return rb_yield(arguments->instance); } @@ -364,7 +367,8 @@ io_buffer_for_yield_instance_ensure(VALUE _arguments) * collector, the source string will be locked and cannot be modified. * * If the string is frozen, it will create a read-only buffer which cannot be - * modified. + * modified. If the string is shared, it may trigger a copy-on-write when + * using the block form. * * string = 'test' * buffer = IO::Buffer.for(string) @@ -396,6 +400,7 @@ rb_io_buffer_type_for(VALUE klass, VALUE string) .klass = klass, .string = string, .instance = Qnil, + .flags = 0, }; return rb_ensure(io_buffer_for_yield_instance, (VALUE)&arguments, io_buffer_for_yield_instance_ensure, (VALUE)&arguments); @@ -403,7 +408,7 @@ rb_io_buffer_type_for(VALUE klass, VALUE string) else { // This internally returns the source string if it's already frozen. string = rb_str_tmp_frozen_acquire(string); - return io_buffer_for_make_instance(klass, string); + return io_buffer_for_make_instance(klass, string, RB_IO_BUFFER_READONLY); } } diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb index 45813256e4..a0949a54f2 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -348,10 +348,6 @@ class TestIOBuffer < Test::Unit::TestCase end def test_read - # This is currently a bug in IO:Buffer [#19084] which affects extended - # strings. On 32 bit machines, the example below becomes extended, so - # we omit this test until the bug is fixed. - omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1 io = Tempfile.new io.write("Hello World") io.seek(0) @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 70 +#define RUBY_PATCHLEVEL 71 #include "ruby/version.h" #include "ruby/internal/abi.h" |
