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