]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/SafeString.c
MdePkg BaseLib: Convert Ia32/Wbinvd.asm to NASM
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
index b0e1ce72e2986349f85e1ea8cb7af2cb7d6e9d6a..ede2f4c5b433f4d0057185a35afefe35f54524b3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Safe String functions.\r
 \r
-  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2016, 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
@@ -106,6 +106,8 @@ InternalSafeStringNoAsciiStrOverlap (
 /**\r
   Returns the length of a Null-terminated Unicode string.\r
 \r
+  This function is similar as strlen_s defined in C11.\r
+\r
   If String is not aligned on a 16-bit boundary, then ASSERT().\r
 \r
   @param  String   A pointer to a Null-terminated Unicode string.\r
@@ -151,10 +153,14 @@ StrnLenS (
   Copies the string pointed to by Source (including the terminating null char)\r
   to the array pointed to by Destination.\r
 \r
+  This function is similar as strcpy_s defined in C11.\r
+\r
   If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
   If Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Unicode string.\r
   @param  DestMax                  The maximum number of Destination Unicode\r
                                    char, including terminating null char.\r
@@ -229,10 +235,14 @@ StrCpyS (
   Source to the array pointed to by Destination. If no null char is copied from\r
   Source, then Destination[Length] is always set to null.\r
 \r
+  This function is similar as strncpy_s defined in C11.\r
+\r
   If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Unicode string.\r
   @param  DestMax                  The maximum number of Destination Unicode\r
                                    char, including terminating null char.\r
@@ -318,10 +328,14 @@ StrnCpyS (
   Appends a copy of the string pointed to by Source (including the terminating\r
   null char) to the end of the string pointed to by Destination.\r
 \r
+  This function is similar as strcat_s defined in C11.\r
+\r
   If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
   If Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Unicode string.\r
   @param  DestMax                  The maximum number of Destination Unicode\r
                                    char, including terminating null char.\r
@@ -415,10 +429,14 @@ StrCatS (
   copied from Source, then Destination[StrLen(Destination) + Length] is always\r
   set to null.\r
 \r
+  This function is similar as strncat_s defined in C11.\r
+\r
   If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
   If Source is not aligned on a 16-bit boundary, then ASSERT().\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Unicode string.\r
   @param  DestMax                  The maximum number of Destination Unicode\r
                                    char, including terminating null char.\r
@@ -520,6 +538,8 @@ StrnCatS (
 /**\r
   Returns the length of a Null-terminated Ascii string.\r
 \r
+  This function is similar as strlen_s defined in C11.\r
+\r
   @param  String   A pointer to a Null-terminated Ascii string.\r
   @param  MaxSize  The maximum number of Destination Ascii\r
                    char, including terminating null char.\r
@@ -561,8 +581,12 @@ AsciiStrnLenS (
   Copies the string pointed to by Source (including the terminating null char)\r
   to the array pointed to by Destination.\r
 \r
+  This function is similar as strcpy_s defined in C11.\r
+\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Ascii string.\r
   @param  DestMax                  The maximum number of Destination Ascii\r
                                    char, including terminating null char.\r
@@ -634,8 +658,12 @@ AsciiStrCpyS (
   Source to the array pointed to by Destination. If no null char is copied from\r
   Source, then Destination[Length] is always set to null.\r
 \r
+  This function is similar as strncpy_s defined in C11.\r
+\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Ascii string.\r
   @param  DestMax                  The maximum number of Destination Ascii\r
                                    char, including terminating null char.\r
@@ -718,8 +746,12 @@ AsciiStrnCpyS (
   Appends a copy of the string pointed to by Source (including the terminating\r
   null char) to the end of the string pointed to by Destination.\r
 \r
+  This function is similar as strcat_s defined in C11.\r
+\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Ascii string.\r
   @param  DestMax                  The maximum number of Destination Ascii\r
                                    char, including terminating null char.\r
@@ -810,8 +842,12 @@ AsciiStrCatS (
   copied from Source, then Destination[StrLen(Destination) + Length] is always\r
   set to null.\r
 \r
+  This function is similar as strncat_s defined in C11.\r
+\r
   If an error would be returned, then the function will also ASSERT().\r
 \r
+  If an error is returned, then the Destination is unmodified.\r
+\r
   @param  Destination              A pointer to a Null-terminated Ascii string.\r
   @param  DestMax                  The maximum number of Destination Ascii\r
                                    char, including terminating null char.\r
@@ -906,3 +942,197 @@ AsciiStrnCatS (
 \r
   return RETURN_SUCCESS;\r
 }\r
+\r
+/**\r
+  Convert a Null-terminated Unicode string to a Null-terminated\r
+  ASCII string.\r
+\r
+  This function is similar to AsciiStrCpyS.\r
+\r
+  This function converts the content of the Unicode string Source\r
+  to the ASCII string Destination by copying the lower 8 bits of\r
+  each Unicode character. The function terminates the ASCII string\r
+  Destination by appending a Null-terminator character at the end.\r
+\r
+  The caller is responsible to make sure Destination points to a buffer with size\r
+  equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.\r
+\r
+  If any Unicode characters in Source contain non-zero value in\r
+  the upper 8 bits, then ASSERT().\r
+\r
+  If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\r
+\r
+  @param  Source        The pointer to a Null-terminated Unicode string.\r
+  @param  Destination   The pointer to a Null-terminated ASCII string.\r
+  @param  DestMax       The maximum number of Destination Ascii\r
+                        char, including terminating null char.\r
+\r
+  @retval RETURN_SUCCESS           String is converted.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than\r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than\r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UnicodeStrToAsciiStrS (\r
+  IN      CONST CHAR16              *Source,\r
+  OUT     CHAR8                     *Destination,\r
+  IN      UINTN                     DestMax\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  ASSERT (((UINTN) Source & BIT0) == 0);\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.\r
+  //\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. DestMax shall be greater than StrnLenS (Source, DestMax).\r
+  //\r
+  SourceLen = StrnLenS (Source, DestMax);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // convert string\r
+  //\r
+  while (*Source != '\0') {\r
+    //\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
+    *(Destination++) = (CHAR8) *(Source++);\r
+  }\r
+  *Destination = '\0';\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Convert one Null-terminated ASCII string to a Null-terminated\r
+  Unicode string.\r
+\r
+  This function is similar to StrCpyS.\r
+\r
+  This function converts the contents of the ASCII string Source to the Unicode\r
+  string Destination. The function terminates the Unicode string Destination by\r
+  appending a Null-terminator character at the end.\r
+\r
+  The caller is responsible to make sure Destination points to a buffer with size\r
+  equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
+\r
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+  If an error would be returned, then the function will also ASSERT().\r
+\r
+  If an error is returned, then the Destination is unmodified.\r
+\r
+  @param  Source        The pointer to a Null-terminated ASCII string.\r
+  @param  Destination   The pointer to a Null-terminated Unicode string.\r
+  @param  DestMax       The maximum number of Destination Unicode\r
+                        char, including terminating null char.\r
+\r
+  @retval RETURN_SUCCESS           String is converted.\r
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).\r
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
+                                   If Source is NULL.\r
+                                   If PcdMaximumUnicodeStringLength is not zero,\r
+                                    and DestMax is greater than\r
+                                    PcdMaximumUnicodeStringLength.\r
+                                   If PcdMaximumAsciiStringLength is not zero,\r
+                                    and DestMax is greater than\r
+                                    PcdMaximumAsciiStringLength.\r
+                                   If DestMax is 0.\r
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+AsciiStrToUnicodeStrS (\r
+  IN      CONST CHAR8               *Source,\r
+  OUT     CHAR16                    *Destination,\r
+  IN      UINTN                     DestMax\r
+  )\r
+{\r
+  UINTN            SourceLen;\r
+\r
+  ASSERT (((UINTN) Destination & BIT0) == 0);\r
+\r
+  //\r
+  // 1. Neither Destination nor Source shall be a null pointer.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.\r
+  //\r
+  if (RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+  if (ASCII_RSIZE_MAX != 0) {\r
+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // 3. DestMax shall not equal zero.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
+\r
+  //\r
+  // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
+  //\r
+  SourceLen = AsciiStrnLenS (Source, DestMax);\r
+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
+\r
+  //\r
+  // 5. Copying shall not take place between objects that overlap.\r
+  //\r
+  SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
+\r
+  //\r
+  // Convert string\r
+  //\r
+  while (*Source != '\0') {\r
+    *(Destination++) = (CHAR16)*(Source++);\r
+  }\r
+  *Destination = '\0';\r
+\r
+  return RETURN_SUCCESS;\r
+}\r