]> git.proxmox.com Git - mirror_edk2.git/commitdiff
StdLib/LibC/Locale/multibyte_Utf8.c: Fix obscure corner cases in wide to multibyte...
authordarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 15 May 2013 01:59:11 +0000 (01:59 +0000)
committerdarylm503 <darylm503@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 15 May 2013 01:59:11 +0000 (01:59 +0000)
DecodeOneStateful: Properly handle combinations of Src, Dest, or Len being NULL or 0.

EncodeUtf8: Do not zero-terminate the result string in this worker function.

mbsrtowcs: Remove test for **src == '\0', as per ISO/IEC 9899:199409.  Allows "".

wcsrtombs:  The C Language standard, ISO/IEC 9899:199409, states that the wcsrtombs() function will stop before encountering the terminating NUL character only if Dest is NOT NULL.  This implies that if Dest is NULL, the Limit parameter will be ignored.  In order to avoid system hangs, if Dest is NULL a Limit value of ASCII_STRING_MAX is automatically used.  Also fixed a typo in the function header comment.

With these changes, StdLib now passes all of the C Language Standards Compliance Tests for ISO/IEC 9899:199409 (C95).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: daryl.mcdaniel@intel.com
Reviewed-by: erik.c.bjorge@intel.com
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14358 6f19259b-4bc3-4df7-8a09-765794883524

StdLib/LibC/Locale/multibyte_Utf8.c

index ec9b01265896850a86d09318dc4a17fdb18d1e05..ffe3dee231ca203b9e448a827b77f82ae75c4761 100644 (file)
@@ -197,19 +197,24 @@ DecodeOneStateful(
   int           NumConv;\r
   unsigned char ch;\r
 \r
-  if((Src == NULL) || (*Src == '\0')) {\r
-    return 0;\r
-  }\r
   if(pS == NULL) {\r
     pS = &LocalConvState;\r
   }\r
-  SrcEnd  = Src + Len;\r
   NumConv = 0;\r
-  while(Src < SrcEnd) {\r
-    ch = (unsigned char)*Src++;\r
-    NumConv = ProcessOneByte(ch, pS);\r
-    if(NumConv != -2)\r
-      break;\r
+  if(Src != NULL) {\r
+    if(*Src != 0) {\r
+      SrcEnd  = Src + Len;\r
+      while(Src < SrcEnd) {\r
+        ch = (unsigned char)*Src++;\r
+        NumConv = ProcessOneByte(ch, pS);\r
+        if(NumConv != -2) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+    else if(Dest != NULL) {\r
+      *Dest = 0;\r
+    }\r
   }\r
   if((NumConv > 0) && (Dest != NULL)) {\r
     Dest[0] = pS->D[0];\r
@@ -416,14 +421,6 @@ EncodeUtf8(char *Dest, wchar_t ch)
   */\r
   if(Dest != NULL) {        // Save character if Dest is not NULL\r
     memcpy(Dest, Buff, NumInBuff);\r
-\r
-    if(ch != 0) {\r
-      // Terminate the destination string.\r
-      Dest[NumInBuff] = '\0';\r
-    }\r
-    else {\r
-      NumInBuff = 0;\r
-    }\r
   }\r
   return NumInBuff;             // Tell the caller\r
 }\r
@@ -646,7 +643,7 @@ mbsrtowcs(
   size_t        RetVal = 0;\r
   const char   *MySrc;\r
 \r
-  if((src == NULL) || (*src == NULL) || (**src == '\0')) {\r
+  if((src == NULL) || (*src == NULL)) {\r
     return 0;\r
   }\r
 \r
@@ -855,7 +852,7 @@ wctomb(
 }\r
 \r
 /** The wcsrtombs function converts a sequence of wide characters from the array\r
-    indirectly pointed to by Dest into a sequence of corresponding multibyte\r
+    indirectly pointed to by Src into a sequence of corresponding multibyte\r
     characters that begins in the conversion state described by the object\r
     pointed to by ps.\r
 \r
@@ -914,15 +911,16 @@ wcsrtombs(
     return (0);\r
 \r
   if (Dest == NULL) {\r
-    if(MaxBytes <= 0) {\r
-      MaxBytes = ASCII_STRING_MAX;\r
-    }\r
-    NumStored = EstimateWtoM(*Src, MaxBytes, NULL);\r
+    NumStored = EstimateWtoM(*Src, ASCII_STRING_MAX, NULL);\r
   }\r
   else {\r
-    while (OneWcToMcLen(InCh = *(*Src)++) <= MaxBytes) {\r
+    if((MaxBytes < 0) || (MaxBytes > ASCII_STRING_MAX)) {\r
+      MaxBytes = ASCII_STRING_MAX;\r
+    }\r
+    while ((MaxBytes > 0) && (OneWcToMcLen(InCh = *(*Src)++) <= MaxBytes)) {\r
       if(InCh == 0) {\r
         *Src = NULL;\r
+        *Dest = 0;      // NUL terminate Dest string, but don't count the NUL\r
         break;\r
       }\r
       count = (int)wcrtomb(Dest, InCh, NULL);\r