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