diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c index 71bedb7de70..54f62aecec5 100644 --- a/dlls/kernel32/tests/codepage.c +++ b/dlls/kernel32/tests/codepage.c @@ -276,12 +276,14 @@ static void test_overlapped_buffers(void) static void test_string_conversion(LPBOOL bUsedDefaultChar) { char mbc; - char mbs[5]; + char mbs[15]; int ret; WCHAR wc1 = 228; /* Western Windows-1252 character */ WCHAR wc2 = 1088; /* Russian Windows-1251 character not displayable for Windows-1252 */ static const WCHAR wcs[] = {'T', 'h', 1088, 'i', 0}; /* String with ASCII characters and a Russian character */ static const WCHAR dbwcs[] = {28953, 25152, 0}; /* String with Chinese (codepage 950) characters */ + static const WCHAR dbwcs2[] = {0x7bb8, 0x3d, 0xc813, 0xac00, 0xb77d, 0}; + static const char default_char[] = {0xa3, 0xbf, 0}; SetLastError(0xdeadbeef); ret = WideCharToMultiByte(1252, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar); @@ -358,6 +360,11 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar) ok(!strcmp(mbs, "??"), "mbs is %s\n", mbs); if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar); + ret = WideCharToMultiByte(936, WC_COMPOSITECHECK, dbwcs2, -1, mbs, sizeof(mbs), (const char *)default_char, bUsedDefaultChar); + ok(ret == 10, "ret is %d\n", ret); + ok(!strcmp(mbs, "\xf3\xe7\x3d\xa3\xbf\xa3\xbf\xa3\xbf"), "mbs is %s\n", mbs); + if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar); + /* Length-only tests */ SetLastError(0xdeadbeef); ret = WideCharToMultiByte(1252, 0, &wc2, 1, NULL, 0, NULL, bUsedDefaultChar); diff --git a/libs/wine/wctomb.c b/libs/wine/wctomb.c index 3b081d45653..29a3d920142 100644 --- a/libs/wine/wctomb.c +++ b/libs/wine/wctomb.c @@ -275,6 +275,14 @@ static inline int is_valid_dbcs_mapping( const struct dbcs_table *table, int fla return 1; } +/* compute the default char for the dbcs case */ +static inline WCHAR get_defchar_dbcs( const struct dbcs_table *table, const char *defchar ) +{ + if (!defchar) return table->info.def_char; + if (!defchar[1]) return (unsigned char)defchar[0]; + return ((unsigned char)defchar[0] << 8) | (unsigned char)defchar[1]; +} + /* query necessary dst length for src string */ static int get_length_dbcs( const struct dbcs_table *table, int flags, const WCHAR *src, unsigned int srclen, @@ -282,8 +290,7 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags, { const unsigned short * const uni2cp_low = table->uni2cp_low; const unsigned short * const uni2cp_high = table->uni2cp_high; - WCHAR defchar_value = table->info.def_char; - WCHAR composed; + WCHAR defchar_value, composed; int len, tmp; if (!defchar && !used && !(flags & WC_COMPOSITECHECK)) @@ -295,7 +302,7 @@ static int get_length_dbcs( const struct dbcs_table *table, int flags, return len; } - if (defchar) defchar_value = defchar[1] ? ((defchar[0] << 8) | defchar[1]) : defchar[0]; + defchar_value = get_defchar_dbcs( table, defchar ); if (!used) used = &tmp; /* avoid checking on every char */ *used = 0; for (len = 0; srclen; len++, srclen--, src++) @@ -376,11 +383,10 @@ static int wcstombs_dbcs_slow( const struct dbcs_table *table, int flags, { const unsigned short * const uni2cp_low = table->uni2cp_low; const unsigned short * const uni2cp_high = table->uni2cp_high; - WCHAR defchar_value = table->info.def_char; + WCHAR defchar_value = get_defchar_dbcs( table, defchar ); WCHAR composed; int len, tmp; - if (defchar) defchar_value = defchar[1] ? ((defchar[0] << 8) | defchar[1]) : defchar[0]; if (!used) used = &tmp; /* avoid checking on every char */ *used = 0;