From 2b8bc1b4760d8ecb4fdcdd79923d29d0ab20b908 Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Sat, 6 Apr 2024 17:10:23 +0300 Subject: win32: UTF8_OUTPUT: flush stream before conversion writeCon_utf8 is unbuffered - it writes directly using WriteConsoleW, but some winansi libc IO wrappers, like fputs, use the libc API directly if the content doesn't need any special handling (e.g. all ASCII and no escape sequences), and so if the stream is buffered, and if only some parts of it go through writeCon_utf8, then we can get wrong output order due to some parts being buffered and some not. Case in point, the recent commit 54dbf0fa5 made the output of "time" buffered, and so if only parts of it go through writeCon_utf8, then we get bad output order. This did actually happen, because not all the winasi wrappers have this ASCII-only optimization (e.g. winansi_putchar), and "time" did end up with wrong output order. Even if all the winansi wrappers were ASCII-optimized, "time" could still have unicode output, e.g. with -f. Fix it by flushing the stream before converting using writeCon_utf8. --- win32/winansi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win32/winansi.c b/win32/winansi.c index 66b040b31..dc98b9d2b 100644 --- a/win32/winansi.c +++ b/win32/winansi.c @@ -1590,8 +1590,10 @@ static int conv_fwriteCon(FILE *stream, char *buf, size_t siz) { if (conout_conv_enabled()) { #if ENABLE_FEATURE_UTF8_OUTPUT - if (GetConsoleOutputCP() != CP_UTF8) + if (GetConsoleOutputCP() != CP_UTF8) { + fflush(stream); // writeCon_utf8 is unbuffered return writeCon_utf8(fileno(stream), buf, siz) ? EOF : 0; + } #else charToConBuffA(buf, siz); #endif -- cgit v1.2.3-55-g6feb