Home | History | Annotate | Download | only in BaseLib
      1 /** @file
      2   Safe String functions.
      3 
      4   Copyright (c) 2014, 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   If String is not aligned on a 16-bit boundary, then ASSERT().
    110 
    111   @param  String   A pointer to a Null-terminated Unicode string.
    112   @param  MaxSize  The maximum number of Destination Unicode
    113                    char, including terminating null char.
    114 
    115   @retval 0        If String is NULL.
    116   @retval MaxSize  If there is no null character in the first MaxSize characters of String.
    117   @return The number of characters that percede the terminating null character.
    118 
    119 **/
    120 UINTN
    121 EFIAPI
    122 StrnLenS (
    123   IN CONST CHAR16              *String,
    124   IN UINTN                     MaxSize
    125   )
    126 {
    127   UINTN                             Length;
    128 
    129   ASSERT (((UINTN) String & BIT0) == 0);
    130 
    131   //
    132   // If String is a null pointer, then the StrnLenS function returns zero.
    133   //
    134   if (String == NULL) {
    135     return 0;
    136   }
    137 
    138   //
    139   // Otherwise, the StrnLenS function returns the number of characters that precede the
    140   // terminating null character. If there is no null character in the first MaxSize characters of
    141   // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
    142   // be accessed by StrnLenS.
    143   //
    144   for (Length = 0; (Length < MaxSize) && (*String != 0); String++, Length++) {
    145     ;
    146   }
    147   return Length;
    148 }
    149 
    150 /**
    151   Copies the string pointed to by Source (including the terminating null char)
    152   to the array pointed to by Destination.
    153 
    154   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    155   If Source is not aligned on a 16-bit boundary, then ASSERT().
    156   If an error would be returned, then the function will also ASSERT().
    157 
    158   @param  Destination              A pointer to a Null-terminated Unicode string.
    159   @param  DestMax                  The maximum number of Destination Unicode
    160                                    char, including terminating null char.
    161   @param  Source                   A pointer to a Null-terminated Unicode string.
    162 
    163   @retval RETURN_SUCCESS           String is copied.
    164   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
    165   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    166                                    If Source is NULL.
    167                                    If PcdMaximumUnicodeStringLength is not zero,
    168                                     and DestMax is greater than
    169                                     PcdMaximumUnicodeStringLength.
    170                                    If DestMax is 0.
    171   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    172 **/
    173 RETURN_STATUS
    174 EFIAPI
    175 StrCpyS (
    176   OUT CHAR16       *Destination,
    177   IN  UINTN        DestMax,
    178   IN  CONST CHAR16 *Source
    179   )
    180 {
    181   UINTN            SourceLen;
    182 
    183   ASSERT (((UINTN) Destination & BIT0) == 0);
    184   ASSERT (((UINTN) Source & BIT0) == 0);
    185 
    186   //
    187   // 1. Neither Destination nor Source shall be a null pointer.
    188   //
    189   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    190   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    191 
    192   //
    193   // 2. DestMax shall not be greater than RSIZE_MAX.
    194   //
    195   if (RSIZE_MAX != 0) {
    196     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    197   }
    198 
    199   //
    200   // 3. DestMax shall not equal zero.
    201   //
    202   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    203 
    204   //
    205   // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
    206   //
    207   SourceLen = StrnLenS (Source, DestMax);
    208   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    209 
    210   //
    211   // 5. Copying shall not take place between objects that overlap.
    212   //
    213   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    214 
    215   //
    216   // The StrCpyS function copies the string pointed to by Source (including the terminating
    217   // null character) into the array pointed to by Destination.
    218   //
    219   while (*Source != 0) {
    220     *(Destination++) = *(Source++);
    221   }
    222   *Destination = 0;
    223 
    224   return RETURN_SUCCESS;
    225 }
    226 
    227 /**
    228   Copies not more than Length successive char from the string pointed to by
    229   Source to the array pointed to by Destination. If no null char is copied from
    230   Source, then Destination[Length] is always set to null.
    231 
    232   If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
    233   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
    234   If an error would be returned, then the function will also ASSERT().
    235 
    236   @param  Destination              A pointer to a Null-terminated Unicode string.
    237   @param  DestMax                  The maximum number of Destination Unicode
    238                                    char, including terminating null char.
    239   @param  Source                   A pointer to a Null-terminated Unicode string.
    240   @param  Length                   The maximum number of Unicode characters to copy.
    241 
    242   @retval RETURN_SUCCESS           String is copied.
    243   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
    244                                    MIN(StrLen(Source), Length).
    245   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    246                                    If Source is NULL.
    247                                    If PcdMaximumUnicodeStringLength is not zero,
    248                                     and DestMax is greater than
    249                                     PcdMaximumUnicodeStringLength.
    250                                    If DestMax is 0.
    251   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    252 **/
    253 RETURN_STATUS
    254 EFIAPI
    255 StrnCpyS (
    256   OUT CHAR16       *Destination,
    257   IN  UINTN        DestMax,
    258   IN  CONST CHAR16 *Source,
    259   IN  UINTN        Length
    260   )
    261 {
    262   UINTN            SourceLen;
    263 
    264   ASSERT (((UINTN) Destination & BIT0) == 0);
    265   ASSERT (((UINTN) Source & BIT0) == 0);
    266 
    267   //
    268   // 1. Neither Destination nor Source shall be a null pointer.
    269   //
    270   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    271   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    272 
    273   //
    274   // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
    275   //
    276   if (RSIZE_MAX != 0) {
    277     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    278     SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    279   }
    280 
    281   //
    282   // 3. DestMax shall not equal zero.
    283   //
    284   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    285 
    286   //
    287   // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
    288   //
    289   SourceLen = StrnLenS (Source, DestMax);
    290   if (Length >= DestMax) {
    291     SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    292   }
    293 
    294   //
    295   // 5. Copying shall not take place between objects that overlap.
    296   //
    297   if (SourceLen > Length) {
    298     SourceLen = Length;
    299   }
    300   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    301 
    302   //
    303   // The StrnCpyS function copies not more than Length successive characters (characters that
    304   // follow a null character are not copied) from the array pointed to by Source to the array
    305   // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
    306   // character.
    307   //
    308   while ((*Source != 0) && (SourceLen > 0)) {
    309     *(Destination++) = *(Source++);
    310     SourceLen--;
    311   }
    312   *Destination = 0;
    313 
    314   return RETURN_SUCCESS;
    315 }
    316 
    317 /**
    318   Appends a copy of the string pointed to by Source (including the terminating
    319   null char) to the end of the string pointed to by Destination.
    320 
    321   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    322   If Source is not aligned on a 16-bit boundary, then ASSERT().
    323   If an error would be returned, then the function will also ASSERT().
    324 
    325   @param  Destination              A pointer to a Null-terminated Unicode string.
    326   @param  DestMax                  The maximum number of Destination Unicode
    327                                    char, including terminating null char.
    328   @param  Source                   A pointer to a Null-terminated Unicode string.
    329 
    330   @retval RETURN_SUCCESS           String is appended.
    331   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    332                                    StrLen(Destination).
    333   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    334                                    greater than StrLen(Source).
    335   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    336                                    If Source is NULL.
    337                                    If PcdMaximumUnicodeStringLength is not zero,
    338                                     and DestMax is greater than
    339                                     PcdMaximumUnicodeStringLength.
    340                                    If DestMax is 0.
    341   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    342 **/
    343 RETURN_STATUS
    344 EFIAPI
    345 StrCatS (
    346   IN OUT CHAR16       *Destination,
    347   IN     UINTN        DestMax,
    348   IN     CONST CHAR16 *Source
    349   )
    350 {
    351   UINTN               DestLen;
    352   UINTN               CopyLen;
    353   UINTN               SourceLen;
    354 
    355   ASSERT (((UINTN) Destination & BIT0) == 0);
    356   ASSERT (((UINTN) Source & BIT0) == 0);
    357 
    358   //
    359   // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
    360   //
    361   DestLen = StrnLenS (Destination, DestMax);
    362   CopyLen = DestMax - DestLen;
    363 
    364   //
    365   // 1. Neither Destination nor Source shall be a null pointer.
    366   //
    367   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    368   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    369 
    370   //
    371   // 2. DestMax shall not be greater than RSIZE_MAX.
    372   //
    373   if (RSIZE_MAX != 0) {
    374     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    375   }
    376 
    377   //
    378   // 3. DestMax shall not equal zero.
    379   //
    380   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    381 
    382   //
    383   // 4. CopyLen shall not equal zero.
    384   //
    385   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    386 
    387   //
    388   // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
    389   //
    390   SourceLen = StrnLenS (Source, CopyLen);
    391   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    392 
    393   //
    394   // 6. Copying shall not take place between objects that overlap.
    395   //
    396   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    397 
    398   //
    399   // The StrCatS function appends a copy of the string pointed to by Source (including the
    400   // terminating null character) to the end of the string pointed to by Destination. The initial character
    401   // from Source overwrites the null character at the end of Destination.
    402   //
    403   Destination = Destination + DestLen;
    404   while (*Source != 0) {
    405     *(Destination++) = *(Source++);
    406   }
    407   *Destination = 0;
    408 
    409   return RETURN_SUCCESS;
    410 }
    411 
    412 /**
    413   Appends not more than Length successive char from the string pointed to by
    414   Source to the end of the string pointed to by Destination. If no null char is
    415   copied from Source, then Destination[StrLen(Destination) + Length] is always
    416   set to null.
    417 
    418   If Destination is not aligned on a 16-bit boundary, then ASSERT().
    419   If Source is not aligned on a 16-bit boundary, then ASSERT().
    420   If an error would be returned, then the function will also ASSERT().
    421 
    422   @param  Destination              A pointer to a Null-terminated Unicode string.
    423   @param  DestMax                  The maximum number of Destination Unicode
    424                                    char, including terminating null char.
    425   @param  Source                   A pointer to a Null-terminated Unicode string.
    426   @param  Length                   The maximum number of Unicode characters to copy.
    427 
    428   @retval RETURN_SUCCESS           String is appended.
    429   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    430                                    StrLen(Destination).
    431   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    432                                    greater than MIN(StrLen(Source), Length).
    433   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    434                                    If Source is NULL.
    435                                    If PcdMaximumUnicodeStringLength is not zero,
    436                                     and DestMax is greater than
    437                                     PcdMaximumUnicodeStringLength.
    438                                    If DestMax is 0.
    439   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    440 **/
    441 RETURN_STATUS
    442 EFIAPI
    443 StrnCatS (
    444   IN OUT CHAR16       *Destination,
    445   IN     UINTN        DestMax,
    446   IN     CONST CHAR16 *Source,
    447   IN     UINTN        Length
    448   )
    449 {
    450   UINTN               DestLen;
    451   UINTN               CopyLen;
    452   UINTN               SourceLen;
    453 
    454   ASSERT (((UINTN) Destination & BIT0) == 0);
    455   ASSERT (((UINTN) Source & BIT0) == 0);
    456 
    457   //
    458   // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
    459   //
    460   DestLen = StrnLenS (Destination, DestMax);
    461   CopyLen = DestMax - DestLen;
    462 
    463   //
    464   // 1. Neither Destination nor Source shall be a null pointer.
    465   //
    466   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    467   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    468 
    469   //
    470   // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
    471   //
    472   if (RSIZE_MAX != 0) {
    473     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    474     SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
    475   }
    476 
    477   //
    478   // 3. DestMax shall not equal zero.
    479   //
    480   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    481 
    482   //
    483   // 4. CopyLen shall not equal zero.
    484   //
    485   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    486 
    487   //
    488   // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
    489   //
    490   SourceLen = StrnLenS (Source, CopyLen);
    491   if (Length >= CopyLen) {
    492     SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    493   }
    494 
    495   //
    496   // 6. Copying shall not take place between objects that overlap.
    497   //
    498   if (SourceLen > Length) {
    499     SourceLen = Length;
    500   }
    501   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    502 
    503   //
    504   // The StrnCatS function appends not more than Length successive characters (characters
    505   // that follow a null character are not copied) from the array pointed to by Source to the end of
    506   // the string pointed to by Destination. The initial character from Source overwrites the null character at
    507   // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
    508   // a null character.
    509   //
    510   Destination = Destination + DestLen;
    511   while ((*Source != 0) && (SourceLen > 0)) {
    512     *(Destination++) = *(Source++);
    513     SourceLen--;
    514   }
    515   *Destination = 0;
    516 
    517   return RETURN_SUCCESS;
    518 }
    519 
    520 /**
    521   Returns the length of a Null-terminated Ascii string.
    522 
    523   @param  String   A pointer to a Null-terminated Ascii string.
    524   @param  MaxSize  The maximum number of Destination Ascii
    525                    char, including terminating null char.
    526 
    527   @retval 0        If String is NULL.
    528   @retval MaxSize  If there is no null character in the first MaxSize characters of String.
    529   @return The number of characters that percede the terminating null character.
    530 
    531 **/
    532 UINTN
    533 EFIAPI
    534 AsciiStrnLenS (
    535   IN CONST CHAR8               *String,
    536   IN UINTN                     MaxSize
    537   )
    538 {
    539   UINTN                             Length;
    540 
    541   //
    542   // If String is a null pointer, then the AsciiStrnLenS function returns zero.
    543   //
    544   if (String == NULL) {
    545     return 0;
    546   }
    547 
    548   //
    549   // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
    550   // terminating null character. If there is no null character in the first MaxSize characters of
    551   // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
    552   // be accessed by AsciiStrnLenS.
    553   //
    554   for (Length = 0; (Length < MaxSize) && (*String != 0); String++, Length++) {
    555     ;
    556   }
    557   return Length;
    558 }
    559 
    560 /**
    561   Copies the string pointed to by Source (including the terminating null char)
    562   to the array pointed to by Destination.
    563 
    564   If an error would be returned, then the function will also ASSERT().
    565 
    566   @param  Destination              A pointer to a Null-terminated Ascii string.
    567   @param  DestMax                  The maximum number of Destination Ascii
    568                                    char, including terminating null char.
    569   @param  Source                   A pointer to a Null-terminated Ascii string.
    570 
    571   @retval RETURN_SUCCESS           String is copied.
    572   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
    573   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    574                                    If Source is NULL.
    575                                    If PcdMaximumAsciiStringLength is not zero,
    576                                     and DestMax is greater than
    577                                     PcdMaximumAsciiStringLength.
    578                                    If DestMax is 0.
    579   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    580 **/
    581 RETURN_STATUS
    582 EFIAPI
    583 AsciiStrCpyS (
    584   OUT CHAR8        *Destination,
    585   IN  UINTN        DestMax,
    586   IN  CONST CHAR8  *Source
    587   )
    588 {
    589   UINTN            SourceLen;
    590 
    591   //
    592   // 1. Neither Destination nor Source shall be a null pointer.
    593   //
    594   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    595   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    596 
    597   //
    598   // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
    599   //
    600   if (ASCII_RSIZE_MAX != 0) {
    601     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    602   }
    603 
    604   //
    605   // 3. DestMax shall not equal zero.
    606   //
    607   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    608 
    609   //
    610   // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
    611   //
    612   SourceLen = AsciiStrnLenS (Source, DestMax);
    613   SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    614 
    615   //
    616   // 5. Copying shall not take place between objects that overlap.
    617   //
    618   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    619 
    620   //
    621   // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
    622   // null character) into the array pointed to by Destination.
    623   //
    624   while (*Source != 0) {
    625     *(Destination++) = *(Source++);
    626   }
    627   *Destination = 0;
    628 
    629   return RETURN_SUCCESS;
    630 }
    631 
    632 /**
    633   Copies not more than Length successive char from the string pointed to by
    634   Source to the array pointed to by Destination. If no null char is copied from
    635   Source, then Destination[Length] is always set to null.
    636 
    637   If an error would be returned, then the function will also ASSERT().
    638 
    639   @param  Destination              A pointer to a Null-terminated Ascii string.
    640   @param  DestMax                  The maximum number of Destination Ascii
    641                                    char, including terminating null char.
    642   @param  Source                   A pointer to a Null-terminated Ascii string.
    643   @param  Length                   The maximum number of Ascii characters to copy.
    644 
    645   @retval RETURN_SUCCESS           String is copied.
    646   @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than
    647                                    MIN(StrLen(Source), Length).
    648   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    649                                    If Source is NULL.
    650                                    If PcdMaximumAsciiStringLength is not zero,
    651                                     and DestMax is greater than
    652                                     PcdMaximumAsciiStringLength.
    653                                    If DestMax is 0.
    654   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    655 **/
    656 RETURN_STATUS
    657 EFIAPI
    658 AsciiStrnCpyS (
    659   OUT CHAR8        *Destination,
    660   IN  UINTN        DestMax,
    661   IN  CONST CHAR8  *Source,
    662   IN  UINTN        Length
    663   )
    664 {
    665   UINTN            SourceLen;
    666 
    667   //
    668   // 1. Neither Destination nor Source shall be a null pointer.
    669   //
    670   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    671   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    672 
    673   //
    674   // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
    675   //
    676   if (ASCII_RSIZE_MAX != 0) {
    677     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    678     SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    679   }
    680 
    681   //
    682   // 3. DestMax shall not equal zero.
    683   //
    684   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    685 
    686   //
    687   // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
    688   //
    689   SourceLen = AsciiStrnLenS (Source, DestMax);
    690   if (Length >= DestMax) {
    691     SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
    692   }
    693 
    694   //
    695   // 5. Copying shall not take place between objects that overlap.
    696   //
    697   if (SourceLen > Length) {
    698     SourceLen = Length;
    699   }
    700   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    701 
    702   //
    703   // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
    704   // follow a null character are not copied) from the array pointed to by Source to the array
    705   // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
    706   // character.
    707   //
    708   while ((*Source != 0) && (SourceLen > 0)) {
    709     *(Destination++) = *(Source++);
    710     SourceLen--;
    711   }
    712   *Destination = 0;
    713 
    714   return RETURN_SUCCESS;
    715 }
    716 
    717 /**
    718   Appends a copy of the string pointed to by Source (including the terminating
    719   null char) to the end of the string pointed to by Destination.
    720 
    721   If an error would be returned, then the function will also ASSERT().
    722 
    723   @param  Destination              A pointer to a Null-terminated Ascii string.
    724   @param  DestMax                  The maximum number of Destination Ascii
    725                                    char, including terminating null char.
    726   @param  Source                   A pointer to a Null-terminated Ascii string.
    727 
    728   @retval RETURN_SUCCESS           String is appended.
    729   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    730                                    StrLen(Destination).
    731   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    732                                    greater than StrLen(Source).
    733   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    734                                    If Source is NULL.
    735                                    If PcdMaximumAsciiStringLength is not zero,
    736                                     and DestMax is greater than
    737                                     PcdMaximumAsciiStringLength.
    738                                    If DestMax is 0.
    739   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    740 **/
    741 RETURN_STATUS
    742 EFIAPI
    743 AsciiStrCatS (
    744   IN OUT CHAR8        *Destination,
    745   IN     UINTN        DestMax,
    746   IN     CONST CHAR8  *Source
    747   )
    748 {
    749   UINTN               DestLen;
    750   UINTN               CopyLen;
    751   UINTN               SourceLen;
    752 
    753   //
    754   // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
    755   //
    756   DestLen = AsciiStrnLenS (Destination, DestMax);
    757   CopyLen = DestMax - DestLen;
    758 
    759   //
    760   // 1. Neither Destination nor Source shall be a null pointer.
    761   //
    762   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    763   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    764 
    765   //
    766   // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
    767   //
    768   if (ASCII_RSIZE_MAX != 0) {
    769     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    770   }
    771 
    772   //
    773   // 3. DestMax shall not equal zero.
    774   //
    775   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    776 
    777   //
    778   // 4. CopyLen shall not equal zero.
    779   //
    780   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    781 
    782   //
    783   // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
    784   //
    785   SourceLen = AsciiStrnLenS (Source, CopyLen);
    786   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    787 
    788   //
    789   // 6. Copying shall not take place between objects that overlap.
    790   //
    791   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    792 
    793   //
    794   // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
    795   // terminating null character) to the end of the string pointed to by Destination. The initial character
    796   // from Source overwrites the null character at the end of Destination.
    797   //
    798   Destination = Destination + DestLen;
    799   while (*Source != 0) {
    800     *(Destination++) = *(Source++);
    801   }
    802   *Destination = 0;
    803 
    804   return RETURN_SUCCESS;
    805 }
    806 
    807 /**
    808   Appends not more than Length successive char from the string pointed to by
    809   Source to the end of the string pointed to by Destination. If no null char is
    810   copied from Source, then Destination[StrLen(Destination) + Length] is always
    811   set to null.
    812 
    813   If an error would be returned, then the function will also ASSERT().
    814 
    815   @param  Destination              A pointer to a Null-terminated Ascii string.
    816   @param  DestMax                  The maximum number of Destination Ascii
    817                                    char, including terminating null char.
    818   @param  Source                   A pointer to a Null-terminated Ascii string.
    819   @param  Length                   The maximum number of Ascii characters to copy.
    820 
    821   @retval RETURN_SUCCESS           String is appended.
    822   @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
    823                                    StrLen(Destination).
    824   @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
    825                                    greater than MIN(StrLen(Source), Length).
    826   @retval RETURN_INVALID_PARAMETER If Destination is NULL.
    827                                    If Source is NULL.
    828                                    If PcdMaximumAsciiStringLength is not zero,
    829                                     and DestMax is greater than
    830                                     PcdMaximumAsciiStringLength.
    831                                    If DestMax is 0.
    832   @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
    833 **/
    834 RETURN_STATUS
    835 EFIAPI
    836 AsciiStrnCatS (
    837   IN OUT CHAR8        *Destination,
    838   IN     UINTN        DestMax,
    839   IN     CONST CHAR8  *Source,
    840   IN     UINTN        Length
    841   )
    842 {
    843   UINTN               DestLen;
    844   UINTN               CopyLen;
    845   UINTN               SourceLen;
    846 
    847   //
    848   // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
    849   //
    850   DestLen = AsciiStrnLenS (Destination, DestMax);
    851   CopyLen = DestMax - DestLen;
    852 
    853   //
    854   // 1. Neither Destination nor Source shall be a null pointer.
    855   //
    856   SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
    857   SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
    858 
    859   //
    860   // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
    861   //
    862   if (ASCII_RSIZE_MAX != 0) {
    863     SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    864     SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
    865   }
    866 
    867   //
    868   // 3. DestMax shall not equal zero.
    869   //
    870   SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
    871 
    872   //
    873   // 4. CopyLen shall not equal zero.
    874   //
    875   SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
    876 
    877   //
    878   // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
    879   //
    880   SourceLen = AsciiStrnLenS (Source, CopyLen);
    881   if (Length >= CopyLen) {
    882     SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
    883   }
    884 
    885   //
    886   // 6. Copying shall not take place between objects that overlap.
    887   //
    888   if (SourceLen > Length) {
    889     SourceLen = Length;
    890   }
    891   SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
    892 
    893   //
    894   // The AsciiStrnCatS function appends not more than Length successive characters (characters
    895   // that follow a null character are not copied) from the array pointed to by Source to the end of
    896   // the string pointed to by Destination. The initial character from Source overwrites the null character at
    897   // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
    898   // a null character.
    899   //
    900   Destination = Destination + DestLen;
    901   while ((*Source != 0) && (SourceLen > 0)) {
    902     *(Destination++) = *(Source++);
    903     SourceLen--;
    904   }
    905   *Destination = 0;
    906 
    907   return RETURN_SUCCESS;
    908 }
    909