[phobos] Bug 3763 (How to fix readlnImpl())

David Simcha dsimcha at gmail.com
Thu Feb 4 07:26:13 PST 2010


On Thu, Feb 4, 2010 at 12:10 AM, Andrei Alexandrescu <andrei at erdani.com>wrote:

> David Simcha wrote:
>
>> I recently filed bug 3673 (
>> http://d.puremagic.com/issues/show_bug.cgi?id=3763) and started looking
>> at possible fixes.  This is a bug in std.stdio.readlnImpl().  However, the
>> more I think about it the more I think the function needs to be completely
>> rethought, not just patched.  I'm not sure if this is a high priority given
>> that it has nothing to do with the language spec and TDPL but it's a pretty
>> embarrassing quality of implementation issue.
>>
>> Anyhow, readlnImpl() takes a ref char[] and tries to recycle the memory to
>> read in another line.  In doing so, it queries GC.capacity for the relevant
>> memory block and resizes the array to the size of the memory block.  This is
>> arguably unsafe in the general case because, if someone passes in a slice
>> that starts at the beginning of a GC block to use as the buffer, everything
>> else in the same GC block can get overwritten.  This massively violates the
>> principle of least surprise.  On the other hand, when encapsulated in the
>> higher level API of byLine(), it's both safe and efficient.
>>
>
> Could you please give an example?


import std.stdio;

void main() {
    auto writer = File("foo.txt", "wb");
    foreach(i; 0..1000) {
        writer.write('a');
    }
    writer.writeln();
    writer.close();

    auto chars = new char[500];
    chars[] = 'b';
    auto buf = chars[0..100];

    auto reader = File("foo.txt", "rb");
    reader.readln(buf);
    writeln(chars[$ - 1]);  // a
    assert(chars[$ - 1] == 'b');  // FAILS.
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/phobos/attachments/20100204/0fb2c442/attachment.htm>


More information about the phobos mailing list