Skip to content

Commit 5101cfb

Browse files
tenderworkstenderloveXrXrkou
authored
Make sure shared buffer is copied on mutation (#117)
We need to ensure shared buffers are made independent on mutation. Otherwise we could end up mutating unrelated string buffers. --------- Co-authored-by: Aaron Patterson <[email protected]> Co-authored-by: Alan Wu <[email protected]> Co-authored-by: Aaron Patterson <[email protected]> Co-authored-by: Sutou Kouhei <[email protected]>
1 parent a5b6271 commit 5101cfb

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

ext/stringio/stringio.c

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ check_modifiable(struct StringIO *ptr)
180180
else if (OBJ_FROZEN_RAW(ptr->string)) {
181181
rb_raise(rb_eIOError, "not modifiable string");
182182
}
183+
rb_str_modify(ptr->string);
183184
}
184185

185186
static VALUE

test/stringio/test_stringio.rb

+18
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ def open_file(content)
1414

1515
include TestEOF::Seek
1616

17+
def test_do_not_mutate_shared_buffers
18+
# Ensure we have two strings that are not embedded but have the same shared
19+
# string reference.
20+
#
21+
# In this case, we must use eval because we need two strings literals that
22+
# are long enough they cannot be embedded, but also contain the same bytes.
23+
24+
a = eval(("x" * 1024).dump)
25+
b = eval(("x" * 1024).dump)
26+
27+
s = StringIO.new(b)
28+
s.getc
29+
s.ungetc '#'
30+
31+
# We mutated b, so a should not be mutated
32+
assert_equal("x", a[0])
33+
end
34+
1735
def test_version
1836
assert_kind_of(String, StringIO::VERSION)
1937
end

0 commit comments

Comments
 (0)