Actions
Bug #9847
closedCannot create new String when using File.read(size, buffer)
Description
This bug was first noticed in version 1.9.2 and is still present in 2.1.2p95
The attached script does the following to highlight this bug:
- create a file of 13 fixed-length records of a specific size: all records contain a repeated letter, A for the first, B for the second, through M
- Test
#1
: read all records from the file and store them into an array of Strings, usingFile.read(size)
and storing via 'cache << buffer
' - Test
#2
: read all records from the file and store them into an Array of Strings, usingFile.read(size, buffer)
and storing via 'cache << String.new(buffer)
'; buffer will be reused during each read, cache will hold copies - test cycle is run using a record length of 23 and a record length of 24, highlighting Ruby's optimization of short strings
Results of running this script:
- with a record size of 23, Tests
#1

show the cache containing all records:[ A, B, ... M ]
- with a record size of 24, Test
#1
shows the cache containing all records:[ A, B, ... M ]
- with a record size of 24, Test
#2
shows the cache containing:[ M, M, ... M ]
Diagnosis & Notes:
- with a record size > 23 and reading a file using
File.read(size, buffer)
, buffer is in such a state as to prevent a new unique String from being derived - variations of this script showed that
String.new
was a creating new String object on each record read, but the contents of all of the Strings stored in the cache Array were being overwritten on each call toFile.read
- this shows that
String.new(buffer)
is creating new String objects, but that the underlying values of all strings based on buffer were sharing the same internal memory - this behavior exists in the "long string" variation of String; short optimized Strings do not share this property
Files
Updated by Feldmarschal (Kenneth Guerin) over 10 years ago
Errata:
- comments regarding Test
#2
in script are incorrect, but the code is still valid - Issue was not noticed in 1.9.2; that was the last version at which the code worked properly
- Issue started in 2.0
Updated by nobu (Nobuyoshi Nakada) over 10 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r45979.
io.c: buffer must be modifiable
- io.c (io_setstrbuf): always check if the buffer is modifiable.
[ruby-core:62643] [Bug #9847]
Updated by nobu (Nobuyoshi Nakada) over 10 years ago
- Description updated (diff)
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN to 2.0.0: REQUIRED, 2.1: REQUIRED
Updated by usa (Usaku NAKAMURA) over 10 years ago
- Backport changed from 2.0.0: REQUIRED, 2.1: REQUIRED to 2.0.0: DONE, 2.1: REQUIRED
backported into ruby_2_0_0
at r46580.
Updated by nagachika (Tomoyuki Chikanaga) over 10 years ago
- Backport changed from 2.0.0: DONE, 2.1: REQUIRED to 2.0.0: DONE, 2.1: DONE
Backported into ruby_2_1
branch at r46614.
Updated by nobu (Nobuyoshi Nakada) over 10 years ago
- Has duplicate Bug #10007: IO#read does not respect String Copy-On-Write in some cases added
Actions
Like0
Like0Like0Like0Like0Like0Like0