diff --git a/CHANGELOG b/CHANGELOG index 6556573..c7a05f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ innoextract 1.9 (TBD) - Fixed handling of path separators in Japanese and Korean installers - Fixed build with newer Boost versions - Windows: Fixed heap corruption + - Windows: Fixed garbled output innoextract 1.8 (2019-09-15) - Added support for Inno Setup 6.0.0 installers diff --git a/src/util/windows.cpp b/src/util/windows.cpp index 4b7a6ae..e75f57a 100644 --- a/src/util/windows.cpp +++ b/src/util/windows.cpp @@ -75,9 +75,8 @@ class windows_console_sink : public util::ansi_console_parser buffer; - const utf8_codecvt * codecvt; - utf8_codecvt::state_type codecvt_state; + std::string in_buffer; + std::string out_buffer; //! Initial console display attributes WORD initial_attributes; @@ -236,6 +235,10 @@ class windows_console_sink : public util::ansi_console_parser(out_buffer.c_str()); + LPCWSTR oend = obegin + out_buffer.size() / 2; + + if(deferred_clear) { + handle_deferred_clear(obegin, oend); + } + + DWORD count; + WriteConsoleW(handle, obegin, DWORD(oend - obegin), &count, NULL); + + } + void handle_text(const char * s, size_t n) { + if(!in_buffer.empty()) { + in_buffer.append(s, n); + s = in_buffer.c_str(); + n = in_buffer.size(); + } + const char * end = s + n; if(s == end) { return; } - for(;;) { - - wchar_t * obegin = &buffer.front(); - wchar_t * oend = obegin + buffer.size(); - wchar_t * onext = obegin; - - std::codecvt_base::result res; - res = codecvt->in(codecvt_state, s, end, s, obegin, oend, onext); - - if(deferred_clear) { - handle_deferred_clear(obegin, onext); - } - - DWORD count; - WriteConsoleW(handle, obegin, DWORD(onext - obegin), &count, NULL); - - if(res != std::codecvt_base::partial) { - break; - } - - if(onext == oend) { - buffer.resize(buffer.size() * 2); - } - - } + const char * e = wtf8_find_end(s, end); + + output_text(s, e); + + in_buffer.assign(e, end); } public: - windows_console_sink(HANDLE console_handle, const utf8_codecvt * converter) + windows_console_sink(HANDLE console_handle) : handle(console_handle) - , buffer(256) - , codecvt(converter) , initial_attributes(get_attributes()) , default_attributes(get_default_attributes()) , attributes(initial_attributes) @@ -389,6 +392,9 @@ public: { } ~windows_console_sink() { + if(!in_buffer.empty()) { + output_text(in_buffer.c_str(), in_buffer.c_str() + in_buffer.size()); + } if(deferred_clear) { CONSOLE_SCREEN_BUFFER_INFO info; if(GetConsoleScreenBufferInfo(handle, &info)) { @@ -400,9 +406,6 @@ public: }; -// UTF8 -> UTF-16 converter -static utf8_codecvt codecvt; - typedef boost::iostreams::stream_buffer console_buffer; struct console_buffer_info { HANDLE handle; @@ -440,7 +443,7 @@ static bool is_console(HANDLE handle) { static void init_console(std::ostream & os, console_buffer_info & info, DWORD n) { info.handle = GetStdHandle(n); if(is_console(info.handle)) { - info.buf = new console_buffer(info.handle, &codecvt); + info.buf = new console_buffer(info.handle); info.orig_buf = os.rdbuf(info.buf); } else { info.handle = NULL;