Home | History | Annotate | Download | only in BaseLib
      1 /** @file
      2   Safe String functions.
      3 
      4   Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Base.h>
     16 #include <Library/DebugLib.h>
     17 #include <Library/PcdLib.h>
     18 #include <Library/BaseLib.h>
     19 
     20 #define RSIZE_MAX  (PcdGet32 (PcdMaximumUnicodeStringLength))
     21 
     22 #define ASCII_RSIZE_MAX  (PcdGet32 (PcdMaximumAsciiStringLength))
     23 
     24 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status)  \
     25   do { \
     26     ASSERT (Expression); \
     27     if (!(Expression)) { \
     28       return Status; \
     29     } \
     30   } while (FALSE)
     31 
     32 /**
     33   Returns if 2 memory blocks are overlapped.
     34 
     35   @param  Base1  Base address of 1st memory block.
     36   @param  Size1  Size of 1st memory block.
     37   @param  Base2  Base address of 2nd memory block.
     38   @param  Size2  Size of 2nd memory block.
     39 
     40   @retval TRUE  2 memory blocks are overlapped.
     41   @retval FALSE 2 memory blocks are not overlapped.
     42 **/
     43 BOOLEAN
     44 InternalSafeStringIsOverlap (
     45   IN VOID    *Base1,
     46   IN UINTN   Size1,
     47   IN VOID    *Base2,
     48   IN UINTN   Size2
     49   )
     50 {
     51   if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
     52       (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
     53     return TRUE;
     54   }
     55   return FALSE;
     56 }
     57 
     58 /**
     59   Returns if 2 Unicode strings are not overlapped.
     60 
     61   @param  Str1   Start address of 1st Unicode string.
     62   @param  Size1  The number of char in 1st Unicode string,
     63                  including terminating null char.
     64   @param  Str2   Start address of 2nd Unicode string.
     65   @param  Size2  The number of char in 2nd Unicode string,
     66                  including terminating null char.
     67 
     68   @retval TRUE  2 Unicode strings are NOT overlapped.
     69   @retval FALSE 2 Unicode strings are overlapped.
     70 **/
     71 BOOLEAN
     72 InternalSafeStringNoStrOverlap (
     73   IN CHAR16  *Str1,
     74   IN UINTN   Size1,
     75   IN CHAR16  *Str2,
     76   IN UINTN   Size2
     77   )
     78 {
     79   return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
     80 }
     81 
     82 /**
     83   Returns if 2 Ascii strings are not overlapped.
     84 
     85   @param  Str1   Start address of 1st Ascii string.
     86   @param  Size1  The number of char in 1st Ascii string,
     87                  including terminating null char.
     88   @param  Str2   Start address of 2nd Ascii string.
     89   @param  Size2  The number of char in 2nd Ascii string,
     90                  including terminating null char.
     91 
     92   @retval TRUE  2 Ascii strings are NOT overlapped.
     93   @retval FALSE 2 Ascii strings are overlapped.
     94 **/
     95 BOOLEAN
     96 InternalSafeStringNoAsciiStrOverlap (
     97   IN CHAR8   *Str1,
     98   IN UINTN   Size1,
     99   IN CHAR8   *Str2,
    100   IN UINTN   Size2
    101   )
    102 {
    103   return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);
    104 }
    105 
    106 /**
    107   Returns the length of a Null-terminated Unicode string.
    108 
    109   This function is similar as strlen_s defined in C11.
    110 
    111   If String is not aligned on a 16-bit boundary, then ASSERT().
    112 
    113   @param  String   A pointer to a Null-terminated Unicode string.
    114   @param  MaxSize  The maximum number of Destination Unicode
    115                    char, including terminating null char.
    116 
    117   @retval 0        If String is NULL.
    118   @retval MaxSize  If there is no null character in the first MaxSize characters of String.
    119   @return The number of characters that percede the terminating null character.
    120 
    121 **/
    122 UINTN
    123 EFIAPI
    124 StrnLenS (
    125   IN CONST CHAR16              *String,
    126   IN UINTN                     MaxSize
    127   )
    128 {
    129   UINTN                             Length;
    130 
    131   ASSERT (((UINTN) String & BIT0) == 0);
    132 
    133   //
    134   // If String is a null pointer, then the StrnLenS function returns zero.
    135   //
    136   if (String == NULL) {
    137     return 0;
    138   }
    139 
    140   //
    141   // Otherwise, the StrnLenS function returns the number of characters that precede the
    142   // terminating null character. If there is no null character in the first MaxSize characters of
    143   // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
    144   // be accessed by StrnLenS.
    145   //
    146   Length = 0;
    147   while (String[Length] != 0) {
    148     if (Length >= MaxSize - 1) {
    149       return MaxSize;
    150     }
    151     Length++;
    152   }
    153   return Length;
    154 }
    155 
    156 /**
    157   Copies the string pointed to by Source (including the terminating null char)
    158   to the array pointed to by Destination.
    159 
    160   This function is similar as strcpy_s defined in C11.
    161 
    162   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    163   If Source is not aligned on a 16-bit boundary, then ASSERT().
    164   If an error would be returned, then the function will also ASSERT().
    165 
    166   If an error is returned, then the Destination is unmodified.
    167 
    168   @param  Destination              A pointer to a Null-terminated Unicode string.
    169   @param  DestMax                  The maximum number of Destination Unicode
    170                                    char, including terminating null char.
    171   @param  Source                   A pointer to a Null-terminated Unicode string.
    172 
    173   @retval RETURN_SUCCESS           String is copied.
    174   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
    175   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    176                                    If Source is NULL.
    177                                    If PcdMaximumUnicodeStringLength is not zero,
    178                                     and DestMax is greater than
    179                                     PcdMaximumUnicodeStringLength.
    180                                    If DestMax is 0.
    181   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    182 **/
    183 RETURN_STATUS
    184 EFIAPI
    185 StrCpyS (
    186   OUT CHAR16       *Destination,
    187   IN  UINTN        DestMax,
    188   IN  CONST CHAR16 *Source
    189   )
    190 {
    191   UINTN            SourceLen;
    192 
    193   ASSERT (((UINTN) Destination & BIT0) == 0);
    194   ASSERT (((UINTN) Source & BIT0) == 0);
    195 
    196   //
    197   // 1. Neither Destination nor Source shall be a null pointer.
    198   //
    199   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    200   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    201 
    202   //
    203   // 2. DestMax shall not be greater than RSIZE_MAX.
    204   //
    205   if (RSIZE_MAX != 0) {
    206     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    207   }
    208 
    209   //
    210   // 3. DestMax shall not equal zero.
    211   //
    212   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    213 
    214   //
    215   // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
    216   //
    217   SourceLen = StrnLenS (Source, DestMax);
    218   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    219 
    220   //
    221   // 5. Copying shall not take place between objects that overlap.
    222   //
    223   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    224 
    225   //
    226   // The StrCpyS function copies the string pointed to by Source (including the terminating
    227   // null character) into the array pointed to by Destination.
    228   //
    229   while (*Source != 0) {
    230     *(Destination++) = *(Source++);
    231   }
    232   *Destination = 0;
    233 
    234   return RETURN_SUCCESS;
    235 }
    236 
    237 /**
    238   Copies not more than Length successive char from the string pointed to by
    239   Source to the array pointed to by Destination. If no null char is copied from
    240   Source, then Destination[Length] is always set to null.
    241 
    242   This function is similar as strncpy_s defined in C11.
    243 
    244   If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
    245   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
    246   If an error would be returned, then the function will also ASSERT().
    247 
    248   If an error is returned, then the Destination is unmodified.
    249 
    250   @param  Destination              A pointer to a Null-terminated Unicode string.
    251   @param  DestMax                  The maximum number of Destination Unicode
    252                                    char, including terminating null char.
    253   @param  Source                   A pointer to a Null-terminated Unicode string.
    254   @param  Length                   The maximum number of Unicode characters to copy.
    255 
    256   @retval RETURN_SUCCESS           String is copied.
    257   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
    258                                    MIN(StrLen(Source), Length).
    259   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    260                                    If Source is NULL.
    261                                    If PcdMaximumUnicodeStringLength is not zero,
    262                                     and DestMax is greater than
    263                                     PcdMaximumUnicodeStringLength.
    264                                    If DestMax is 0.
    265   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    266 **/
    267 RETURN_STATUS
    268 EFIAPI
    269 StrnCpyS (
    270   OUT CHAR16       *Destination,
    271   IN  UINTN        DestMax,
    272   IN  CONST CHAR16 *Source,
    273   IN  UINTN        Length
    274   )
    275 {
    276   UINTN            SourceLen;
    277 
    278   ASSERT (((UINTN) Destination & BIT0) == 0);
    279   ASSERT (((UINTN) Source & BIT0) == 0);
    280 
    281   //
    282   // 1. Neither Destination nor Source shall be a null pointer.
    283   //
    284   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    285   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    286 
    287   //
    288   // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
    289   //
    290   if (RSIZE_MAX != 0) {
    291     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    292     SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    293   }
    294 
    295   //
    296   // 3. DestMax shall not equal zero.
    297   //
    298   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    299 
    300   //
    301   // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
    302   //
    303   SourceLen = StrnLenS (Source, DestMax);
    304   if (Length >= DestMax) {
    305     SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    306   }
    307 
    308   //
    309   // 5. Copying shall not take place between objects that overlap.
    310   //
    311   if (SourceLen > Length) {
    312     SourceLen = Length;
    313   }
    314   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    315 
    316   //
    317   // The StrnCpyS function copies not more than Length successive characters (characters that
    318   // follow a null character are not copied) from the array pointed to by Source to the array
    319   // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
    320   // character.
    321   //
    322   while ((*Source != 0) && (SourceLen > 0)) {
    323     *(Destination++) = *(Source++);
    324     SourceLen--;
    325   }
    326   *Destination = 0;
    327 
    328   return RETURN_SUCCESS;
    329 }
    330 
    331 /**
    332   Appends a copy of the string pointed to by Source (including the terminating
    333   null char) to the end of the string pointed to by Destination.
    334 
    335   This function is similar as strcat_s defined in C11.
    336 
    337   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    338   If Source is not aligned on a 16-bit boundary, then ASSERT().
    339   If an error would be returned, then the function will also ASSERT().
    340 
    341   If an error is returned, then the Destination is unmodified.
    342 
    343   @param  Destination              A pointer to a Null-terminated Unicode string.
    344   @param  DestMax                  The maximum number of Destination Unicode
    345                                    char, including terminating null char.
    346   @param  Source                   A pointer to a Null-terminated Unicode string.
    347 
    348   @retval RETURN_SUCCESS           String is appended.
    349   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    350                                    StrLen(Destination).
    351   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    352                                    greater than StrLen(Source).
    353   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    354                                    If Source is NULL.
    355                                    If PcdMaximumUnicodeStringLength is not zero,
    356                                     and DestMax is greater than
    357                                     PcdMaximumUnicodeStringLength.
    358                                    If DestMax is 0.
    359   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    360 **/
    361 RETURN_STATUS
    362 EFIAPI
    363 StrCatS (
    364   IN OUT CHAR16       *Destination,
    365   IN     UINTN        DestMax,
    366   IN     CONST CHAR16 *Source
    367   )
    368 {
    369   UINTN               DestLen;
    370   UINTN               CopyLen;
    371   UINTN               SourceLen;
    372 
    373   ASSERT (((UINTN) Destination & BIT0) == 0);
    374   ASSERT (((UINTN) Source & BIT0) == 0);
    375 
    376   //
    377   // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
    378   //
    379   DestLen = StrnLenS (Destination, DestMax);
    380   CopyLen = DestMax - DestLen;
    381 
    382   //
    383   // 1. Neither Destination nor Source shall be a null pointer.
    384   //
    385   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    386   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    387 
    388   //
    389   // 2. DestMax shall not be greater than RSIZE_MAX.
    390   //
    391   if (RSIZE_MAX != 0) {
    392     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    393   }
    394 
    395   //
    396   // 3. DestMax shall not equal zero.
    397   //
    398   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    399 
    400   //
    401   // 4. CopyLen shall not equal zero.
    402   //
    403   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    404 
    405   //
    406   // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
    407   //
    408   SourceLen = StrnLenS (Source, CopyLen);
    409   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    410 
    411   //
    412   // 6. Copying shall not take place between objects that overlap.
    413   //
    414   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    415 
    416   //
    417   // The StrCatS function appends a copy of the string pointed to by Source (including the
    418   // terminating null character) to the end of the string pointed to by Destination. The initial character
    419   // from Source overwrites the null character at the end of Destination.
    420   //
    421   Destination = Destination + DestLen;
    422   while (*Source != 0) {
    423     *(Destination++) = *(Source++);
    424   }
    425   *Destination = 0;
    426 
    427   return RETURN_SUCCESS;
    428 }
    429 
    430 /**
    431   Appends not more than Length successive char from the string pointed to by
    432   Source to the end of the string pointed to by Destination. If no null char is
    433   copied from Source, then Destination[StrLen(Destination) + Length] is always
    434   set to null.
    435 
    436   This function is similar as strncat_s defined in C11.
    437 
    438   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    439   If Source is not aligned on a 16-bit boundary, then ASSERT().
    440   If an error would be returned, then the function will also ASSERT().
    441 
    442   If an error is returned, then the Destination is unmodified.
    443 
    444   @param  Destination              A pointer to a Null-terminated Unicode string.
    445   @param  DestMax                  The maximum number of Destination Unicode
    446                                    char, including terminating null char.
    447   @param  Source                   A pointer to a Null-terminated Unicode string.
    448   @param  Length                   The maximum number of Unicode characters to copy.
    449 
    450   @retval RETURN_SUCCESS           String is appended.
    451   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    452                                    StrLen(Destination).
    453   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    454                                    greater than MIN(StrLen(Source), Length).
    455   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    456                                    If Source is NULL.
    457                                    If PcdMaximumUnicodeStringLength is not zero,
    458                                     and DestMax is greater than
    459                                     PcdMaximumUnicodeStringLength.
    460                                    If DestMax is 0.
    461   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    462 **/
    463 RETURN_STATUS
    464 EFIAPI
    465 StrnCatS (
    466   IN OUT CHAR16       *Destination,
    467   IN     UINTN        DestMax,
    468   IN     CONST CHAR16 *Source,
    469   IN     UINTN        Length
    470   )
    471 {
    472   UINTN               DestLen;
    473   UINTN               CopyLen;
    474   UINTN               SourceLen;
    475 
    476   ASSERT (((UINTN) Destination & BIT0) == 0);
    477   ASSERT (((UINTN) Source & BIT0) == 0);
    478 
    479   //
    480   // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
    481   //
    482   DestLen = StrnLenS (Destination, DestMax);
    483   CopyLen = DestMax - DestLen;
    484 
    485   //
    486   // 1. Neither Destination nor Source shall be a null pointer.
    487   //
    488   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    489   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    490 
    491   //
    492   // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
    493   //
    494   if (RSIZE_MAX != 0) {
    495     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    496     SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    497   }
    498 
    499   //
    500   // 3. DestMax shall not equal zero.
    501   //
    502   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    503 
    504   //
    505   // 4. CopyLen shall not equal zero.
    506   //
    507   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    508 
    509   //
    510   // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
    511   //
    512   SourceLen = StrnLenS (Source, CopyLen);
    513   if (Length >= CopyLen) {
    514     SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    515   }
    516 
    517   //
    518   // 6. Copying shall not take place between objects that overlap.
    519   //
    520   if (SourceLen > Length) {
    521     SourceLen = Length;
    522   }
    523   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    524 
    525   //
    526   // The StrnCatS function appends not more than Length successive characters (characters
    527   // that follow a null character are not copied) from the array pointed to by Source to the end of
    528   // the string pointed to by Destination. The initial character from Source overwrites the null character at
    529   // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
    530   // a null character.
    531   //
    532   Destination = Destination + DestLen;
    533   while ((*Source != 0) && (SourceLen > 0)) {
    534     *(Destination++) = *(Source++);
    535     SourceLen--;
    536   }
    537   *Destination = 0;
    538 
    539   return RETURN_SUCCESS;
    540 }
    541 
    542 /**
    543   Returns the length of a Null-terminated Ascii string.
    544 
    545   This function is similar as strlen_s defined in C11.
    546 
    547   @param  String   A pointer to a Null-terminated Ascii string.
    548   @param  MaxSize  The maximum number of Destination Ascii
    549                    char, including terminating null char.
    550 
    551   @retval 0        If String is NULL.
    552   @retval MaxSize  If there is no null character in the first MaxSize characters of String.
    553   @return The number of characters that percede the terminating null character.
    554 
    555 **/
    556 UINTN
    557 EFIAPI
    558 AsciiStrnLenS (
    559   IN CONST CHAR8               *String,
    560   IN UINTN                     MaxSize
    561   )
    562 {
    563   UINTN                             Length;
    564 
    565   //
    566   // If String is a null pointer, then the AsciiStrnLenS function returns zero.
    567   //
    568   if (String == NULL) {
    569     return 0;
    570   }
    571 
    572   //
    573   // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
    574   // terminating null character. If there is no null character in the first MaxSize characters of
    575   // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
    576   // be accessed by AsciiStrnLenS.
    577   //
    578   Length = 0;
    579   while (String[Length] != 0) {
    580     if (Length >= MaxSize - 1) {
    581       return MaxSize;
    582     }
    583     Length++;
    584   }
    585   return Length;
    586 }
    587 
    588 /**
    589   Copies the string pointed to by Source (including the terminating null char)
    590   to the array pointed to by Destination.
    591 
    592   This function is similar as strcpy_s defined in C11.
    593 
    594   If an error would be returned, then the function will also ASSERT().
    595 
    596   If an error is returned, then the Destination is unmodified.
    597 
    598   @param  Destination              A pointer to a Null-terminated Ascii string.
    599   @param  DestMax                  The maximum number of Destination Ascii
    600                                    char, including terminating null char.
    601   @param  Source                   A pointer to a Null-terminated Ascii string.
    602 
    603   @retval RETURN_SUCCESS           String is copied.
    604   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
    605   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    606                                    If Source is NULL.
    607                                    If PcdMaximumAsciiStringLength is not zero,
    608                                     and DestMax is greater than
    609                                     PcdMaximumAsciiStringLength.
    610                                    If DestMax is 0.
    611   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    612 **/
    613 RETURN_STATUS
    614 EFIAPI
    615 AsciiStrCpyS (
    616   OUT CHAR8        *Destination,
    617   IN  UINTN        DestMax,
    618   IN  CONST CHAR8  *Source
    619   )
    620 {
    621   UINTN            SourceLen;
    622 
    623   //
    624   // 1. Neither Destination nor Source shall be a null pointer.
    625   //
    626   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    627   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    628 
    629   //
    630   // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
    631   //
    632   if (ASCII_RSIZE_MAX != 0) {
    633     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    634   }
    635 
    636   //
    637   // 3. DestMax shall not equal zero.
    638   //
    639   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    640 
    641   //
    642   // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
    643   //
    644   SourceLen = AsciiStrnLenS (Source, DestMax);
    645   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    646 
    647   //
    648   // 5. Copying shall not take place between objects that overlap.
    649   //
    650   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    651 
    652   //
    653   // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
    654   // null character) into the array pointed to by Destination.
    655   //
    656   while (*Source != 0) {
    657     *(Destination++) = *(Source++);
    658   }
    659   *Destination = 0;
    660 
    661   return RETURN_SUCCESS;
    662 }
    663 
    664 /**
    665   Copies not more than Length successive char from the string pointed to by
    666   Source to the array pointed to by Destination. If no null char is copied from
    667   Source, then Destination[Length] is always set to null.
    668 
    669   This function is similar as strncpy_s defined in C11.
    670 
    671   If an error would be returned, then the function will also ASSERT().
    672 
    673   If an error is returned, then the Destination is unmodified.
    674 
    675   @param  Destination              A pointer to a Null-terminated Ascii string.
    676   @param  DestMax                  The maximum number of Destination Ascii
    677                                    char, including terminating null char.
    678   @param  Source                   A pointer to a Null-terminated Ascii string.
    679   @param  Length                   The maximum number of Ascii characters to copy.
    680 
    681   @retval RETURN_SUCCESS           String is copied.
    682   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
    683                                    MIN(StrLen(Source), Length).
    684   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    685                                    If Source is NULL.
    686                                    If PcdMaximumAsciiStringLength is not zero,
    687                                     and DestMax is greater than
    688                                     PcdMaximumAsciiStringLength.
    689                                    If DestMax is 0.
    690   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    691 **/
    692 RETURN_STATUS
    693 EFIAPI
    694 AsciiStrnCpyS (
    695   OUT CHAR8        *Destination,
    696   IN  UINTN        DestMax,
    697   IN  CONST CHAR8  *Source,
    698   IN  UINTN        Length
    699   )
    700 {
    701   UINTN            SourceLen;
    702 
    703   //
    704   // 1. Neither Destination nor Source shall be a null pointer.
    705   //
    706   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    707   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    708 
    709   //
    710   // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
    711   //
    712   if (ASCII_RSIZE_MAX != 0) {
    713     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    714     SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    715   }
    716 
    717   //
    718   // 3. DestMax shall not equal zero.
    719   //
    720   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    721 
    722   //
    723   // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
    724   //
    725   SourceLen = AsciiStrnLenS (Source, DestMax);
    726   if (Length >= DestMax) {
    727     SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    728   }
    729 
    730   //
    731   // 5. Copying shall not take place between objects that overlap.
    732   //
    733   if (SourceLen > Length) {
    734     SourceLen = Length;
    735   }
    736   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    737 
    738   //
    739   // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
    740   // follow a null character are not copied) from the array pointed to by Source to the array
    741   // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
    742   // character.
    743   //
    744   while ((*Source != 0) && (SourceLen > 0)) {
    745     *(Destination++) = *(Source++);
    746     SourceLen--;
    747   }
    748   *Destination = 0;
    749 
    750   return RETURN_SUCCESS;
    751 }
    752 
    753 /**
    754   Appends a copy of the string pointed to by Source (including the terminating
    755   null char) to the end of the string pointed to by Destination.
    756 
    757   This function is similar as strcat_s defined in C11.
    758 
    759   If an error would be returned, then the function will also ASSERT().
    760 
    761   If an error is returned, then the Destination is unmodified.
    762 
    763   @param  Destination              A pointer to a Null-terminated Ascii string.
    764   @param  DestMax                  The maximum number of Destination Ascii
    765                                    char, including terminating null char.
    766   @param  Source                   A pointer to a Null-terminated Ascii string.
    767 
    768   @retval RETURN_SUCCESS           String is appended.
    769   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    770                                    StrLen(Destination).
    771   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    772                                    greater than StrLen(Source).
    773   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    774                                    If Source is NULL.
    775                                    If PcdMaximumAsciiStringLength is not zero,
    776                                     and DestMax is greater than
    777                                     PcdMaximumAsciiStringLength.
    778                                    If DestMax is 0.
    779   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    780 **/
    781 RETURN_STATUS
    782 EFIAPI
    783 AsciiStrCatS (
    784   IN OUT CHAR8        *Destination,
    785   IN     UINTN        DestMax,
    786   IN     CONST CHAR8  *Source
    787   )
    788 {
    789   UINTN               DestLen;
    790   UINTN               CopyLen;
    791   UINTN               SourceLen;
    792 
    793   //
    794   // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
    795   //
    796   DestLen = AsciiStrnLenS (Destination, DestMax);
    797   CopyLen = DestMax - DestLen;
    798 
    799   //
    800   // 1. Neither Destination nor Source shall be a null pointer.
    801   //
    802   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    803   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    804 
    805   //
    806   // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
    807   //
    808   if (ASCII_RSIZE_MAX != 0) {
    809     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    810   }
    811 
    812   //
    813   // 3. DestMax shall not equal zero.
    814   //
    815   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    816 
    817   //
    818   // 4. CopyLen shall not equal zero.
    819   //
    820   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    821 
    822   //
    823   // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
    824   //
    825   SourceLen = AsciiStrnLenS (Source, CopyLen);
    826   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    827 
    828   //
    829   // 6. Copying shall not take place between objects that overlap.
    830   //
    831   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    832 
    833   //
    834   // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
    835   // terminating null character) to the end of the string pointed to by Destination. The initial character
    836   // from Source overwrites the null character at the end of Destination.
    837   //
    838   Destination = Destination + DestLen;
    839   while (*Source != 0) {
    840     *(Destination++) = *(Source++);
    841   }
    842   *Destination = 0;
    843 
    844   return RETURN_SUCCESS;
    845 }
    846 
    847 /**
    848   Appends not more than Length successive char from the string pointed to by
    849   Source to the end of the string pointed to by Destination. If no null char is
    850   copied from Source, then Destination[StrLen(Destination) + Length] is always
    851   set to null.
    852 
    853   This function is similar as strncat_s defined in C11.
    854 
    855   If an error would be returned, then the function will also ASSERT().
    856 
    857   If an error is returned, then the Destination is unmodified.
    858 
    859   @param  Destination              A pointer to a Null-terminated Ascii string.
    860   @param  DestMax                  The maximum number of Destination Ascii
    861                                    char, including terminating null char.
    862   @param  Source                   A pointer to a Null-terminated Ascii string.
    863   @param  Length                   The maximum number of Ascii characters to copy.
    864 
    865   @retval RETURN_SUCCESS           String is appended.
    866   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    867                                    StrLen(Destination).
    868   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    869                                    greater than MIN(StrLen(Source), Length).
    870   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    871                                    If Source is NULL.
    872                                    If PcdMaximumAsciiStringLength is not zero,
    873                                     and DestMax is greater than
    874                                     PcdMaximumAsciiStringLength.
    875                                    If DestMax is 0.
    876   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    877 **/
    878 RETURN_STATUS
    879 EFIAPI
    880 AsciiStrnCatS (
    881   IN OUT CHAR8        *Destination,
    882   IN     UINTN        DestMax,
    883   IN     CONST CHAR8  *Source,
    884   IN     UINTN        Length
    885   )
    886 {
    887   UINTN               DestLen;
    888   UINTN               CopyLen;
    889   UINTN               SourceLen;
    890 
    891   //
    892   // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
    893   //
    894   DestLen = AsciiStrnLenS (Destination, DestMax);
    895   CopyLen = DestMax - DestLen;
    896 
    897   //
    898   // 1. Neither Destination nor Source shall be a null pointer.
    899   //
    900   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    901   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    902 
    903   //
    904   // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
    905   //
    906   if (ASCII_RSIZE_MAX != 0) {
    907     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    908     SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    909   }
    910 
    911   //
    912   // 3. DestMax shall not equal zero.
    913   //
    914   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    915 
    916   //
    917   // 4. CopyLen shall not equal zero.
    918   //
    919   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    920 
    921   //
    922   // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
    923   //
    924   SourceLen = AsciiStrnLenS (Source, CopyLen);
    925   if (Length >= CopyLen) {
    926     SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    927   }
    928 
    929   //
    930   // 6. Copying shall not take place between objects that overlap.
    931   //
    932   if (SourceLen > Length) {
    933     SourceLen = Length;
    934   }
    935   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    936 
    937   //
    938   // The AsciiStrnCatS function appends not more than Length successive characters (characters
    939   // that follow a null character are not copied) from the array pointed to by Source to the end of
    940   // the string pointed to by Destination. The initial character from Source overwrites the null character at
    941   // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
    942   // a null character.
    943   //
    944   Destination = Destination + DestLen;
    945   while ((*Source != 0) && (SourceLen > 0)) {
    946     *(Destination++) = *(Source++);
    947     SourceLen--;
    948   }
    949   *Destination = 0;
    950 
    951   return RETURN_SUCCESS;
    952 }
    953 
    954 /**
    955   Convert a Null-terminated Unicode string to a Null-terminated
    956   ASCII string.
    957 
    958   This function is similar to AsciiStrCpyS.
    959 
    960   This function converts the content of the Unicode string Source
    961   to the ASCII string Destination by copying the lower 8 bits of
    962   each Unicode character. The function terminates the ASCII string
    963   Destination by appending a Null-terminator character at the end.
    964 
    965   The caller is responsible to make sure Destination points to a buffer with size
    966   equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
    967 
    968   If any Unicode characters in Source contain non-zero value in
    969   the upper 8 bits, then ASSERT().
    970 
    971   If Source is not aligned on a 16-bit boundary, then ASSERT().
    972   If an error would be returned, then the function will also ASSERT().
    973 
    974   If an error is returned, then the Destination is unmodified.
    975 
    976   @param  Source        The pointer to a Null-terminated Unicode string.
    977   @param  Destination   The pointer to a Null-terminated ASCII string.
    978   @param  DestMax       The maximum number of Destination Ascii
    979                         char, including terminating null char.
    980 
    981   @retval RETURN_SUCCESS           String is converted.
    982   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
    983   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    984                                    If Source is NULL.
    985                                    If PcdMaximumAsciiStringLength is not zero,
    986                                     and DestMax is greater than
    987                                     PcdMaximumAsciiStringLength.
    988                                    If PcdMaximumUnicodeStringLength is not zero,
    989                                     and DestMax is greater than
    990                                     PcdMaximumUnicodeStringLength.
    991                                    If DestMax is 0.
    992   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    993 
    994 **/
    995 RETURN_STATUS
    996 EFIAPI
    997 UnicodeStrToAsciiStrS (
    998   IN      CONST CHAR16              *Source,
    999   OUT     CHAR8                     *Destination,
   1000   IN      UINTN                     DestMax
   1001   )
   1002 {
   1003   UINTN            SourceLen;
   1004 
   1005   ASSERT (((UINTN) Source & BIT0) == 0);
   1006 
   1007   //
   1008   // 1. Neither Destination nor Source shall be a null pointer.
   1009   //
   1010   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
   1011   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
   1012 
   1013   //
   1014   // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
   1015   //
   1016   if (ASCII_RSIZE_MAX != 0) {
   1017     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
   1018   }
   1019   if (RSIZE_MAX != 0) {
   1020     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
   1021   }
   1022 
   1023   //
   1024   // 3. DestMax shall not equal zero.
   1025   //
   1026   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
   1027 
   1028   //
   1029   // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
   1030   //
   1031   SourceLen = StrnLenS (Source, DestMax);
   1032   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
   1033 
   1034   //
   1035   // 5. Copying shall not take place between objects that overlap.
   1036   //
   1037   SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
   1038 
   1039   //
   1040   // convert string
   1041   //
   1042   while (*Source != '\0') {
   1043     //
   1044     // If any Unicode characters in Source contain
   1045     // non-zero value in the upper 8 bits, then ASSERT().
   1046     //
   1047     ASSERT (*Source < 0x100);
   1048     *(Destination++) = (CHAR8) *(Source++);
   1049   }
   1050   *Destination = '\0';
   1051 
   1052   return RETURN_SUCCESS;
   1053 }
   1054 
   1055 
   1056 /**
   1057   Convert one Null-terminated ASCII string to a Null-terminated
   1058   Unicode string.
   1059 
   1060   This function is similar to StrCpyS.
   1061 
   1062   This function converts the contents of the ASCII string Source to the Unicode
   1063   string Destination. The function terminates the Unicode string Destination by
   1064   appending a Null-terminator character at the end.
   1065 
   1066   The caller is responsible to make sure Destination points to a buffer with size
   1067   equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
   1068 
   1069   If Destination is not aligned on a 16-bit boundary, then ASSERT().
   1070   If an error would be returned, then the function will also ASSERT().
   1071 
   1072   If an error is returned, then the Destination is unmodified.
   1073 
   1074   @param  Source        The pointer to a Null-terminated ASCII string.
   1075   @param  Destination   The pointer to a Null-terminated Unicode string.
   1076   @param  DestMax       The maximum number of Destination Unicode
   1077                         char, including terminating null char.
   1078 
   1079   @retval RETURN_SUCCESS           String is converted.
   1080   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
   1081   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
   1082                                    If Source is NULL.
   1083                                    If PcdMaximumUnicodeStringLength is not zero,
   1084                                     and DestMax is greater than
   1085                                     PcdMaximumUnicodeStringLength.
   1086                                    If PcdMaximumAsciiStringLength is not zero,
   1087                                     and DestMax is greater than
   1088                                     PcdMaximumAsciiStringLength.
   1089                                    If DestMax is 0.
   1090   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
   1091 
   1092 **/
   1093 RETURN_STATUS
   1094 EFIAPI
   1095 AsciiStrToUnicodeStrS (
   1096   IN      CONST CHAR8               *Source,
   1097   OUT     CHAR16                    *Destination,
   1098   IN      UINTN                     DestMax
   1099   )
   1100 {
   1101   UINTN            SourceLen;
   1102 
   1103   ASSERT (((UINTN) Destination & BIT0) == 0);
   1104 
   1105   //
   1106   // 1. Neither Destination nor Source shall be a null pointer.
   1107   //
   1108   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
   1109   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
   1110 
   1111   //
   1112   // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
   1113   //
   1114   if (RSIZE_MAX != 0) {
   1115     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
   1116   }
   1117   if (ASCII_RSIZE_MAX != 0) {
   1118     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
   1119   }
   1120 
   1121   //
   1122   // 3. DestMax shall not equal zero.
   1123   //
   1124   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
   1125 
   1126   //
   1127   // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
   1128   //
   1129   SourceLen = AsciiStrnLenS (Source, DestMax);
   1130   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
   1131 
   1132   //
   1133   // 5. Copying shall not take place between objects that overlap.
   1134   //
   1135   SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
   1136 
   1137   //
   1138   // Convert string
   1139   //
   1140   while (*Source != '\0') {
   1141     *(Destination++) = (CHAR16)*(Source++);
   1142   }
   1143   *Destination = '\0';
   1144 
   1145   return RETURN_SUCCESS;
   1146 }
   1147