]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/String.c
MdePkg/BaseLib: Use PcdSpeculationBarrierType
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
index 07c0562f3bfc488d9ec216ae9dbfe8e99fd2c90d..32e189791cb8716cd543a2b7231dc6ee51b46892 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
-  Unicode and ASCII string primatives.\r
+  Unicode and ASCII string primitives.\r
 \r
-  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -73,7 +67,7 @@ StrCpy (
 /**\r
   [ATTENTION] This function will be deprecated for security reason.\r
 \r
-  Copies up to a specified length from one Null-terminated Unicode string  to \r
+  Copies up to a specified length from one Null-terminated Unicode string  to\r
   another Null-terminated Unicode string and returns the new Unicode string.\r
 \r
   This function copies the contents of the Unicode string Source to the Unicode\r
@@ -89,7 +83,7 @@ StrCpy (
   If Length > 0 and Source is NULL, then ASSERT().\r
   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If Source and Destination overlap, then ASSERT().\r
-  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than \r
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
   PcdMaximumUnicodeStringLength, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
@@ -188,7 +182,7 @@ StrLen (
   Returns the size of a Null-terminated Unicode string in bytes, including the\r
   Null terminator.\r
 \r
-  This function returns the size, in bytes, of the Null-terminated Unicode string \r
+  This function returns the size, in bytes, of the Null-terminated Unicode string\r
   specified by String.\r
 \r
   If String is NULL, then ASSERT().\r
@@ -262,7 +256,7 @@ StrCmp (
 /**\r
   Compares up to a specified length the contents of two Null-terminated Unicode strings,\r
   and returns the difference between the first mismatched Unicode characters.\r
-  \r
+\r
   This function compares the Null-terminated Unicode string FirstString to the\r
   Null-terminated Unicode string SecondString. At most, Length Unicode\r
   characters will be compared. If Length is 0, then 0 is returned. If\r
@@ -315,6 +309,7 @@ StrnCmp (
   }\r
 \r
   while ((*FirstString != L'\0') &&\r
+         (*SecondString != L'\0') &&\r
          (*FirstString == *SecondString) &&\r
          (Length > 1)) {\r
     FirstString++;\r
@@ -381,8 +376,8 @@ StrCat (
 /**\r
   [ATTENTION] This function will be deprecated for security reason.\r
 \r
-  Concatenates up to a specified length one Null-terminated Unicode to the end \r
-  of another Null-terminated Unicode string, and returns the concatenated \r
+  Concatenates up to a specified length one Null-terminated Unicode to the end\r
+  of another Null-terminated Unicode string, and returns the concatenated\r
   Unicode string.\r
 \r
   This function concatenates two Null-terminated Unicode strings. The contents\r
@@ -398,7 +393,7 @@ StrCat (
   If Length > 0 and Source is NULL, then ASSERT().\r
   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If Source and Destination overlap, then ASSERT().\r
-  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than \r
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
   PcdMaximumUnicodeStringLength, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
   than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
@@ -491,13 +486,13 @@ StrStr (
   while (*String != L'\0') {\r
     SearchStringTmp = SearchString;\r
     FirstMatch = String;\r
-    \r
-    while ((*String == *SearchStringTmp) \r
+\r
+    while ((*String == *SearchStringTmp)\r
             && (*String != L'\0')) {\r
       String++;\r
       SearchStringTmp++;\r
-    } \r
-    \r
+    }\r
+\r
     if (*SearchStringTmp == L'\0') {\r
       return (CHAR16 *) FirstMatch;\r
     }\r
@@ -515,7 +510,7 @@ StrStr (
 /**\r
   Check if a Unicode character is a decimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
+  This internal function checks if a Unicode character is a\r
   decimal character. The valid decimal character is from\r
   L'0' to L'9'.\r
 \r
@@ -535,7 +530,7 @@ InternalIsDecimalDigitCharacter (
 }\r
 \r
 /**\r
-  Convert a Unicode character to upper case only if \r
+  Convert a Unicode character to upper case only if\r
   it maps to a valid small-case ASCII character.\r
 \r
   This internal function only deal with Unicode character\r
@@ -551,7 +546,7 @@ InternalIsDecimalDigitCharacter (
 **/\r
 CHAR16\r
 EFIAPI\r
-InternalCharToUpper (\r
+CharToUpper (\r
   IN      CHAR16                    Char\r
   )\r
 {\r
@@ -567,7 +562,7 @@ InternalCharToUpper (
 \r
   This internal function only deal with Unicode character\r
   which maps to a valid hexadecimal ASII character, i.e.\r
-  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other \r
+  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
   Unicode character, the value returned does not make sense.\r
 \r
   @param  Char  The character to convert.\r
@@ -585,14 +580,14 @@ InternalHexCharToUintn (
     return Char - L'0';\r
   }\r
 \r
-  return (UINTN) (10 + InternalCharToUpper (Char) - L'A');\r
+  return (10 + CharToUpper (Char) - L'A');\r
 }\r
 \r
 /**\r
   Check if a Unicode character is a hexadecimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
-  decimal character.  The valid hexadecimal character is \r
+  This internal function checks if a Unicode character is a\r
+  decimal character.  The valid hexadecimal character is\r
   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
 \r
 \r
@@ -637,7 +632,7 @@ InternalIsHexaDecimalDigitCharacter (
   If String has no pad spaces or valid decimal digits,\r
   then 0 is returned.\r
   If the number represented by String overflows according\r
-  to the range defined by UINTN, then ASSERT().\r
+  to the range defined by UINTN, then MAX_UINTN is returned.\r
 \r
   If PcdMaximumUnicodeStringLength is not zero, and String contains\r
   more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
@@ -655,40 +650,8 @@ StrDecimalToUintn (
   )\r
 {\r
   UINTN     Result;\r
-  \r
-  //\r
-  // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
-  // Length tests are performed inside StrLen().\r
-  //\r
-  ASSERT (StrSize (String) != 0);\r
-\r
-  //\r
-  // Ignore the pad spaces (space or tab)\r
-  //\r
-  while ((*String == L' ') || (*String == L'\t')) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == L'0') {\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
 \r
-  while (InternalIsDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));\r
-\r
-    Result = Result * 10 + (*String - L'0');\r
-    String++;\r
-  }\r
-  \r
+  StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -716,7 +679,7 @@ StrDecimalToUintn (
   If String has no pad spaces or valid decimal digits,\r
   then 0 is returned.\r
   If the number represented by String overflows according\r
-  to the range defined by UINT64, then ASSERT().\r
+  to the range defined by UINT64, then MAX_UINT64 is returned.\r
 \r
   If PcdMaximumUnicodeStringLength is not zero, and String contains\r
   more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
@@ -734,40 +697,8 @@ StrDecimalToUint64 (
   )\r
 {\r
   UINT64     Result;\r
-  \r
-  //\r
-  // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
-  // Length tests are performed inside StrLen().\r
-  //\r
-  ASSERT (StrSize (String) != 0);\r
-\r
-  //\r
-  // Ignore the pad spaces (space or tab)\r
-  //\r
-  while ((*String == L' ') || (*String == L'\t')) {\r
-    String++;\r
-  }\r
 \r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == L'0') {\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-\r
-  while (InternalIsDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));\r
-\r
-    Result = MultU64x32 (Result, 10) + (*String - L'0');\r
-    String++;\r
-  }\r
-  \r
+  StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -795,7 +726,7 @@ StrDecimalToUint64 (
   If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
   then zero is returned.\r
   If the number represented by String overflows according to the range defined by\r
-  UINTN, then ASSERT().\r
+  UINTN, then MAX_UINTN is returned.\r
 \r
   If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
@@ -814,49 +745,7 @@ StrHexToUintn (
 {\r
   UINTN     Result;\r
 \r
-  //\r
-  // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
-  // Length tests are performed inside StrLen().\r
-  //\r
-  ASSERT (StrSize (String) != 0);\r
-  \r
-  //\r
-  // Ignore the pad spaces (space or tab) \r
-  //\r
-  while ((*String == L' ') || (*String == L'\t')) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == L'0') {\r
-    String++;\r
-  }\r
-\r
-  if (InternalCharToUpper (*String) == L'X') {\r
-    if (*(String - 1) != L'0') {\r
-      return 0;\r
-    }\r
-    //\r
-    // Skip the 'X'\r
-    //\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-  \r
-  while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the Hex Number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));\r
-\r
-    Result = (Result << 4) + InternalHexCharToUintn (*String);\r
-    String++;\r
-  }\r
-\r
+  StrHexToUintnS (String, (CHAR16 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -885,7 +774,7 @@ StrHexToUintn (
   If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
   then zero is returned.\r
   If the number represented by String overflows according to the range defined by\r
-  UINT64, then ASSERT().\r
+  UINT64, then MAX_UINT64 is returned.\r
 \r
   If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
@@ -904,58 +793,14 @@ StrHexToUint64 (
 {\r
   UINT64    Result;\r
 \r
-  //\r
-  // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
-  // Length tests are performed inside StrLen().\r
-  //\r
-  ASSERT (StrSize (String) != 0);\r
-  \r
-  //\r
-  // Ignore the pad spaces (space or tab) \r
-  //\r
-  while ((*String == L' ') || (*String == L'\t')) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == L'0') {\r
-    String++;\r
-  }\r
-\r
-  if (InternalCharToUpper (*String) == L'X') {\r
-    ASSERT (*(String - 1) == L'0');\r
-    if (*(String - 1) != L'0') {\r
-      return 0;\r
-    }\r
-    //\r
-    // Skip the 'X'\r
-    //\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-  \r
-  while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the Hex Number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));\r
-\r
-    Result = LShiftU64 (Result, 4);\r
-    Result = Result + InternalHexCharToUintn (*String);\r
-    String++;\r
-  }\r
-\r
+  StrHexToUint64S (String, (CHAR16 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
 /**\r
   Check if a ASCII character is a decimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
+  This internal function checks if a Unicode character is a\r
   decimal character. The valid decimal character is from\r
   '0' to '9'.\r
 \r
@@ -977,8 +822,8 @@ InternalAsciiIsDecimalDigitCharacter (
 /**\r
   Check if a ASCII character is a hexadecimal character.\r
 \r
-  This internal function checks if a ASCII character is a \r
-  decimal character.  The valid hexadecimal character is \r
+  This internal function checks if a ASCII character is a\r
+  decimal character.  The valid hexadecimal character is\r
   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
 \r
 \r
@@ -1064,7 +909,7 @@ UnicodeStrToAsciiStr (
   ReturnValue = Destination;\r
   while (*Source != '\0') {\r
     //\r
-    // If any Unicode characters in Source contain \r
+    // If any Unicode characters in Source contain\r
     // non-zero value in the upper 8 bits, then ASSERT().\r
     //\r
     ASSERT (*Source < 0x100);\r
@@ -1136,7 +981,7 @@ AsciiStrCpy (
 /**\r
   [ATTENTION] This function will be deprecated for security reason.\r
 \r
-  Copies up to a specified length one Null-terminated ASCII string to another \r
+  Copies up to a specified length one Null-terminated ASCII string to another\r
   Null-terminated ASCII string and returns the new ASCII string.\r
 \r
   This function copies the contents of the ASCII string Source to the ASCII\r
@@ -1149,7 +994,7 @@ AsciiStrCpy (
   If Destination is NULL, then ASSERT().\r
   If Source is NULL, then ASSERT().\r
   If Source and Destination overlap, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, and Length is greater than \r
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
   PcdMaximumAsciiStringLength, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
@@ -1325,12 +1170,12 @@ AsciiStrCmp (
 \r
   @param  Chr   one Ascii character\r
 \r
-  @return The uppercase value of Ascii character \r
+  @return The uppercase value of Ascii character\r
 \r
 **/\r
 CHAR8\r
 EFIAPI\r
-InternalBaseLibAsciiToUpper (\r
+AsciiCharToUpper (\r
   IN      CHAR8                     Chr\r
   )\r
 {\r
@@ -1342,7 +1187,7 @@ InternalBaseLibAsciiToUpper (
 \r
   This internal function only deal with Unicode character\r
   which maps to a valid hexadecimal ASII character, i.e.\r
-  '0' to '9', 'a' to 'f' or 'A' to 'F'. For other \r
+  '0' to '9', 'a' to 'f' or 'A' to 'F'. For other\r
   ASCII character, the value returned does not make sense.\r
 \r
   @param  Char  The character to convert.\r
@@ -1360,7 +1205,7 @@ InternalAsciiHexCharToUintn (
     return Char - '0';\r
   }\r
 \r
-  return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A');\r
+  return (10 + AsciiCharToUpper (Char) - 'A');\r
 }\r
 \r
 \r
@@ -1409,13 +1254,13 @@ AsciiStriCmp (
   ASSERT (AsciiStrSize (FirstString));\r
   ASSERT (AsciiStrSize (SecondString));\r
 \r
-  UpperFirstString  = InternalBaseLibAsciiToUpper (*FirstString);\r
-  UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
-  while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
+  UpperFirstString  = AsciiCharToUpper (*FirstString);\r
+  UpperSecondString = AsciiCharToUpper (*SecondString);\r
+  while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {\r
     FirstString++;\r
     SecondString++;\r
-    UpperFirstString  = InternalBaseLibAsciiToUpper (*FirstString);\r
-    UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
+    UpperFirstString  = AsciiCharToUpper (*FirstString);\r
+    UpperSecondString = AsciiCharToUpper (*SecondString);\r
   }\r
 \r
   return UpperFirstString - UpperSecondString;\r
@@ -1434,7 +1279,7 @@ AsciiStriCmp (
 \r
   If Length > 0 and FirstString is NULL, then ASSERT().\r
   If Length > 0 and SecondString is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, and Length is greater than \r
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
   PcdMaximumAsciiStringLength, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than\r
   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
@@ -1446,7 +1291,7 @@ AsciiStriCmp (
   @param  FirstString   A pointer to a Null-terminated ASCII string.\r
   @param  SecondString  A pointer to a Null-terminated ASCII string.\r
   @param  Length        The maximum number of ASCII characters for compare.\r
-  \r
+\r
   @retval ==0       FirstString is identical to SecondString.\r
   @retval !=0       FirstString is not identical to SecondString.\r
 \r
@@ -1474,6 +1319,7 @@ AsciiStrnCmp (
   }\r
 \r
   while ((*FirstString != '\0') &&\r
+         (*SecondString != '\0') &&\r
          (*FirstString == *SecondString) &&\r
          (Length > 1)) {\r
     FirstString++;\r
@@ -1534,8 +1380,8 @@ AsciiStrCat (
 /**\r
   [ATTENTION] This function will be deprecated for security reason.\r
 \r
-  Concatenates up to a specified length one Null-terminated ASCII string to \r
-  the end of another Null-terminated ASCII string, and returns the \r
+  Concatenates up to a specified length one Null-terminated ASCII string to\r
+  the end of another Null-terminated ASCII string, and returns the\r
   concatenated ASCII string.\r
 \r
   This function concatenates two Null-terminated ASCII strings. The contents\r
@@ -1639,13 +1485,13 @@ AsciiStrStr (
   while (*String != '\0') {\r
     SearchStringTmp = SearchString;\r
     FirstMatch = String;\r
-    \r
-    while ((*String == *SearchStringTmp) \r
+\r
+    while ((*String == *SearchStringTmp)\r
             && (*String != '\0')) {\r
       String++;\r
       SearchStringTmp++;\r
-    } \r
-    \r
+    }\r
+\r
     if (*SearchStringTmp == '\0') {\r
       return (CHAR8 *) FirstMatch;\r
     }\r
@@ -1679,7 +1525,7 @@ AsciiStrStr (
   If String has only pad spaces, then 0 is returned.\r
   If String has no pad spaces or valid decimal digits, then 0 is returned.\r
   If the number represented by String overflows according to the range defined by\r
-  UINTN, then ASSERT().\r
+  UINTN, then MAX_UINTN is returned.\r
   If String is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
   PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
@@ -1697,39 +1543,8 @@ AsciiStrDecimalToUintn (
   )\r
 {\r
   UINTN     Result;\r
-  \r
-  //\r
-  // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
-  //\r
-  ASSERT (AsciiStrSize (String) != 0);\r
-\r
-  //\r
-  // Ignore the pad spaces (space or tab)\r
-  //\r
-  while ((*String == ' ') || (*String == '\t' )) {\r
-    String++;\r
-  }\r
 \r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == '0') {\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-\r
-  while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));\r
-\r
-    Result = Result * 10 + (*String - '0');\r
-    String++;\r
-  }\r
-  \r
+  AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -1753,7 +1568,7 @@ AsciiStrDecimalToUintn (
   If String has only pad spaces, then 0 is returned.\r
   If String has no pad spaces or valid decimal digits, then 0 is returned.\r
   If the number represented by String overflows according to the range defined by\r
-  UINT64, then ASSERT().\r
+  UINT64, then MAX_UINT64 is returned.\r
   If String is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
   PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
@@ -1771,39 +1586,8 @@ AsciiStrDecimalToUint64 (
   )\r
 {\r
   UINT64     Result;\r
-  \r
-  //\r
-  // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
-  //\r
-  ASSERT (AsciiStrSize (String) != 0);\r
-\r
-  //\r
-  // Ignore the pad spaces (space or tab)\r
-  //\r
-  while ((*String == ' ') || (*String == '\t' )) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == '0') {\r
-    String++;\r
-  }\r
 \r
-  Result = 0;\r
-\r
-  while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));\r
-\r
-    Result = MultU64x32 (Result, 10) + (*String - '0');\r
-    String++;\r
-  }\r
-  \r
+  AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -1830,7 +1614,7 @@ AsciiStrDecimalToUint64 (
   0 is returned.\r
 \r
   If the number represented by String overflows according to the range defined by UINTN,\r
-  then ASSERT().\r
+  then MAX_UINTN is returned.\r
   If String is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero,\r
   and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
@@ -1849,49 +1633,7 @@ AsciiStrHexToUintn (
 {\r
   UINTN     Result;\r
 \r
-  //\r
-  // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
-  //\r
-  ASSERT (AsciiStrSize (String) != 0);\r
-  \r
-  //\r
-  // Ignore the pad spaces (space or tab) \r
-  //\r
-  while ((*String == ' ') || (*String == '\t' )) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == '0') {\r
-    String++;\r
-  }\r
-\r
-  if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
-    ASSERT (*(String - 1) == '0');\r
-    if (*(String - 1) != '0') {\r
-      return 0;\r
-    }\r
-    //\r
-    // Skip the 'X'\r
-    //\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-  \r
-  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the Hex Number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));\r
-\r
-    Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);\r
-    String++;\r
-  }\r
-\r
+  AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -1919,7 +1661,7 @@ AsciiStrHexToUintn (
   0 is returned.\r
 \r
   If the number represented by String overflows according to the range defined by UINT64,\r
-  then ASSERT().\r
+  then MAX_UINT64 is returned.\r
   If String is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero,\r
   and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
@@ -1938,53 +1680,7 @@ AsciiStrHexToUint64 (
 {\r
   UINT64    Result;\r
 \r
-  //\r
-  // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
-  //\r
-  ASSERT (AsciiStrSize (String) != 0);\r
-  \r
-  //\r
-  // Ignore the pad spaces (space or tab) and leading Zeros\r
-  //\r
-  //\r
-  // Ignore the pad spaces (space or tab) \r
-  //\r
-  while ((*String == ' ') || (*String == '\t' )) {\r
-    String++;\r
-  }\r
-\r
-  //\r
-  // Ignore leading Zeros after the spaces\r
-  //\r
-  while (*String == '0') {\r
-    String++;\r
-  }\r
-\r
-  if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
-    ASSERT (*(String - 1) == '0');\r
-    if (*(String - 1) != '0') {\r
-      return 0;\r
-    }\r
-    //\r
-    // Skip the 'X'\r
-    //\r
-    String++;\r
-  }\r
-\r
-  Result = 0;\r
-  \r
-  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
-    //\r
-    // If the Hex Number represented by String overflows according \r
-    // to the range defined by UINTN, then ASSERT().\r
-    //\r
-    ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));\r
-\r
-    Result = LShiftU64 (Result, 4);\r
-    Result = Result + InternalAsciiHexCharToUintn (*String);\r
-    String++;\r
-  }\r
-\r
+  AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result);\r
   return Result;\r
 }\r
 \r
@@ -2044,7 +1740,7 @@ AsciiStrToUnicodeStr (
 \r
   ReturnValue = Destination;\r
   while (*Source != '\0') {\r
-    *(Destination++) = (CHAR16) *(Source++);\r
+    *(Destination++) = (CHAR16)(UINT8) *(Source++);\r
   }\r
   //\r
   // End the Destination with a NULL.\r
@@ -2061,6 +1757,337 @@ AsciiStrToUnicodeStr (
 \r
 #endif\r
 \r
+//\r
+// The basis for Base64 encoding is RFC 4686 https://tools.ietf.org/html/rfc4648\r
+//\r
+// RFC 4686 has a number of MAY and SHOULD cases.  This implementation chooses\r
+// the more restrictive versions for security concerns (see RFC 4686 section 3.3).\r
+//\r
+// A invalid character, if encountered during the decode operation, causes the data\r
+// to be rejected. In addition, the '=' padding character is only allowed at the end\r
+// of the Base64 encoded string.\r
+//\r
+#define BAD_V  99\r
+\r
+STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
+                                "abcdefghijklmnopqrstuvwxyz"\r
+                                "0123456789+/";\r
+\r
+STATIC UINT8 DecodingTable[] = {\r
+  //\r
+  // Valid characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\r
+  // Also, set '=' as a zero for decoding\r
+  // 0  ,            1,           2,           3,            4,           5,            6,           7,           8,            9,           a,            b,            c,           d,            e,            f\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //   0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  10\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,     62,  BAD_V,  BAD_V,  BAD_V,     63,   //  20\r
+     52,     53,     54,     55,     56,     57,     58,     59,     60,     61,  BAD_V,  BAD_V,  BAD_V,      0,  BAD_V,  BAD_V,   //  30\r
+  BAD_V,      0,      1,      2,      3,      4,      5,      6,      7,      8,      9,     10,     11,     12,     13,     14,   //  40\r
+     15,     16,     17,     18,     19,     20,     21,     22,     23,     24,     25,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  50\r
+  BAD_V,     26,     27,     28,     29,     30,     31,     32,     33,     34,     35,     36,     37,     38,     39,     40,   //  60\r
+     41,     42,     43,     44,     45,     46,     47,     48,     49,     50,     51,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  70\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  80\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  90\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  a0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  b0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  c0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  d0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  d0\r
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V    //  f0\r
+};\r
+\r
+/**\r
+  Convert binary data to a Base64 encoded ascii string based on RFC4648.\r
+\r
+  Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.\r
+  The Ascii string is produced by converting the data string specified by Source and SourceLength.\r
+\r
+  @param Source            Input UINT8 data\r
+  @param SourceLength      Number of UINT8 bytes of data\r
+  @param Destination       Pointer to output string buffer\r
+  @param DestinationSize   Size of ascii buffer. Set to 0 to get the size needed.\r
+                           Caller is responsible for passing in buffer of DestinationSize\r
+\r
+  @retval RETURN_SUCCESS             When ascii buffer is filled in.\r
+  @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.\r
+  @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL    If SourceLength is 0 and DestinationSize is <1.\r
+  @retval RETURN_BUFFER_TOO_SMALL    If Destination is NULL or DestinationSize is smaller than required buffersize.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+Base64Encode (\r
+  IN  CONST UINT8  *Source,\r
+  IN        UINTN   SourceLength,\r
+  OUT       CHAR8  *Destination   OPTIONAL,\r
+  IN OUT    UINTN  *DestinationSize\r
+  )\r
+{\r
+\r
+  UINTN          RequiredSize;\r
+  UINTN          Left;\r
+\r
+  //\r
+  // Check pointers, and SourceLength is valid\r
+  //\r
+  if ((Source == NULL) || (DestinationSize == NULL)) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Allow for RFC 4648 test vector 1\r
+  //\r
+  if (SourceLength == 0) {\r
+    if (*DestinationSize < 1) {\r
+      *DestinationSize = 1;\r
+      return RETURN_BUFFER_TOO_SMALL;\r
+    }\r
+    *DestinationSize = 1;\r
+    *Destination = '\0';\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Check if SourceLength or  DestinationSize is valid\r
+  //\r
+  if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // 4 ascii per 3 bytes + NULL\r
+  //\r
+  RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;\r
+  if ((Destination == NULL) || *DestinationSize < RequiredSize) {\r
+    *DestinationSize = RequiredSize;\r
+    return RETURN_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  Left = SourceLength;\r
+\r
+  //\r
+  // Encode 24 bits (three bytes) into 4 ascii characters\r
+  //\r
+  while (Left >= 3) {\r
+\r
+    *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2 ];\r
+    *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+    *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];\r
+    *Destination++ = EncodingTable[( Source[2] & 0x3f)];\r
+    Left -= 3;\r
+    Source += 3;\r
+  }\r
+\r
+  //\r
+  // Handle the remainder, and add padding '=' characters as necessary.\r
+  //\r
+  switch (Left) {\r
+    case 0:\r
+\r
+      //\r
+      // No bytes Left, done.\r
+      //\r
+      break;\r
+    case 1:\r
+\r
+      //\r
+      // One more data byte, two pad characters\r
+      //\r
+      *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];\r
+      *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];\r
+      *Destination++ = '=';\r
+      *Destination++ = '=';\r
+      break;\r
+    case 2:\r
+\r
+      //\r
+      // Two more data bytes, and one pad character\r
+      //\r
+      *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];\r
+      *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+      *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];\r
+      *Destination++ = '=';\r
+      break;\r
+    }\r
+  //\r
+  // Add terminating NULL\r
+  //\r
+  *Destination = '\0';\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Convert Base64 ascii string to binary data based on RFC4648.\r
+\r
+  Produce Null-terminated binary data in the output buffer specified by Destination and DestinationSize.\r
+  The binary data is produced by converting the Base64 ascii string specified by Source and SourceLength.\r
+\r
+  @param Source            Input ASCII characters\r
+  @param SourceLength      Number of ASCII characters\r
+  @param Destination       Pointer to output buffer\r
+  @param DestinationSize   Caller is responsible for passing in buffer of at least DestinationSize.\r
+                           Set 0 to get the size needed. Set to bytes stored on return.\r
+\r
+  @retval RETURN_SUCCESS             When binary buffer is filled in.\r
+  @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.\r
+  @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS -(UINTN)Destination ).\r
+  @retval RETURN_INVALID_PARAMETER   If there is any invalid character in input stream.\r
+  @retval RETURN_BUFFER_TOO_SMALL    If buffer length is smaller than required buffer size.\r
+ **/\r
+RETURN_STATUS\r
+EFIAPI\r
+Base64Decode (\r
+  IN  CONST CHAR8  *Source,\r
+  IN        UINTN   SourceLength,\r
+  OUT       UINT8  *Destination   OPTIONAL,\r
+  IN OUT    UINTN  *DestinationSize\r
+  )\r
+{\r
+\r
+  UINT32   Value;\r
+  CHAR8    Chr;\r
+  INTN     BufferSize;\r
+  UINTN    SourceIndex;\r
+  UINTN    DestinationIndex;\r
+  UINTN    Index;\r
+  UINTN    ActualSourceLength;\r
+\r
+  //\r
+  // Check pointers are not NULL\r
+  //\r
+  if ((Source == NULL) || (DestinationSize == NULL)) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check if SourceLength or  DestinationSize is valid\r
+  //\r
+  if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  ActualSourceLength = 0;\r
+  BufferSize = 0;\r
+\r
+  //\r
+  // Determine the actual number of valid characters in the string.\r
+  // All invalid characters except selected white space characters,\r
+  // will cause the Base64 string to be rejected. White space to allow\r
+  // properly formatted XML will be ignored.\r
+  //\r
+  // See section 3.3 of RFC 4648.\r
+  //\r
+  for (SourceIndex = 0; SourceIndex < SourceLength; SourceIndex++) {\r
+\r
+    //\r
+    // '=' is part of the quantum\r
+    //\r
+    if (Source[SourceIndex] == '=') {\r
+      ActualSourceLength++;\r
+      BufferSize--;\r
+\r
+      //\r
+      // Only two '=' characters can be valid.\r
+      //\r
+      if (BufferSize < -2) {\r
+        return RETURN_INVALID_PARAMETER;\r
+      }\r
+    }\r
+    else {\r
+      Chr = Source[SourceIndex];\r
+      if (BAD_V != DecodingTable[(UINT8) Chr]) {\r
+\r
+        //\r
+        // The '=' characters are only valid at the end, so any\r
+        // valid character after an '=', will be flagged as an error.\r
+        //\r
+        if (BufferSize < 0) {\r
+          return RETURN_INVALID_PARAMETER;\r
+        }\r
+          ActualSourceLength++;\r
+      }\r
+        else {\r
+\r
+        //\r
+        // The reset of the decoder will ignore all invalid characters allowed here.\r
+        // Ignoring selected white space is useful.  In this case, the decoder will\r
+        // ignore ' ', '\t', '\n', and '\r'.\r
+        //\r
+        if ((Chr != ' ') &&(Chr != '\t') &&(Chr != '\n') &&(Chr != '\r')) {\r
+          return RETURN_INVALID_PARAMETER;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // The Base64 character string must be a multiple of 4 character quantums.\r
+  //\r
+  if (ActualSourceLength % 4 != 0) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  BufferSize += ActualSourceLength / 4 * 3;\r
+    if (BufferSize < 0) {\r
+      return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // BufferSize is >= 0\r
+  //\r
+  if ((Destination == NULL) || (*DestinationSize < (UINTN) BufferSize)) {\r
+    *DestinationSize = BufferSize;\r
+    return RETURN_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // If no decodable characters, return a size of zero. RFC 4686 test vector 1.\r
+  //\r
+  if (ActualSourceLength == 0) {\r
+    *DestinationSize = 0;\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Input data is verified to be a multiple of 4 valid charcters.  Process four\r
+  // characters at a time. Uncounted (ie. invalid)  characters will be ignored.\r
+  //\r
+  for (SourceIndex = 0, DestinationIndex = 0; (SourceIndex < SourceLength) && (DestinationIndex < *DestinationSize); ) {\r
+    Value = 0;\r
+\r
+    //\r
+    // Get 24 bits of data from 4 input characters, each character representing 6 bits\r
+    //\r
+    for (Index = 0; Index < 4; Index++) {\r
+      do {\r
+      Chr = DecodingTable[(UINT8) Source[SourceIndex++]];\r
+      } while (Chr == BAD_V);\r
+      Value <<= 6;\r
+      Value |= (UINT32)Chr;\r
+    }\r
+\r
+    //\r
+    // Store 3 bytes of binary data (24 bits)\r
+    //\r
+    *Destination++ = (UINT8) (Value >> 16);\r
+    DestinationIndex++;\r
+\r
+    //\r
+    // Due to the '=' special cases for the two bytes at the end,\r
+    // we have to check the length and not store the padding data\r
+    //\r
+    if (DestinationIndex++ < *DestinationSize) {\r
+      *Destination++ = (UINT8) (Value >>  8);\r
+    }\r
+    if (DestinationIndex++ < *DestinationSize) {\r
+      *Destination++ = (UINT8) Value;\r
+    }\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
 /**\r
   Converts an 8-bit value to an 8-bit BCD value.\r
 \r