Author: tfaber
Date: Mon Sep 26 10:12:58 2016
New Revision: 72810

URL: http://svn.reactos.org/svn/reactos?rev=72810&view=rev
Log:
[KERNEL32]
- Handle UTF-16 surrogate pairs in IntWideCharToMultiByteUTF8.
CORE-12042 #resolve

Modified:
    trunk/reactos/dll/win32/kernel32/winnls/string/nls.c

Modified: trunk/reactos/dll/win32/kernel32/winnls/string/nls.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/winnls/string/nls.c?rev=72810&r1=72809&r2=72810&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/winnls/string/nls.c        [iso-8859-1] 
(original)
+++ trunk/reactos/dll/win32/kernel32/winnls/string/nls.c        [iso-8859-1] 
Mon Sep 26 10:12:58 2016
@@ -95,7 +95,7 @@
     RtlInitCodePageTable((PUSHORT)AnsiCodePage.SectionMapping,
                          &AnsiCodePage.CodePageTable);
     AnsiCodePage.CodePage = AnsiCodePage.CodePageTable.CodePage;
-    
+
     InsertTailList(&CodePageListHead, &AnsiCodePage.Entry);
 
     /* Setup OEM code page. */
@@ -515,7 +515,7 @@
                 TempString++;
             }
         }
-        
+
         /* Does caller query for output buffer size? */
         if (WideCharCount == 0)
         {
@@ -753,7 +753,7 @@
                            LPBOOL UsedDefaultChar)
 {
     INT TempLength;
-    WCHAR Char;
+    DWORD Char;
 
     /* Does caller query for output buffer size? */
     if (MultiByteCount == 0)
@@ -766,7 +766,17 @@
             {
                 TempLength++;
                 if (*WideCharString >= 0x800)
+                {
                     TempLength++;
+                    if (*WideCharString >= 0xd800 && *WideCharString < 0xdc00 
&&
+                        WideCharCount >= 1 &&
+                        WideCharString[1] >= 0xdc00 && WideCharString[1] <= 
0xe000)
+                    {
+                        WideCharCount--;
+                        WideCharString++;
+                        TempLength++;
+                    }
+                }
             }
         }
         return TempLength;
@@ -798,6 +808,35 @@
             MultiByteString[0] = 0xc0 | Char;
             MultiByteString += 2;
             TempLength -= 2;
+            continue;
+        }
+
+        /* surrogate pair 0x10000-0x10ffff: 4 bytes */
+        if (Char >= 0xd800 && Char < 0xdc00 &&
+            WideCharCount >= 1 &&
+            WideCharString[1] >= 0xdc00 && WideCharString[1] < 0xe000)
+        {
+            WideCharCount--;
+            WideCharString++;
+
+            if (TempLength < 4)
+            {
+                SetLastError(ERROR_INSUFFICIENT_BUFFER);
+                break;
+            }
+
+            Char = (Char - 0xd800) << 10;
+            Char |= *WideCharString - 0xdc00;
+            ASSERT(Char <= 0xfffff);
+            Char += 0x10000;
+            ASSERT(Char <= 0x10ffff);
+
+            MultiByteString[3] = 0x80 | (Char & 0x3f); Char >>= 6;
+            MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
+            MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
+            MultiByteString[0] = 0xf0 | Char;
+            MultiByteString += 4;
+            TempLength -= 4;
             continue;
         }
 


Reply via email to