@@ -89,6 +89,7 @@ cnc_mcerr cnc_c32nrtomcn_windows_code_page(size_t* __p_maybe_dst_len, char** __p
8989 ? INT_MAX
9090 : static_cast <int >(*__p_maybe_dst_len))
9191 : INT_MAX);
92+ CPINFOEXW* __p_info = (CPINFOEXW*)__p_state->__win32_code_page .__code_page_info ;
9293 const int __win32_err = ::WideCharToMultiByte (static_cast <UINT>(__code_page_id),
9394 __used_defaults.__flags , __intermediate_output, static_cast <int >(__intermediate_size),
9495 __win32_dst, __win32_dst_len, __used_defaults.__p_default_char ,
@@ -108,6 +109,12 @@ cnc_mcerr cnc_c32nrtomcn_windows_code_page(size_t* __p_maybe_dst_len, char** __p
108109 }
109110 }
110111 else {
112+ if (::ztd::__idk_detail::__windows::__widechar_to_multibyte_conversion_failed (
113+ __intermediate_output, __intermediate_size, __win32_dst, __p_info)) {
114+ __p_src[0 ] = __initial_src;
115+ __p_src_len[0 ] = __initial_src_len;
116+ return cnc_mcerr_invalid_sequence;
117+ }
111118 // okay, it should be good
112119 if (!__is_unbounded) {
113120 if (__p_maybe_dst_len[0 ] < static_cast <size_t >(__win32_err)) {
@@ -167,6 +174,7 @@ cnc_mcerr cnc_mcnrtoc32n_windows_code_page(size_t* __p_maybe_dst_len, ztd_char32
167174 const uint32_t __code_page_id = cnc_mcstate_get_win32_code_page (__p_state);
168175 const uint32_t __flags
169176 = ::ztd::__idk_detail::__windows::__multibyte_to_widechar_flags (__code_page_id);
177+ CPINFOEXW* __p_info = (CPINFOEXW*)__p_state->__win32_code_page .__code_page_info ;
170178 for (; __input_read_size <= __initial_src_len; ++__input_read_size) {
171179 if (__input_read_size > CNC_MC_INPUT_MAX) {
172180 // can't do much else
@@ -180,6 +188,10 @@ cnc_mcerr cnc_mcnrtoc32n_windows_code_page(size_t* __p_maybe_dst_len, ztd_char32
180188 continue ;
181189 }
182190 else {
191+ if (::ztd::__idk_detail::__windows::__multibyte_to_widechar_conversion_failed (
192+ __input_read_size, __initial_src, __p_intermediate_output, __p_info)) {
193+ return cnc_mcerr_invalid_sequence;
194+ }
183195 __intermediate_size = static_cast <size_t >(__win32_err);
184196 break ;
185197 }
@@ -286,37 +298,45 @@ cnc_mcerr cnc_mwcnrtomcn_windows_code_page(size_t* __p_maybe_dst_len, char** __p
286298 const ztd_wchar_t * __initial_src = *__p_src;
287299 const size_t __initial_src_len = *__p_src_len;
288300 char __win32_blackhole_buffer[CNC_MC_MAX];
289- char * __dst = __is_counting ? __win32_blackhole_buffer : *__p_maybe_dst;
301+ char * __win32_dst = __is_counting ? __win32_blackhole_buffer : *__p_maybe_dst;
290302 const size_t __dst_size
291303 = __is_unbounded ? ztdc_c_array_size (__win32_blackhole_buffer) : *__p_maybe_dst_len;
292304 const uint32_t __code_page_id = cnc_mcstate_get_win32_code_page (__p_state);
293305 BOOL __default_char_used = false ;
294306 CHAR __default_char = ' ?' ;
295307 auto __used_defaults = ::ztd::__idk_detail::__windows::__widechar_to_multibyte_used_char (
296308 __code_page_id, &__default_char, &__default_char_used);
309+ CPINFOEXW* __p_info = (CPINFOEXW*)__p_state->__win32_code_page .__code_page_info ;
297310 for (size_t __input_read_size = 1 ; __input_read_size <= __initial_src_len;
298311 ++__input_read_size) {
299312 if (__input_read_size > CNC_MWC_INPUT_MAX) {
300313 break ;
301314 }
302315 const int __win32_err = ::WideCharToMultiByte (static_cast <UINT>(__code_page_id),
303- __used_defaults.__flags , __initial_src, static_cast <int >(__input_read_size), __dst,
304- static_cast <int >(__dst_size), __used_defaults.__p_default_char ,
316+ __used_defaults.__flags , __initial_src, static_cast <int >(__input_read_size),
317+ __win32_dst, static_cast <int >(__dst_size), __used_defaults.__p_default_char ,
305318 __used_defaults.__p_default_char_used );
306319 if (__win32_err == 0 ) {
307320 DWORD __last_win32_err = ::GetLastError ();
308- if (__last_win32_err == ERROR_NO_UNICODE_TRANSLATION || __default_char_used ) {
321+ if (__last_win32_err == ERROR_NO_UNICODE_TRANSLATION) {
309322 // loop around; we don't know if this is from a partial read (because of our
310323 // artifical limitations) or because it's a genuine error. This is, of course,
311324 // the problem with these crappy 1990s/2000s APIs.
312325 continue ;
313326 }
327+ else if (__default_char_used) {
328+ return cnc_mcerr_invalid_sequence;
329+ }
314330 else if (!__is_unbounded && __last_win32_err == ERROR_INSUFFICIENT_BUFFER) {
315331 return cnc_mcerr_insufficient_output;
316332 }
317333 // if it's not one of those, then it's safe to loop around and do it again...
318334 }
319335 else {
336+ if (::ztd::__idk_detail::__windows::__widechar_to_multibyte_conversion_failed (
337+ __initial_src, __input_read_size, __win32_dst, __p_info)) {
338+ return cnc_mcerr_invalid_sequence;
339+ }
320340 if (!__is_unbounded) {
321341 if (__p_maybe_dst_len[0 ] < static_cast <size_t >(__win32_err)) {
322342 return cnc_mcerr_insufficient_output;
@@ -375,6 +395,7 @@ cnc_mcerr cnc_mcnrtomwcn_windows_code_page(size_t* __p_maybe_dst_len, ztd_wchar_
375395 const uint32_t __code_page_id = cnc_mcstate_get_win32_code_page (__p_state);
376396 uint32_t __flags
377397 = ::ztd::__idk_detail::__windows::__multibyte_to_widechar_flags (__code_page_id);
398+ CPINFOEXW* __p_info = (CPINFOEXW*)__p_state->__win32_code_page .__code_page_info ;
378399 for (size_t __input_read_size = 1 ; __input_read_size <= __initial_src_len;
379400 ++__input_read_size) {
380401 if (__input_read_size > CNC_MC_INPUT_MAX) {
@@ -391,6 +412,10 @@ cnc_mcerr cnc_mcnrtomwcn_windows_code_page(size_t* __p_maybe_dst_len, ztd_wchar_
391412 continue ;
392413 }
393414 else {
415+ if (::ztd::__idk_detail::__windows::__multibyte_to_widechar_conversion_failed (
416+ __input_read_size, __initial_src, __dst, __p_info)) {
417+ return cnc_mcerr_invalid_sequence;
418+ }
394419 if (!__is_unbounded) {
395420 if (__p_maybe_dst_len[0 ] < static_cast <size_t >(__win32_err)) {
396421 return cnc_mcerr_insufficient_output;
0 commit comments