Skip to content

Commit

Permalink
fix issue 14861 - Error in stdio.d in LockingTextReader.readFront()
Browse files Browse the repository at this point in the history
Calling ungetc more than once is not guaranteed to work. Replacing the
ungetc calls with ftell/fseek.
  • Loading branch information
aG0aep6G committed Sep 1, 2015
1 parent 5f165ae commit 24123bd
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions std/stdio.d
Expand Up @@ -2881,14 +2881,15 @@ struct LockingTextReader
return buf[0 .. seqLen];
}

/* Read a utf8 sequence from the file into _front, putting the chars back so
that they can be read again.
/* Read a utf8 sequence from the file into _front, then rewind to the
beginning of the sequence so that it can be read again.
Destroys/closes the file when at EOF. */
private void readFront()
{
import std.exception : enforce;
import std.utf : decodeFront;

immutable start = _f.tell();
char[4] buf;
auto chars = takeFront(buf);

Expand All @@ -2902,12 +2903,7 @@ struct LockingTextReader
auto s = chars;
_front = decodeFront(s);

// Put everything back.
foreach(immutable i; 0 .. chars.length)
{
immutable c = chars[$ - 1 - i];
enforce(ungetc(c, cast(FILE*) _f._p.handle) == c);
}
_f.seek(start); // rewind
}

void popFront()
Expand Down Expand Up @@ -2984,6 +2980,27 @@ unittest // bugzilla 12320
assert(ltr.empty);
}

unittest // bugzilla 14861
{
auto deleteme = testFilename();
File fw = File(deleteme, "w");
fw.rawWrite("a".replicate(16383) ~ "\xD1\x91\xD1\x82");
/* \xD1\x91 = U+0451 CYRILLIC SMALL LETTER IO */
/* \xD1\x82 = U+0442 CYRILLIC SMALL LETTER TE */
fw.close();
scope(exit) std.file.remove(deleteme);

File fr = File(deleteme, "r");
fr.rawRead(new char[16383]);

auto ltr = LockingTextReader(fr);
assert(ltr.front == '\u0451'); /* passes */
ltr.popFront(); /* "Invalid UTF-8 sequence" */
assert(ltr.front == '\u0442');
ltr.popFront();
assert(ltr.empty);
}

/**
* Indicates whether $(D T) is a file handle of some kind.
*/
Expand Down

0 comments on commit 24123bd

Please sign in to comment.