Alexandre Julliard : ntdll: Fix DBCS mappings in RtlCustomCPToUnicodeN().

Alexandre Julliard julliard at winehq.org
Fri Dec 6 16:06:38 CST 2019


Module: wine
Branch: master
Commit: 117dbfa2cf4e831c6eccad982c82cf9ae808eccc
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=117dbfa2cf4e831c6eccad982c82cf9ae808eccc

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Dec  6 17:17:52 2019 +0100

ntdll: Fix DBCS mappings in RtlCustomCPToUnicodeN().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/locale.c | 31 ++++++++++++++++++++++++++++---
 dlls/ntdll/locale.c          |  8 ++++----
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index de1d4fca22..e43eee2788 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -89,6 +89,7 @@ static NTSTATUS (WINAPI *pRtlNormalizeString)(ULONG, LPCWSTR, INT, LPWSTR, INT*)
 static NTSTATUS (WINAPI *pRtlIsNormalizedString)(ULONG, LPCWSTR, INT, BOOLEAN*);
 static NTSTATUS (WINAPI *pNtGetNlsSectionPtr)(ULONG,ULONG,void*,void**,SIZE_T*);
 static void (WINAPI *pRtlInitCodePageTable)(USHORT*,CPTABLEINFO*);
+static NTSTATUS (WINAPI *pRtlCustomCPToUnicodeN)(CPTABLEINFO*,WCHAR*,DWORD,DWORD*,const char*,DWORD);
 
 static void InitFunctionPointers(void)
 {
@@ -134,6 +135,7 @@ static void InitFunctionPointers(void)
   X(RtlIsNormalizedString);
   X(NtGetNlsSectionPtr);
   X(RtlInitCodePageTable);
+  X(RtlCustomCPToUnicodeN);
 #undef X
 }
 
@@ -4196,17 +4198,40 @@ static void test_GetCPInfo(void)
         ret = UnmapViewOfFile( ptr );
         todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
 
-        status = pNtGetNlsSectionPtr( 11, 932, NULL, &ptr, &size );
+        status = pNtGetNlsSectionPtr( 11, 936, NULL, &ptr, &size );
         ok( !status, "failed %x\n", status );
-        ok( size > 0x20000 && size <= 0x30000, "wrong size %lx\n", size );
+        ok( size > 0x30000 && size <= 0x40000, "wrong size %lx\n", size );
         memset( &table, 0xcc, sizeof(table) );
         if (pRtlInitCodePageTable)
         {
             pRtlInitCodePageTable( ptr, &table );
-            ok( table.CodePage == 932, "wrong codepage %u\n", table.CodePage );
+            ok( table.CodePage == 936, "wrong codepage %u\n", table.CodePage );
             ok( table.MaximumCharacterSize == 2, "wrong char size %u\n", table.MaximumCharacterSize );
             ok( table.DefaultChar == '?', "wrong default char %x\n", table.DefaultChar );
             ok( table.DBCSCodePage == TRUE, "wrong dbcs %u\n", table.DBCSCodePage );
+
+            if (pRtlCustomCPToUnicodeN)
+            {
+                static const unsigned char buf[] = { 0xbf, 0xb4, 0xc7, 0, 0x78 };
+                static const WCHAR expect[][4] = { { 0xcccc, 0xcccc, 0xcccc, 0xcccc },
+                                                   { 0x0000, 0xcccc, 0xcccc, 0xcccc },
+                                                   { 0x770b, 0xcccc, 0xcccc, 0xcccc },
+                                                   { 0x770b, 0x0000, 0xcccc, 0xcccc },
+                                                   { 0x770b, 0x003f, 0xcccc, 0xcccc },
+                                                   { 0x770b, 0x003f, 0x0078, 0xcccc } };
+                WCHAR wbuf[5];
+                DWORD i, j, reslen;
+
+                for (i = 0; i <= sizeof(buf); i++)
+                {
+                    memset( wbuf, 0xcc, sizeof(wbuf) );
+                    RtlCustomCPToUnicodeN( &table, wbuf, sizeof(wbuf), &reslen, (char *)buf, i );
+                    for (j = 0; j < 4; j++) if (expect[i][j] == 0xcccc) break;
+                    ok( reslen == j * sizeof(WCHAR), "%u: wrong len %u\n", i, reslen );
+                    for (j = 0; j < 4; j++)
+                        ok( wbuf[j] == expect[i][j], "%u: char %u got %04x\n", i, j, wbuf[j] );
+                }
+            }
         }
         ret = UnmapViewOfFile( ptr );
         todo_wine ok( ret, "UnmapViewOfFile failed err %u\n", GetLastError() );
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c
index f5faada578..d505a36ba8 100644
--- a/dlls/ntdll/locale.c
+++ b/dlls/ntdll/locale.c
@@ -841,10 +841,10 @@ WCHAR WINAPI RtlAnsiCharToUnicodeChar( char **ansi )
     if (nls_info.AnsiTableInfo.DBCSOffsets)
     {
         USHORT off = nls_info.AnsiTableInfo.DBCSOffsets[(unsigned char)**ansi];
-        if (off && (*ansi)[1])
+        if (off)
         {
             (*ansi)++;
-            return nls_info.AnsiTableInfo.MultiByteTable[off + (unsigned char)*(*ansi)++];
+            return nls_info.AnsiTableInfo.DBCSOffsets[off + (unsigned char)*(*ansi)++];
         }
     }
     return nls_info.AnsiTableInfo.MultiByteTable[(unsigned char)*(*ansi)++];
@@ -919,11 +919,11 @@ NTSTATUS WINAPI RtlCustomCPToUnicodeN( CPTABLEINFO *info, WCHAR *dst, DWORD dstl
         for (i = dstlen; srclen && i; i--, srclen--, src++, dst++)
         {
             USHORT off = info->DBCSOffsets[(unsigned char)*src];
-            if (off && srclen > 1 && src[1])
+            if (off && srclen > 1)
             {
                 src++;
                 srclen--;
-                *dst = info->MultiByteTable[off + (unsigned char)*src];
+                *dst = info->DBCSOffsets[off + (unsigned char)*src];
             }
             else *dst = info->MultiByteTable[(unsigned char)*src];
         }




More information about the wine-cvs mailing list