Bug 13856 – std.stdio.readln stomps arrays

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-12-11T22:47:00Z
Last change time
2015-10-04T18:19:58Z
Keywords
pull
Assigned to
nobody
Creator
r.sagitario

Comments

Comment #0 by r.sagitario — 2014-12-11T22:47:47Z
This program causes two asserts on Win32: import std.stdio; import std.file; import core.memory; void main() { std.file.write("testread", "abcd\n0123456789abcde\n"); File f = File("testread", "rb"); char[] ln = new char[2]; f.readln(ln); assert(ln == "abcd\n"); char[] t = ln[0..2]; t ~= 't'; // stomps ln assert(t == "abt"); assert(ln == "abcd\n"); // fails // it can get also stomp the array length ln = new char[4]; f.readln(ln); assert(ln == "0123456789abcde\n"); auto bi = GC.query(ln.ptr); assert(bi.base == ln.ptr); assert(bi.attr & GC.BlkAttr.APPENDABLE); int len = ln.ptr[bi.size - 1]; // last byte should be allocated array size assert(ln.length <= len && len < bi.size); // fails: len = 10 } shows that readln fills the memory of arrays with data without respecting the "allocation length" also stored for arrays. There are different implementations for DigitalMars, Microsoft and GCC runtime, so the behaviour might be slightly different, but all assume that the passed array is GC.malloced, starts at the allocation block and has size GC.sizeOf(arr.ptr).
Comment #1 by r.sagitario — 2014-12-12T10:35:32Z
This shows that the current implementation also adds an unnecesary allocation when supplying stack allocated arrays as an initial buffer. void main() { std.file.write("testread", "abcd\n"); File f = File("testread", "rb"); char[100] buf; ln = buf[]; f.readln(ln); assert(ln.ptr == buf.ptr); }
Comment #2 by r.sagitario — 2014-12-12T11:07:42Z
Comment #3 by ag0aep6g — 2015-01-19T21:16:37Z
*** Issue 14005 has been marked as a duplicate of this issue. ***
Comment #4 by mk — 2015-03-19T22:36:10Z
*** Issue 14310 has been marked as a duplicate of this issue. ***
Comment #5 by code — 2015-03-24T13:36:57Z
As an intermediate replacement it is possible to use byLine.
Comment #6 by acehreli — 2015-03-24T13:59:39Z
Both of the bugs that are marked as duplicates of this one use byLine. (However, bug 14005 seems to be cured at this time.) Ali
Comment #7 by schveiguy — 2015-03-24T14:28:31Z
(In reply to Martin Nowak from comment #5) > As an intermediate replacement it is possible to use byLine. Not really. readln does not do the same thing as byLine. I don't know how you would use byline instead of readln in the OP code. byLine is not really meant to be a "read a line here or there" type of operation, it's meant to exhaust the stream a line at a time.
Comment #8 by github-bugzilla — 2015-07-13T15:05:12Z
Commit pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/497c463e100c690e750c28e8918f7f785fd4a4f1 Merge pull request #2794 from rainers/issue13856 Fix Issue 13856 - std.stdio.readln stomps arrays
Comment #9 by github-bugzilla — 2015-10-04T18:19:58Z