@@ -287,7 +287,7 @@ namespace cnc {
287287 BOOL __default_char_used = false ;
288288 CHAR __default_char = ' ?' ;
289289 auto __used_defaults
290- = ::ztd::__idk_detail::__windows::__multibyte_to_widechar_used_char (
290+ = ::ztd::__idk_detail::__windows::__widechar_to_multibyte_used_char (
291291 ::ztd::__idk_detail::__windows::__code_page_active_thread, &__default_char,
292292 &__default_char_used);
293293 const size_t __intermediate_size
@@ -300,6 +300,9 @@ namespace cnc {
300300 : INT_MAX);
301301 for (size_t __intermediate_input_read = 1 ;
302302 __intermediate_input_read <= __intermediate_size; ++__intermediate_input_read) {
303+ if (__intermediate_input_read > CNC_MWC_INPUT_MAX) {
304+ break ;
305+ }
303306 const int __win32_err = ::WideCharToMultiByte (
304307 ::ztd::__idk_detail::__windows::__code_page_active_thread,
305308 WC_ERR_INVALID_CHARS, __intermediate_output,
@@ -309,10 +312,11 @@ namespace cnc {
309312 DWORD __last_win32_err = ::GetLastError ();
310313 if (__last_win32_err == ERROR_NO_UNICODE_TRANSLATION
311314 || __default_char_used) {
312- // we can break early: it was illegal stuff that can't translate
313- __p_src[0 ] = __initial_src;
314- __p_src_len[0 ] = __initial_src_len;
315- return cnc_mcerr_invalid_sequence;
315+ // loop around; we don't know if this is from a partial read (because
316+ // of our
317+ // artifical limitations) or because it's a genuine error. This is, of
318+ // course, the problem with these crappy 1990s/2000s APIs.
319+ continue ;
316320 }
317321 else if (__last_win32_err == ERROR_INSUFFICIENT_BUFFER) {
318322 if (!_IsUnbounded) {
@@ -326,6 +330,16 @@ namespace cnc {
326330 }
327331 }
328332 else {
333+ if (__win32_err == 1 ) {
334+ // double-check if we were screwed over by the conversion: given
335+ // Win32's undocumented fuckups around this, the only way to know if
336+ // we actually failed is by checking if the single character we output
337+ // is equal to a replacement character, and if the replacement
338+ // character is NOT present in the original stream. The proper way to
339+ // do this is to call GetCPInfoExW and then using a comparison to the
340+ // MultiByte stream. But there's so many different things wrong with
341+ // it, and it's hard to know.
342+ }
329343 // okay, it should be good
330344 if (!_IsUnbounded) {
331345 if (__p_maybe_dst_len[0 ] < static_cast <size_t >(__win32_err)) {
@@ -1093,7 +1107,7 @@ namespace cnc {
10931107 = ::ztd::__idk_detail::__windows::__multibyte_to_widechar_flags (
10941108 ztd::__idk_detail::__windows::__code_page_active_thread);
10951109 for (; __input_read_size <= __initial_src_len; ++__input_read_size) {
1096- if (__input_read_size > CNC_MC_MAX ) {
1110+ if (__input_read_size > CNC_MC_INPUT_MAX ) {
10971111 // can't do much else
10981112 return cnc_mcerr_invalid_sequence;
10991113 }
@@ -1103,9 +1117,8 @@ namespace cnc {
11031117 static_cast <int >(__input_read_size), __p_intermediate_output,
11041118 static_cast <int >(__intermediate_output_initial_size));
11051119 if (__win32_err == 0 ) {
1106- if (::GetLastError () == ERROR_NO_UNICODE_TRANSLATION) {
1107- return cnc_mcerr_invalid_sequence;
1108- }
1120+ // not sure; we have to keep looping, unfortunately.
1121+ continue ;
11091122 }
11101123 else {
11111124 __intermediate_size = static_cast <size_t >(__win32_err);
0 commit comments