https://issues.dlang.org/show_bug.cgi?id=14861
[email protected] changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull CC| |[email protected] Assignee|[email protected] |[email protected] --- Comment #3 from [email protected] --- Reduced test case: ---- import std.stdio; import std.array: replicate; void main() { File fw = File("panic.csv", "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(); File fr = File("panic.csv", "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); } ---- LockingTextReader essentially does this: ---- auto fps = fr.getFP(); auto fp = cast(_iobuf*) fps; assert(FGETC(fp) == '\xD1'); /* passes */ assert(FGETC(fp) == '\x91'); /* passes */ assert(ungetc('\x91', fps) == '\x91'); /* passes */ assert(ungetc('\xD1', fps) == '\xD1'); /* passes */ assert(FGETC(fp) == '\xD1'); /* passes */ assert(FGETC(fp) == '\x91'); /* fails */ ---- The problem is that ungetc is called multiple times. Apparently, the Windows 32 C runtime doesn't like that under these specific circumstances. Checking the documentation for ungetc, calling it more than once is actually not guaranteed to work. Here's a PR that replaces the ungetc calls with ftell/fseek: https://github.com/D-Programming-Language/phobos/pull/3622 --
