TianoCore EDK2 master
SafeString.c
Go to the documentation of this file.
1
9#include "BaseLibInternals.h"
10
11#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
12
13#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
14
15#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
16 do { \
17 if (!(Expression)) { \
18 DEBUG ((DEBUG_VERBOSE, \
19 "%a(%d) %a: SAFE_STRING_CONSTRAINT_CHECK(%a) failed. Return %r\n", \
20 __FILE__, DEBUG_LINE_NUMBER, __FUNCTION__, DEBUG_EXPRESSION_STRING (Expression), Status)); \
21 return Status; \
22 } \
23 } while (FALSE)
24
36BOOLEAN
38 IN VOID *Base1,
39 IN UINTN Size1,
40 IN VOID *Base2,
41 IN UINTN Size2
42 )
43{
44 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
45 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1)))
46 {
47 return TRUE;
48 }
49
50 return FALSE;
51}
52
66BOOLEAN
68 IN CHAR16 *Str1,
69 IN UINTN Size1,
70 IN CHAR16 *Str2,
71 IN UINTN Size2
72 )
73{
74 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof (CHAR16), Str2, Size2 * sizeof (CHAR16));
75}
76
90BOOLEAN
92 IN CHAR8 *Str1,
93 IN UINTN Size1,
94 IN CHAR8 *Str2,
95 IN UINTN Size2
96 )
97{
98 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);
99}
100
117UINTN
118EFIAPI
120 IN CONST CHAR16 *String,
121 IN UINTN MaxSize
122 )
123{
124 UINTN Length;
125
126 ASSERT (((UINTN)String & BIT0) == 0);
127
128 //
129 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
130 //
131 if ((String == NULL) || (MaxSize == 0)) {
132 return 0;
133 }
134
135 //
136 // Otherwise, the StrnLenS function returns the number of characters that precede the
137 // terminating null character. If there is no null character in the first MaxSize characters of
138 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
139 // be accessed by StrnLenS.
140 //
141 Length = 0;
142 while (String[Length] != 0) {
143 if (Length >= MaxSize - 1) {
144 return MaxSize;
145 }
146
147 Length++;
148 }
149
150 return Length;
151}
152
174UINTN
175EFIAPI
177 IN CONST CHAR16 *String,
178 IN UINTN MaxSize
179 )
180{
181 //
182 // If String is a null pointer, then the StrnSizeS function returns zero.
183 //
184 if (String == NULL) {
185 return 0;
186 }
187
188 //
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
190 // Unicode string in bytes, including the Null terminator. If there is no
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
193 // the StrnLenS function.
194 //
195 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);
196}
197
224RETURN_STATUS
225EFIAPI
227 OUT CHAR16 *Destination,
228 IN UINTN DestMax,
229 IN CONST CHAR16 *Source
230 )
231{
232 UINTN SourceLen;
233
234 ASSERT (((UINTN)Destination & BIT0) == 0);
235 ASSERT (((UINTN)Source & BIT0) == 0);
236
237 //
238 // 1. Neither Destination nor Source shall be a null pointer.
239 //
240 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
241 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
242
243 //
244 // 2. DestMax shall not be greater than RSIZE_MAX.
245 //
246 if (RSIZE_MAX != 0) {
247 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
248 }
249
250 //
251 // 3. DestMax shall not equal zero.
252 //
253 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
254
255 //
256 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
257 //
258 SourceLen = StrnLenS (Source, DestMax);
259 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
260
261 //
262 // 5. Copying shall not take place between objects that overlap.
263 //
264 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
265
266 //
267 // The StrCpyS function copies the string pointed to by Source (including the terminating
268 // null character) into the array pointed to by Destination.
269 //
270 while (*Source != 0) {
271 *(Destination++) = *(Source++);
272 }
273
274 *Destination = 0;
275
276 return RETURN_SUCCESS;
277}
278
308RETURN_STATUS
309EFIAPI
311 OUT CHAR16 *Destination,
312 IN UINTN DestMax,
313 IN CONST CHAR16 *Source,
314 IN UINTN Length
315 )
316{
317 UINTN SourceLen;
318
319 ASSERT (((UINTN)Destination & BIT0) == 0);
320 ASSERT (((UINTN)Source & BIT0) == 0);
321
322 //
323 // 1. Neither Destination nor Source shall be a null pointer.
324 //
325 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
326 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
327
328 //
329 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
330 //
331 if (RSIZE_MAX != 0) {
332 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
333 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
334 }
335
336 //
337 // 3. DestMax shall not equal zero.
338 //
339 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
340
341 //
342 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
343 //
344 SourceLen = StrnLenS (Source, MIN (DestMax, Length));
345 if (Length >= DestMax) {
346 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
347 }
348
349 //
350 // 5. Copying shall not take place between objects that overlap.
351 //
352 if (SourceLen > Length) {
353 SourceLen = Length;
354 }
355
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
357
358 //
359 // The StrnCpyS function copies not more than Length successive characters (characters that
360 // follow a null character are not copied) from the array pointed to by Source to the array
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
362 // character.
363 //
364 while ((SourceLen > 0) && (*Source != 0)) {
365 *(Destination++) = *(Source++);
366 SourceLen--;
367 }
368
369 *Destination = 0;
370
371 return RETURN_SUCCESS;
372}
373
403RETURN_STATUS
404EFIAPI
406 IN OUT CHAR16 *Destination,
407 IN UINTN DestMax,
408 IN CONST CHAR16 *Source
409 )
410{
411 UINTN DestLen;
412 UINTN CopyLen;
413 UINTN SourceLen;
414
415 ASSERT (((UINTN)Destination & BIT0) == 0);
416 ASSERT (((UINTN)Source & BIT0) == 0);
417
418 //
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
420 //
421 DestLen = StrnLenS (Destination, DestMax);
422 CopyLen = DestMax - DestLen;
423
424 //
425 // 1. Neither Destination nor Source shall be a null pointer.
426 //
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
428 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
429
430 //
431 // 2. DestMax shall not be greater than RSIZE_MAX.
432 //
433 if (RSIZE_MAX != 0) {
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
435 }
436
437 //
438 // 3. DestMax shall not equal zero.
439 //
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
441
442 //
443 // 4. CopyLen shall not equal zero.
444 //
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
446
447 //
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
449 //
450 SourceLen = StrnLenS (Source, CopyLen);
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
452
453 //
454 // 6. Copying shall not take place between objects that overlap.
455 //
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
457
458 //
459 // The StrCatS function appends a copy of the string pointed to by Source (including the
460 // terminating null character) to the end of the string pointed to by Destination. The initial character
461 // from Source overwrites the null character at the end of Destination.
462 //
463 Destination = Destination + DestLen;
464 while (*Source != 0) {
465 *(Destination++) = *(Source++);
466 }
467
468 *Destination = 0;
469
470 return RETURN_SUCCESS;
471}
472
505RETURN_STATUS
506EFIAPI
508 IN OUT CHAR16 *Destination,
509 IN UINTN DestMax,
510 IN CONST CHAR16 *Source,
511 IN UINTN Length
512 )
513{
514 UINTN DestLen;
515 UINTN CopyLen;
516 UINTN SourceLen;
517
518 ASSERT (((UINTN)Destination & BIT0) == 0);
519 ASSERT (((UINTN)Source & BIT0) == 0);
520
521 //
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
523 //
524 DestLen = StrnLenS (Destination, DestMax);
525 CopyLen = DestMax - DestLen;
526
527 //
528 // 1. Neither Destination nor Source shall be a null pointer.
529 //
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
531 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
532
533 //
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
535 //
536 if (RSIZE_MAX != 0) {
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
538 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
539 }
540
541 //
542 // 3. DestMax shall not equal zero.
543 //
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
545
546 //
547 // 4. CopyLen shall not equal zero.
548 //
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
550
551 //
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
553 //
554 SourceLen = StrnLenS (Source, MIN (CopyLen, Length));
555 if (Length >= CopyLen) {
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
557 }
558
559 //
560 // 6. Copying shall not take place between objects that overlap.
561 //
562 if (SourceLen > Length) {
563 SourceLen = Length;
564 }
565
566 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
567
568 //
569 // The StrnCatS function appends not more than Length successive characters (characters
570 // that follow a null character are not copied) from the array pointed to by Source to the end of
571 // the string pointed to by Destination. The initial character from Source overwrites the null character at
572 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
573 // a null character.
574 //
575 Destination = Destination + DestLen;
576 while ((SourceLen > 0) && (*Source != 0)) {
577 *(Destination++) = *(Source++);
578 SourceLen--;
579 }
580
581 *Destination = 0;
582
583 return RETURN_SUCCESS;
584}
585
629RETURN_STATUS
630EFIAPI
632 IN CONST CHAR16 *String,
633 OUT CHAR16 **EndPointer OPTIONAL,
634 OUT UINTN *Data
635 )
636{
637 ASSERT (((UINTN)String & BIT0) == 0);
638
639 //
640 // 1. Neither String nor Data shall be a null pointer.
641 //
642 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
643 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
644
645 //
646 // 2. The length of String shall not be greater than RSIZE_MAX.
647 //
648 if (RSIZE_MAX != 0) {
649 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
650 }
651
652 if (EndPointer != NULL) {
653 *EndPointer = (CHAR16 *)String;
654 }
655
656 //
657 // Ignore the pad spaces (space or tab)
658 //
659 while ((*String == L' ') || (*String == L'\t')) {
660 String++;
661 }
662
663 //
664 // Ignore leading Zeros after the spaces
665 //
666 while (*String == L'0') {
667 String++;
668 }
669
670 *Data = 0;
671
672 while (InternalIsDecimalDigitCharacter (*String)) {
673 //
674 // If the number represented by String overflows according to the range
675 // defined by UINTN, then MAX_UINTN is stored in *Data and
676 // RETURN_UNSUPPORTED is returned.
677 //
678 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {
679 *Data = MAX_UINTN;
680 if (EndPointer != NULL) {
681 *EndPointer = (CHAR16 *)String;
682 }
683
684 return RETURN_UNSUPPORTED;
685 }
686
687 *Data = *Data * 10 + (*String - L'0');
688 String++;
689 }
690
691 if (EndPointer != NULL) {
692 *EndPointer = (CHAR16 *)String;
693 }
694
695 return RETURN_SUCCESS;
696}
697
741RETURN_STATUS
742EFIAPI
744 IN CONST CHAR16 *String,
745 OUT CHAR16 **EndPointer OPTIONAL,
746 OUT UINT64 *Data
747 )
748{
749 ASSERT (((UINTN)String & BIT0) == 0);
750
751 //
752 // 1. Neither String nor Data shall be a null pointer.
753 //
754 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
755 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
756
757 //
758 // 2. The length of String shall not be greater than RSIZE_MAX.
759 //
760 if (RSIZE_MAX != 0) {
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
762 }
763
764 if (EndPointer != NULL) {
765 *EndPointer = (CHAR16 *)String;
766 }
767
768 //
769 // Ignore the pad spaces (space or tab)
770 //
771 while ((*String == L' ') || (*String == L'\t')) {
772 String++;
773 }
774
775 //
776 // Ignore leading Zeros after the spaces
777 //
778 while (*String == L'0') {
779 String++;
780 }
781
782 *Data = 0;
783
784 while (InternalIsDecimalDigitCharacter (*String)) {
785 //
786 // If the number represented by String overflows according to the range
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and
788 // RETURN_UNSUPPORTED is returned.
789 //
790 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {
791 *Data = MAX_UINT64;
792 if (EndPointer != NULL) {
793 *EndPointer = (CHAR16 *)String;
794 }
795
796 return RETURN_UNSUPPORTED;
797 }
798
799 *Data = MultU64x32 (*Data, 10) + (*String - L'0');
800 String++;
801 }
802
803 if (EndPointer != NULL) {
804 *EndPointer = (CHAR16 *)String;
805 }
806
807 return RETURN_SUCCESS;
808}
809
858RETURN_STATUS
859EFIAPI
861 IN CONST CHAR16 *String,
862 OUT CHAR16 **EndPointer OPTIONAL,
863 OUT UINTN *Data
864 )
865{
866 ASSERT (((UINTN)String & BIT0) == 0);
867
868 //
869 // 1. Neither String nor Data shall be a null pointer.
870 //
871 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
872 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
873
874 //
875 // 2. The length of String shall not be greater than RSIZE_MAX.
876 //
877 if (RSIZE_MAX != 0) {
878 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
879 }
880
881 if (EndPointer != NULL) {
882 *EndPointer = (CHAR16 *)String;
883 }
884
885 //
886 // Ignore the pad spaces (space or tab)
887 //
888 while ((*String == L' ') || (*String == L'\t')) {
889 String++;
890 }
891
892 //
893 // Ignore leading Zeros after the spaces
894 //
895 while (*String == L'0') {
896 String++;
897 }
898
899 if (CharToUpper (*String) == L'X') {
900 if (*(String - 1) != L'0') {
901 *Data = 0;
902 return RETURN_SUCCESS;
903 }
904
905 //
906 // Skip the 'X'
907 //
908 String++;
909 }
910
911 *Data = 0;
912
913 while (InternalIsHexaDecimalDigitCharacter (*String)) {
914 //
915 // If the number represented by String overflows according to the range
916 // defined by UINTN, then MAX_UINTN is stored in *Data and
917 // RETURN_UNSUPPORTED is returned.
918 //
919 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
920 *Data = MAX_UINTN;
921 if (EndPointer != NULL) {
922 *EndPointer = (CHAR16 *)String;
923 }
924
925 return RETURN_UNSUPPORTED;
926 }
927
928 *Data = (*Data << 4) + InternalHexCharToUintn (*String);
929 String++;
930 }
931
932 if (EndPointer != NULL) {
933 *EndPointer = (CHAR16 *)String;
934 }
935
936 return RETURN_SUCCESS;
937}
938
987RETURN_STATUS
988EFIAPI
990 IN CONST CHAR16 *String,
991 OUT CHAR16 **EndPointer OPTIONAL,
992 OUT UINT64 *Data
993 )
994{
995 ASSERT (((UINTN)String & BIT0) == 0);
996
997 //
998 // 1. Neither String nor Data shall be a null pointer.
999 //
1000 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1001 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1002
1003 //
1004 // 2. The length of String shall not be greater than RSIZE_MAX.
1005 //
1006 if (RSIZE_MAX != 0) {
1007 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1008 }
1009
1010 if (EndPointer != NULL) {
1011 *EndPointer = (CHAR16 *)String;
1012 }
1013
1014 //
1015 // Ignore the pad spaces (space or tab)
1016 //
1017 while ((*String == L' ') || (*String == L'\t')) {
1018 String++;
1019 }
1020
1021 //
1022 // Ignore leading Zeros after the spaces
1023 //
1024 while (*String == L'0') {
1025 String++;
1026 }
1027
1028 if (CharToUpper (*String) == L'X') {
1029 if (*(String - 1) != L'0') {
1030 *Data = 0;
1031 return RETURN_SUCCESS;
1032 }
1033
1034 //
1035 // Skip the 'X'
1036 //
1037 String++;
1038 }
1039
1040 *Data = 0;
1041
1042 while (InternalIsHexaDecimalDigitCharacter (*String)) {
1043 //
1044 // If the number represented by String overflows according to the range
1045 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1046 // RETURN_UNSUPPORTED is returned.
1047 //
1048 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {
1049 *Data = MAX_UINT64;
1050 if (EndPointer != NULL) {
1051 *EndPointer = (CHAR16 *)String;
1052 }
1053
1054 return RETURN_UNSUPPORTED;
1055 }
1056
1057 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);
1058 String++;
1059 }
1060
1061 if (EndPointer != NULL) {
1062 *EndPointer = (CHAR16 *)String;
1063 }
1064
1065 return RETURN_SUCCESS;
1066}
1067
1118RETURN_STATUS
1119EFIAPI
1121 IN CONST CHAR16 *String,
1122 OUT CHAR16 **EndPointer OPTIONAL,
1123 OUT IPv6_ADDRESS *Address,
1124 OUT UINT8 *PrefixLength OPTIONAL
1125 )
1126{
1127 RETURN_STATUS Status;
1128 UINTN AddressIndex;
1129 UINTN Uintn;
1130 IPv6_ADDRESS LocalAddress;
1131 UINT8 LocalPrefixLength;
1132 CONST CHAR16 *Pointer;
1133 CHAR16 *End;
1134 UINTN CompressStart;
1135 BOOLEAN ExpectPrefix;
1136
1137 LocalPrefixLength = MAX_UINT8;
1138 CompressStart = ARRAY_SIZE (Address->Addr);
1139 ExpectPrefix = FALSE;
1140
1141 ASSERT (((UINTN)String & BIT0) == 0);
1142
1143 //
1144 // 1. None of String or Guid shall be a null pointer.
1145 //
1146 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1147 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1148
1149 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1150 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1151 if (*Pointer != L':') {
1152 //
1153 // ":" or "/" should be followed by digit characters.
1154 //
1155 return RETURN_UNSUPPORTED;
1156 }
1157
1158 //
1159 // Meet second ":" after previous ":" or "/"
1160 // or meet first ":" in the beginning of String.
1161 //
1162 if (ExpectPrefix) {
1163 //
1164 // ":" shall not be after "/"
1165 //
1166 return RETURN_UNSUPPORTED;
1167 }
1168
1169 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
1170 //
1171 // "::" can only appear once.
1172 // "::" can only appear when address is not full length.
1173 //
1174 return RETURN_UNSUPPORTED;
1175 } else {
1176 //
1177 // Remember the start of zero compressing.
1178 //
1179 CompressStart = AddressIndex;
1180 Pointer++;
1181
1182 if (CompressStart == 0) {
1183 if (*Pointer != L':') {
1184 //
1185 // Single ":" shall not be in the beginning of String.
1186 //
1187 return RETURN_UNSUPPORTED;
1188 }
1189
1190 Pointer++;
1191 }
1192 }
1193 }
1194
1195 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1196 if (*Pointer == L'/') {
1197 //
1198 // Might be optional "/P" after "::".
1199 //
1200 if (CompressStart != AddressIndex) {
1201 return RETURN_UNSUPPORTED;
1202 }
1203 } else {
1204 break;
1205 }
1206 } else {
1207 if (!ExpectPrefix) {
1208 //
1209 // Get X.
1210 //
1211 Status = StrHexToUintnS (Pointer, &End, &Uintn);
1212 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
1213 //
1214 // Number of hexadecimal digit characters is no more than 4.
1215 //
1216 return RETURN_UNSUPPORTED;
1217 }
1218
1219 Pointer = End;
1220 //
1221 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1222 //
1223 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
1224 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
1225 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
1226 AddressIndex += 2;
1227 } else {
1228 //
1229 // Get P, then exit the loop.
1230 //
1231 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
1232 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
1233 //
1234 // Prefix length should not exceed 128.
1235 //
1236 return RETURN_UNSUPPORTED;
1237 }
1238
1239 LocalPrefixLength = (UINT8)Uintn;
1240 Pointer = End;
1241 break;
1242 }
1243 }
1244
1245 //
1246 // Skip ':' or "/"
1247 //
1248 if (*Pointer == L'/') {
1249 ExpectPrefix = TRUE;
1250 } else if (*Pointer == L':') {
1251 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1252 //
1253 // Meet additional ":" after all 8 16-bit address
1254 //
1255 break;
1256 }
1257 } else {
1258 //
1259 // Meet other character that is not "/" or ":" after all 8 16-bit address
1260 //
1261 break;
1262 }
1263
1264 Pointer++;
1265 }
1266
1267 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
1268 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
1269 )
1270 {
1271 //
1272 // Full length of address shall not have compressing zeros.
1273 // Non-full length of address shall have compressing zeros.
1274 //
1275 return RETURN_UNSUPPORTED;
1276 }
1277
1278 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
1279 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
1280 if (AddressIndex > CompressStart) {
1281 CopyMem (
1282 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
1283 &LocalAddress.Addr[CompressStart],
1284 AddressIndex - CompressStart
1285 );
1286 }
1287
1288 if (PrefixLength != NULL) {
1289 *PrefixLength = LocalPrefixLength;
1290 }
1291
1292 if (EndPointer != NULL) {
1293 *EndPointer = (CHAR16 *)Pointer;
1294 }
1295
1296 return RETURN_SUCCESS;
1297}
1298
1340RETURN_STATUS
1341EFIAPI
1343 IN CONST CHAR16 *String,
1344 OUT CHAR16 **EndPointer OPTIONAL,
1345 OUT IPv4_ADDRESS *Address,
1346 OUT UINT8 *PrefixLength OPTIONAL
1347 )
1348{
1349 RETURN_STATUS Status;
1350 UINTN AddressIndex;
1351 UINTN Uintn;
1352 IPv4_ADDRESS LocalAddress;
1353 UINT8 LocalPrefixLength;
1354 CHAR16 *Pointer;
1355
1356 LocalPrefixLength = MAX_UINT8;
1357
1358 ASSERT (((UINTN)String & BIT0) == 0);
1359
1360 //
1361 // 1. None of String or Guid shall be a null pointer.
1362 //
1363 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1364 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1365
1366 for (Pointer = (CHAR16 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1367 if (!InternalIsDecimalDigitCharacter (*Pointer)) {
1368 //
1369 // D or P contains invalid characters.
1370 //
1371 break;
1372 }
1373
1374 //
1375 // Get D or P.
1376 //
1377 Status = StrDecimalToUintnS ((CONST CHAR16 *)Pointer, &Pointer, &Uintn);
1378 if (RETURN_ERROR (Status)) {
1379 return RETURN_UNSUPPORTED;
1380 }
1381
1382 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1383 //
1384 // It's P.
1385 //
1386 if (Uintn > 32) {
1387 return RETURN_UNSUPPORTED;
1388 }
1389
1390 LocalPrefixLength = (UINT8)Uintn;
1391 } else {
1392 //
1393 // It's D.
1394 //
1395 if (Uintn > MAX_UINT8) {
1396 return RETURN_UNSUPPORTED;
1397 }
1398
1399 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
1400 AddressIndex++;
1401 }
1402
1403 //
1404 // Check the '.' or '/', depending on the AddressIndex.
1405 //
1406 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1407 if (*Pointer == L'/') {
1408 //
1409 // '/P' is in the String.
1410 // Skip "/" and get P in next loop.
1411 //
1412 Pointer++;
1413 } else {
1414 //
1415 // '/P' is not in the String.
1416 //
1417 break;
1418 }
1419 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1420 if (*Pointer == L'.') {
1421 //
1422 // D should be followed by '.'
1423 //
1424 Pointer++;
1425 } else {
1426 return RETURN_UNSUPPORTED;
1427 }
1428 }
1429 }
1430
1431 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1432 return RETURN_UNSUPPORTED;
1433 }
1434
1435 CopyMem (Address, &LocalAddress, sizeof (*Address));
1436 if (PrefixLength != NULL) {
1437 *PrefixLength = LocalPrefixLength;
1438 }
1439
1440 if (EndPointer != NULL) {
1441 *EndPointer = Pointer;
1442 }
1443
1444 return RETURN_SUCCESS;
1445}
1446
1489RETURN_STATUS
1490EFIAPI
1492 IN CONST CHAR16 *String,
1493 OUT GUID *Guid
1494 )
1495{
1496 RETURN_STATUS Status;
1497 GUID LocalGuid;
1498
1499 ASSERT (((UINTN)String & BIT0) == 0);
1500
1501 //
1502 // 1. None of String or Guid shall be a null pointer.
1503 //
1504 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1505 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
1506
1507 //
1508 // Get aabbccdd in big-endian.
1509 //
1510 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
1511 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != L'-')) {
1512 return RETURN_UNSUPPORTED;
1513 }
1514
1515 //
1516 // Convert big-endian to little-endian.
1517 //
1518 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
1519 String += 2 * sizeof (LocalGuid.Data1) + 1;
1520
1521 //
1522 // Get eeff in big-endian.
1523 //
1524 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
1525 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != L'-')) {
1526 return RETURN_UNSUPPORTED;
1527 }
1528
1529 //
1530 // Convert big-endian to little-endian.
1531 //
1532 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
1533 String += 2 * sizeof (LocalGuid.Data2) + 1;
1534
1535 //
1536 // Get gghh in big-endian.
1537 //
1538 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
1539 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != L'-')) {
1540 return RETURN_UNSUPPORTED;
1541 }
1542
1543 //
1544 // Convert big-endian to little-endian.
1545 //
1546 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
1547 String += 2 * sizeof (LocalGuid.Data3) + 1;
1548
1549 //
1550 // Get iijj.
1551 //
1552 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
1553 if (RETURN_ERROR (Status) || (String[2 * 2] != L'-')) {
1554 return RETURN_UNSUPPORTED;
1555 }
1556
1557 String += 2 * 2 + 1;
1558
1559 //
1560 // Get kkllmmnnoopp.
1561 //
1562 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
1563 if (RETURN_ERROR (Status)) {
1564 return RETURN_UNSUPPORTED;
1565 }
1566
1567 CopyGuid (Guid, &LocalGuid);
1568 return RETURN_SUCCESS;
1569}
1570
1604RETURN_STATUS
1605EFIAPI
1607 IN CONST CHAR16 *String,
1608 IN UINTN Length,
1609 OUT UINT8 *Buffer,
1610 IN UINTN MaxBufferSize
1611 )
1612{
1613 UINTN Index;
1614
1615 ASSERT (((UINTN)String & BIT0) == 0);
1616
1617 //
1618 // 1. None of String or Buffer shall be a null pointer.
1619 //
1620 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1621 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
1622
1623 //
1624 // 2. Length shall not be greater than RSIZE_MAX.
1625 //
1626 if (RSIZE_MAX != 0) {
1627 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1628 }
1629
1630 //
1631 // 3. Length shall not be odd.
1632 //
1633 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
1634
1635 //
1636 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1637 //
1638 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
1639
1640 //
1641 // 5. String shall not contains invalid hexadecimal digits.
1642 //
1643 for (Index = 0; Index < Length; Index++) {
1644 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
1645 break;
1646 }
1647 }
1648
1649 if (Index != Length) {
1650 return RETURN_UNSUPPORTED;
1651 }
1652
1653 //
1654 // Convert the hex string to bytes.
1655 //
1656 for (Index = 0; Index < Length; Index++) {
1657 //
1658 // For even characters, write the upper nibble for each buffer byte,
1659 // and for even characters, the lower nibble.
1660 //
1661 if ((Index & BIT0) == 0) {
1662 Buffer[Index / 2] = (UINT8)InternalHexCharToUintn (String[Index]) << 4;
1663 } else {
1664 Buffer[Index / 2] |= (UINT8)InternalHexCharToUintn (String[Index]);
1665 }
1666 }
1667
1668 return RETURN_SUCCESS;
1669}
1670
1685UINTN
1686EFIAPI
1688 IN CONST CHAR8 *String,
1689 IN UINTN MaxSize
1690 )
1691{
1692 UINTN Length;
1693
1694 //
1695 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1696 //
1697 if ((String == NULL) || (MaxSize == 0)) {
1698 return 0;
1699 }
1700
1701 //
1702 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1703 // terminating null character. If there is no null character in the first MaxSize characters of
1704 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1705 // be accessed by AsciiStrnLenS.
1706 //
1707 Length = 0;
1708 while (String[Length] != 0) {
1709 if (Length >= MaxSize - 1) {
1710 return MaxSize;
1711 }
1712
1713 Length++;
1714 }
1715
1716 return Length;
1717}
1718
1738UINTN
1739EFIAPI
1741 IN CONST CHAR8 *String,
1742 IN UINTN MaxSize
1743 )
1744{
1745 //
1746 // If String is a null pointer, then the AsciiStrnSizeS function returns
1747 // zero.
1748 //
1749 if (String == NULL) {
1750 return 0;
1751 }
1752
1753 //
1754 // Otherwise, the AsciiStrnSizeS function returns the size of the
1755 // Null-terminated Ascii string in bytes, including the Null terminator. If
1756 // there is no Null terminator in the first MaxSize characters of String,
1757 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1758 // consistent map with the AsciiStrnLenS function.
1759 //
1760 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
1761}
1762
1786RETURN_STATUS
1787EFIAPI
1789 OUT CHAR8 *Destination,
1790 IN UINTN DestMax,
1791 IN CONST CHAR8 *Source
1792 )
1793{
1794 UINTN SourceLen;
1795
1796 //
1797 // 1. Neither Destination nor Source shall be a null pointer.
1798 //
1799 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1800 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1801
1802 //
1803 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1804 //
1805 if (ASCII_RSIZE_MAX != 0) {
1806 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1807 }
1808
1809 //
1810 // 3. DestMax shall not equal zero.
1811 //
1812 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1813
1814 //
1815 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1816 //
1817 SourceLen = AsciiStrnLenS (Source, DestMax);
1818 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1819
1820 //
1821 // 5. Copying shall not take place between objects that overlap.
1822 //
1823 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1824
1825 //
1826 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1827 // null character) into the array pointed to by Destination.
1828 //
1829 while (*Source != 0) {
1830 *(Destination++) = *(Source++);
1831 }
1832
1833 *Destination = 0;
1834
1835 return RETURN_SUCCESS;
1836}
1837
1864RETURN_STATUS
1865EFIAPI
1867 OUT CHAR8 *Destination,
1868 IN UINTN DestMax,
1869 IN CONST CHAR8 *Source,
1870 IN UINTN Length
1871 )
1872{
1873 UINTN SourceLen;
1874
1875 //
1876 // 1. Neither Destination nor Source shall be a null pointer.
1877 //
1878 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1879 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1880
1881 //
1882 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1883 //
1884 if (ASCII_RSIZE_MAX != 0) {
1885 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1886 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1887 }
1888
1889 //
1890 // 3. DestMax shall not equal zero.
1891 //
1892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1893
1894 //
1895 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1896 //
1897 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));
1898 if (Length >= DestMax) {
1899 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1900 }
1901
1902 //
1903 // 5. Copying shall not take place between objects that overlap.
1904 //
1905 if (SourceLen > Length) {
1906 SourceLen = Length;
1907 }
1908
1909 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1910
1911 //
1912 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1913 // follow a null character are not copied) from the array pointed to by Source to the array
1914 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1915 // character.
1916 //
1917 while ((SourceLen > 0) && (*Source != 0)) {
1918 *(Destination++) = *(Source++);
1919 SourceLen--;
1920 }
1921
1922 *Destination = 0;
1923
1924 return RETURN_SUCCESS;
1925}
1926
1953RETURN_STATUS
1954EFIAPI
1956 IN OUT CHAR8 *Destination,
1957 IN UINTN DestMax,
1958 IN CONST CHAR8 *Source
1959 )
1960{
1961 UINTN DestLen;
1962 UINTN CopyLen;
1963 UINTN SourceLen;
1964
1965 //
1966 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1967 //
1968 DestLen = AsciiStrnLenS (Destination, DestMax);
1969 CopyLen = DestMax - DestLen;
1970
1971 //
1972 // 1. Neither Destination nor Source shall be a null pointer.
1973 //
1974 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1975 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1976
1977 //
1978 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1979 //
1980 if (ASCII_RSIZE_MAX != 0) {
1981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1982 }
1983
1984 //
1985 // 3. DestMax shall not equal zero.
1986 //
1987 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1988
1989 //
1990 // 4. CopyLen shall not equal zero.
1991 //
1992 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
1993
1994 //
1995 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1996 //
1997 SourceLen = AsciiStrnLenS (Source, CopyLen);
1998 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
1999
2000 //
2001 // 6. Copying shall not take place between objects that overlap.
2002 //
2003 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2004
2005 //
2006 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2007 // terminating null character) to the end of the string pointed to by Destination. The initial character
2008 // from Source overwrites the null character at the end of Destination.
2009 //
2010 Destination = Destination + DestLen;
2011 while (*Source != 0) {
2012 *(Destination++) = *(Source++);
2013 }
2014
2015 *Destination = 0;
2016
2017 return RETURN_SUCCESS;
2018}
2019
2049RETURN_STATUS
2050EFIAPI
2052 IN OUT CHAR8 *Destination,
2053 IN UINTN DestMax,
2054 IN CONST CHAR8 *Source,
2055 IN UINTN Length
2056 )
2057{
2058 UINTN DestLen;
2059 UINTN CopyLen;
2060 UINTN SourceLen;
2061
2062 //
2063 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2064 //
2065 DestLen = AsciiStrnLenS (Destination, DestMax);
2066 CopyLen = DestMax - DestLen;
2067
2068 //
2069 // 1. Neither Destination nor Source shall be a null pointer.
2070 //
2071 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2072 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2073
2074 //
2075 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2076 //
2077 if (ASCII_RSIZE_MAX != 0) {
2078 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2079 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2080 }
2081
2082 //
2083 // 3. DestMax shall not equal zero.
2084 //
2085 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2086
2087 //
2088 // 4. CopyLen shall not equal zero.
2089 //
2090 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2091
2092 //
2093 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2094 //
2095 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));
2096 if (Length >= CopyLen) {
2097 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2098 }
2099
2100 //
2101 // 6. Copying shall not take place between objects that overlap.
2102 //
2103 if (SourceLen > Length) {
2104 SourceLen = Length;
2105 }
2106
2107 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2108
2109 //
2110 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2111 // that follow a null character are not copied) from the array pointed to by Source to the end of
2112 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2113 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2114 // a null character.
2115 //
2116 Destination = Destination + DestLen;
2117 while ((SourceLen > 0) && (*Source != 0)) {
2118 *(Destination++) = *(Source++);
2119 SourceLen--;
2120 }
2121
2122 *Destination = 0;
2123
2124 return RETURN_SUCCESS;
2125}
2126
2168RETURN_STATUS
2169EFIAPI
2171 IN CONST CHAR8 *String,
2172 OUT CHAR8 **EndPointer OPTIONAL,
2173 OUT UINTN *Data
2174 )
2175{
2176 //
2177 // 1. Neither String nor Data shall be a null pointer.
2178 //
2179 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2180 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2181
2182 //
2183 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2184 //
2185 if (ASCII_RSIZE_MAX != 0) {
2186 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2187 }
2188
2189 if (EndPointer != NULL) {
2190 *EndPointer = (CHAR8 *)String;
2191 }
2192
2193 //
2194 // Ignore the pad spaces (space or tab)
2195 //
2196 while ((*String == ' ') || (*String == '\t')) {
2197 String++;
2198 }
2199
2200 //
2201 // Ignore leading Zeros after the spaces
2202 //
2203 while (*String == '0') {
2204 String++;
2205 }
2206
2207 *Data = 0;
2208
2209 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2210 //
2211 // If the number represented by String overflows according to the range
2212 // defined by UINTN, then MAX_UINTN is stored in *Data and
2213 // RETURN_UNSUPPORTED is returned.
2214 //
2215 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {
2216 *Data = MAX_UINTN;
2217 if (EndPointer != NULL) {
2218 *EndPointer = (CHAR8 *)String;
2219 }
2220
2221 return RETURN_UNSUPPORTED;
2222 }
2223
2224 *Data = *Data * 10 + (*String - '0');
2225 String++;
2226 }
2227
2228 if (EndPointer != NULL) {
2229 *EndPointer = (CHAR8 *)String;
2230 }
2231
2232 return RETURN_SUCCESS;
2233}
2234
2276RETURN_STATUS
2277EFIAPI
2279 IN CONST CHAR8 *String,
2280 OUT CHAR8 **EndPointer OPTIONAL,
2281 OUT UINT64 *Data
2282 )
2283{
2284 //
2285 // 1. Neither String nor Data shall be a null pointer.
2286 //
2287 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2288 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2289
2290 //
2291 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2292 //
2293 if (ASCII_RSIZE_MAX != 0) {
2294 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2295 }
2296
2297 if (EndPointer != NULL) {
2298 *EndPointer = (CHAR8 *)String;
2299 }
2300
2301 //
2302 // Ignore the pad spaces (space or tab)
2303 //
2304 while ((*String == ' ') || (*String == '\t')) {
2305 String++;
2306 }
2307
2308 //
2309 // Ignore leading Zeros after the spaces
2310 //
2311 while (*String == '0') {
2312 String++;
2313 }
2314
2315 *Data = 0;
2316
2317 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2318 //
2319 // If the number represented by String overflows according to the range
2320 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2321 // RETURN_UNSUPPORTED is returned.
2322 //
2323 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {
2324 *Data = MAX_UINT64;
2325 if (EndPointer != NULL) {
2326 *EndPointer = (CHAR8 *)String;
2327 }
2328
2329 return RETURN_UNSUPPORTED;
2330 }
2331
2332 *Data = MultU64x32 (*Data, 10) + (*String - '0');
2333 String++;
2334 }
2335
2336 if (EndPointer != NULL) {
2337 *EndPointer = (CHAR8 *)String;
2338 }
2339
2340 return RETURN_SUCCESS;
2341}
2342
2388RETURN_STATUS
2389EFIAPI
2391 IN CONST CHAR8 *String,
2392 OUT CHAR8 **EndPointer OPTIONAL,
2393 OUT UINTN *Data
2394 )
2395{
2396 //
2397 // 1. Neither String nor Data shall be a null pointer.
2398 //
2399 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2400 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2401
2402 //
2403 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2404 //
2405 if (ASCII_RSIZE_MAX != 0) {
2406 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2407 }
2408
2409 if (EndPointer != NULL) {
2410 *EndPointer = (CHAR8 *)String;
2411 }
2412
2413 //
2414 // Ignore the pad spaces (space or tab)
2415 //
2416 while ((*String == ' ') || (*String == '\t')) {
2417 String++;
2418 }
2419
2420 //
2421 // Ignore leading Zeros after the spaces
2422 //
2423 while (*String == '0') {
2424 String++;
2425 }
2426
2427 if (AsciiCharToUpper (*String) == 'X') {
2428 if (*(String - 1) != '0') {
2429 *Data = 0;
2430 return RETURN_SUCCESS;
2431 }
2432
2433 //
2434 // Skip the 'X'
2435 //
2436 String++;
2437 }
2438
2439 *Data = 0;
2440
2442 //
2443 // If the number represented by String overflows according to the range
2444 // defined by UINTN, then MAX_UINTN is stored in *Data and
2445 // RETURN_UNSUPPORTED is returned.
2446 //
2447 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {
2448 *Data = MAX_UINTN;
2449 if (EndPointer != NULL) {
2450 *EndPointer = (CHAR8 *)String;
2451 }
2452
2453 return RETURN_UNSUPPORTED;
2454 }
2455
2456 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);
2457 String++;
2458 }
2459
2460 if (EndPointer != NULL) {
2461 *EndPointer = (CHAR8 *)String;
2462 }
2463
2464 return RETURN_SUCCESS;
2465}
2466
2512RETURN_STATUS
2513EFIAPI
2515 IN CONST CHAR8 *String,
2516 OUT CHAR8 **EndPointer OPTIONAL,
2517 OUT UINT64 *Data
2518 )
2519{
2520 //
2521 // 1. Neither String nor Data shall be a null pointer.
2522 //
2523 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2524 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2525
2526 //
2527 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2528 //
2529 if (ASCII_RSIZE_MAX != 0) {
2530 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2531 }
2532
2533 if (EndPointer != NULL) {
2534 *EndPointer = (CHAR8 *)String;
2535 }
2536
2537 //
2538 // Ignore the pad spaces (space or tab)
2539 //
2540 while ((*String == ' ') || (*String == '\t')) {
2541 String++;
2542 }
2543
2544 //
2545 // Ignore leading Zeros after the spaces
2546 //
2547 while (*String == '0') {
2548 String++;
2549 }
2550
2551 if (AsciiCharToUpper (*String) == 'X') {
2552 if (*(String - 1) != '0') {
2553 *Data = 0;
2554 return RETURN_SUCCESS;
2555 }
2556
2557 //
2558 // Skip the 'X'
2559 //
2560 String++;
2561 }
2562
2563 *Data = 0;
2564
2566 //
2567 // If the number represented by String overflows according to the range
2568 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2569 // RETURN_UNSUPPORTED is returned.
2570 //
2571 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {
2572 *Data = MAX_UINT64;
2573 if (EndPointer != NULL) {
2574 *EndPointer = (CHAR8 *)String;
2575 }
2576
2577 return RETURN_UNSUPPORTED;
2578 }
2579
2580 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);
2581 String++;
2582 }
2583
2584 if (EndPointer != NULL) {
2585 *EndPointer = (CHAR8 *)String;
2586 }
2587
2588 return RETURN_SUCCESS;
2589}
2590
2631RETURN_STATUS
2632EFIAPI
2634 IN CONST CHAR16 *Source,
2635 OUT CHAR8 *Destination,
2636 IN UINTN DestMax
2637 )
2638{
2639 UINTN SourceLen;
2640
2641 ASSERT (((UINTN)Source & BIT0) == 0);
2642
2643 //
2644 // 1. Neither Destination nor Source shall be a null pointer.
2645 //
2646 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2647 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2648
2649 //
2650 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2651 //
2652 if (ASCII_RSIZE_MAX != 0) {
2653 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2654 }
2655
2656 if (RSIZE_MAX != 0) {
2657 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2658 }
2659
2660 //
2661 // 3. DestMax shall not equal zero.
2662 //
2663 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2664
2665 //
2666 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2667 //
2668 SourceLen = StrnLenS (Source, DestMax);
2669 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2670
2671 //
2672 // 5. Copying shall not take place between objects that overlap.
2673 //
2674 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2675
2676 //
2677 // convert string
2678 //
2679 while (*Source != '\0') {
2680 //
2681 // If any Unicode characters in Source contain
2682 // non-zero value in the upper 8 bits, then ASSERT().
2683 //
2684 ASSERT (*Source < 0x100);
2685 *(Destination++) = (CHAR8)*(Source++);
2686 }
2687
2688 *Destination = '\0';
2689
2690 return RETURN_SUCCESS;
2691}
2692
2738RETURN_STATUS
2739EFIAPI
2741 IN CONST CHAR16 *Source,
2742 IN UINTN Length,
2743 OUT CHAR8 *Destination,
2744 IN UINTN DestMax,
2745 OUT UINTN *DestinationLength
2746 )
2747{
2748 UINTN SourceLen;
2749
2750 ASSERT (((UINTN)Source & BIT0) == 0);
2751
2752 //
2753 // 1. None of Destination, Source or DestinationLength shall be a null
2754 // pointer.
2755 //
2756 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2757 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2758 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2759
2760 //
2761 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2762 // RSIZE_MAX.
2763 //
2764 if (ASCII_RSIZE_MAX != 0) {
2765 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2766 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2767 }
2768
2769 if (RSIZE_MAX != 0) {
2770 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2771 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2772 }
2773
2774 //
2775 // 3. DestMax shall not equal zero.
2776 //
2777 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2778
2779 //
2780 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2781 // StrnLenS(Source, DestMax).
2782 //
2783 SourceLen = StrnLenS (Source, DestMax);
2784 if (Length >= DestMax) {
2785 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2786 }
2787
2788 //
2789 // 5. Copying shall not take place between objects that overlap.
2790 //
2791 if (SourceLen > Length) {
2792 SourceLen = Length;
2793 }
2794
2795 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2796
2797 *DestinationLength = 0;
2798
2799 //
2800 // Convert string
2801 //
2802 while ((*Source != 0) && (SourceLen > 0)) {
2803 //
2804 // If any Unicode characters in Source contain non-zero value in the upper
2805 // 8 bits, then ASSERT().
2806 //
2807 ASSERT (*Source < 0x100);
2808 *(Destination++) = (CHAR8)*(Source++);
2809 SourceLen--;
2810 (*DestinationLength)++;
2811 }
2812
2813 *Destination = 0;
2814
2815 return RETURN_SUCCESS;
2816}
2817
2854RETURN_STATUS
2855EFIAPI
2857 IN CONST CHAR8 *Source,
2858 OUT CHAR16 *Destination,
2859 IN UINTN DestMax
2860 )
2861{
2862 UINTN SourceLen;
2863
2864 ASSERT (((UINTN)Destination & BIT0) == 0);
2865
2866 //
2867 // 1. Neither Destination nor Source shall be a null pointer.
2868 //
2869 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2870 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2871
2872 //
2873 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2874 //
2875 if (RSIZE_MAX != 0) {
2876 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2877 }
2878
2879 if (ASCII_RSIZE_MAX != 0) {
2880 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2881 }
2882
2883 //
2884 // 3. DestMax shall not equal zero.
2885 //
2886 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2887
2888 //
2889 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2890 //
2891 SourceLen = AsciiStrnLenS (Source, DestMax);
2892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2893
2894 //
2895 // 5. Copying shall not take place between objects that overlap.
2896 //
2897 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2898
2899 //
2900 // Convert string
2901 //
2902 while (*Source != '\0') {
2903 *(Destination++) = (CHAR16)(UINT8)*(Source++);
2904 }
2905
2906 *Destination = '\0';
2907
2908 return RETURN_SUCCESS;
2909}
2910
2953RETURN_STATUS
2954EFIAPI
2956 IN CONST CHAR8 *Source,
2957 IN UINTN Length,
2958 OUT CHAR16 *Destination,
2959 IN UINTN DestMax,
2960 OUT UINTN *DestinationLength
2961 )
2962{
2963 UINTN SourceLen;
2964
2965 ASSERT (((UINTN)Destination & BIT0) == 0);
2966
2967 //
2968 // 1. None of Destination, Source or DestinationLength shall be a null
2969 // pointer.
2970 //
2971 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2972 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2973 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2974
2975 //
2976 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2977 // RSIZE_MAX.
2978 //
2979 if (RSIZE_MAX != 0) {
2980 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2982 }
2983
2984 if (ASCII_RSIZE_MAX != 0) {
2985 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2986 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2987 }
2988
2989 //
2990 // 3. DestMax shall not equal zero.
2991 //
2992 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2993
2994 //
2995 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2996 // AsciiStrnLenS(Source, DestMax).
2997 //
2998 SourceLen = AsciiStrnLenS (Source, DestMax);
2999 if (Length >= DestMax) {
3000 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
3001 }
3002
3003 //
3004 // 5. Copying shall not take place between objects that overlap.
3005 //
3006 if (SourceLen > Length) {
3007 SourceLen = Length;
3008 }
3009
3010 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
3011
3012 *DestinationLength = 0;
3013
3014 //
3015 // Convert string
3016 //
3017 while ((*Source != 0) && (SourceLen > 0)) {
3018 *(Destination++) = (CHAR16)(UINT8)*(Source++);
3019 SourceLen--;
3020 (*DestinationLength)++;
3021 }
3022
3023 *Destination = 0;
3024
3025 return RETURN_SUCCESS;
3026}
3027
3076RETURN_STATUS
3077EFIAPI
3079 IN CONST CHAR8 *String,
3080 OUT CHAR8 **EndPointer OPTIONAL,
3081 OUT IPv6_ADDRESS *Address,
3082 OUT UINT8 *PrefixLength OPTIONAL
3083 )
3084{
3085 RETURN_STATUS Status;
3086 UINTN AddressIndex;
3087 UINTN Uintn;
3088 IPv6_ADDRESS LocalAddress;
3089 UINT8 LocalPrefixLength;
3090 CONST CHAR8 *Pointer;
3091 CHAR8 *End;
3092 UINTN CompressStart;
3093 BOOLEAN ExpectPrefix;
3094
3095 LocalPrefixLength = MAX_UINT8;
3096 CompressStart = ARRAY_SIZE (Address->Addr);
3097 ExpectPrefix = FALSE;
3098
3099 //
3100 // None of String or Address shall be a null pointer.
3101 //
3102 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3103 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3104
3105 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3107 if (*Pointer != ':') {
3108 //
3109 // ":" or "/" should be followed by digit characters.
3110 //
3111 return RETURN_UNSUPPORTED;
3112 }
3113
3114 //
3115 // Meet second ":" after previous ":" or "/"
3116 // or meet first ":" in the beginning of String.
3117 //
3118 if (ExpectPrefix) {
3119 //
3120 // ":" shall not be after "/"
3121 //
3122 return RETURN_UNSUPPORTED;
3123 }
3124
3125 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
3126 //
3127 // "::" can only appear once.
3128 // "::" can only appear when address is not full length.
3129 //
3130 return RETURN_UNSUPPORTED;
3131 } else {
3132 //
3133 // Remember the start of zero compressing.
3134 //
3135 CompressStart = AddressIndex;
3136 Pointer++;
3137
3138 if (CompressStart == 0) {
3139 if (*Pointer != ':') {
3140 //
3141 // Single ":" shall not be in the beginning of String.
3142 //
3143 return RETURN_UNSUPPORTED;
3144 }
3145
3146 Pointer++;
3147 }
3148 }
3149 }
3150
3152 if (*Pointer == '/') {
3153 //
3154 // Might be optional "/P" after "::".
3155 //
3156 if (CompressStart != AddressIndex) {
3157 return RETURN_UNSUPPORTED;
3158 }
3159 } else {
3160 break;
3161 }
3162 } else {
3163 if (!ExpectPrefix) {
3164 //
3165 // Get X.
3166 //
3167 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);
3168 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
3169 //
3170 // Number of hexadecimal digit characters is no more than 4.
3171 //
3172 return RETURN_UNSUPPORTED;
3173 }
3174
3175 Pointer = End;
3176 //
3177 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3178 //
3179 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
3180 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
3181 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
3182 AddressIndex += 2;
3183 } else {
3184 //
3185 // Get P, then exit the loop.
3186 //
3187 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);
3188 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
3189 //
3190 // Prefix length should not exceed 128.
3191 //
3192 return RETURN_UNSUPPORTED;
3193 }
3194
3195 LocalPrefixLength = (UINT8)Uintn;
3196 Pointer = End;
3197 break;
3198 }
3199 }
3200
3201 //
3202 // Skip ':' or "/"
3203 //
3204 if (*Pointer == '/') {
3205 ExpectPrefix = TRUE;
3206 } else if (*Pointer == ':') {
3207 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3208 //
3209 // Meet additional ":" after all 8 16-bit address
3210 //
3211 break;
3212 }
3213 } else {
3214 //
3215 // Meet other character that is not "/" or ":" after all 8 16-bit address
3216 //
3217 break;
3218 }
3219
3220 Pointer++;
3221 }
3222
3223 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
3224 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
3225 )
3226 {
3227 //
3228 // Full length of address shall not have compressing zeros.
3229 // Non-full length of address shall have compressing zeros.
3230 //
3231 return RETURN_UNSUPPORTED;
3232 }
3233
3234 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
3235 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
3236 if (AddressIndex > CompressStart) {
3237 CopyMem (
3238 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
3239 &LocalAddress.Addr[CompressStart],
3240 AddressIndex - CompressStart
3241 );
3242 }
3243
3244 if (PrefixLength != NULL) {
3245 *PrefixLength = LocalPrefixLength;
3246 }
3247
3248 if (EndPointer != NULL) {
3249 *EndPointer = (CHAR8 *)Pointer;
3250 }
3251
3252 return RETURN_SUCCESS;
3253}
3254
3294RETURN_STATUS
3295EFIAPI
3297 IN CONST CHAR8 *String,
3298 OUT CHAR8 **EndPointer OPTIONAL,
3299 OUT IPv4_ADDRESS *Address,
3300 OUT UINT8 *PrefixLength OPTIONAL
3301 )
3302{
3303 RETURN_STATUS Status;
3304 UINTN AddressIndex;
3305 UINTN Uintn;
3306 IPv4_ADDRESS LocalAddress;
3307 UINT8 LocalPrefixLength;
3308 CHAR8 *Pointer;
3309
3310 LocalPrefixLength = MAX_UINT8;
3311
3312 //
3313 // None of String or Address shall be a null pointer.
3314 //
3315 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3316 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3317
3318 for (Pointer = (CHAR8 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3319 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {
3320 //
3321 // D or P contains invalid characters.
3322 //
3323 break;
3324 }
3325
3326 //
3327 // Get D or P.
3328 //
3329 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *)Pointer, &Pointer, &Uintn);
3330 if (RETURN_ERROR (Status)) {
3331 return RETURN_UNSUPPORTED;
3332 }
3333
3334 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3335 //
3336 // It's P.
3337 //
3338 if (Uintn > 32) {
3339 return RETURN_UNSUPPORTED;
3340 }
3341
3342 LocalPrefixLength = (UINT8)Uintn;
3343 } else {
3344 //
3345 // It's D.
3346 //
3347 if (Uintn > MAX_UINT8) {
3348 return RETURN_UNSUPPORTED;
3349 }
3350
3351 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
3352 AddressIndex++;
3353 }
3354
3355 //
3356 // Check the '.' or '/', depending on the AddressIndex.
3357 //
3358 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3359 if (*Pointer == '/') {
3360 //
3361 // '/P' is in the String.
3362 // Skip "/" and get P in next loop.
3363 //
3364 Pointer++;
3365 } else {
3366 //
3367 // '/P' is not in the String.
3368 //
3369 break;
3370 }
3371 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3372 if (*Pointer == '.') {
3373 //
3374 // D should be followed by '.'
3375 //
3376 Pointer++;
3377 } else {
3378 return RETURN_UNSUPPORTED;
3379 }
3380 }
3381 }
3382
3383 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3384 return RETURN_UNSUPPORTED;
3385 }
3386
3387 CopyMem (Address, &LocalAddress, sizeof (*Address));
3388 if (PrefixLength != NULL) {
3389 *PrefixLength = LocalPrefixLength;
3390 }
3391
3392 if (EndPointer != NULL) {
3393 *EndPointer = Pointer;
3394 }
3395
3396 return RETURN_SUCCESS;
3397}
3398
3439RETURN_STATUS
3440EFIAPI
3442 IN CONST CHAR8 *String,
3443 OUT GUID *Guid
3444 )
3445{
3446 RETURN_STATUS Status;
3447 GUID LocalGuid;
3448
3449 //
3450 // None of String or Guid shall be a null pointer.
3451 //
3452 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3453 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
3454
3455 //
3456 // Get aabbccdd in big-endian.
3457 //
3458 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
3459 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != '-')) {
3460 return RETURN_UNSUPPORTED;
3461 }
3462
3463 //
3464 // Convert big-endian to little-endian.
3465 //
3466 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
3467 String += 2 * sizeof (LocalGuid.Data1) + 1;
3468
3469 //
3470 // Get eeff in big-endian.
3471 //
3472 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
3473 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != '-')) {
3474 return RETURN_UNSUPPORTED;
3475 }
3476
3477 //
3478 // Convert big-endian to little-endian.
3479 //
3480 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
3481 String += 2 * sizeof (LocalGuid.Data2) + 1;
3482
3483 //
3484 // Get gghh in big-endian.
3485 //
3486 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
3487 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != '-')) {
3488 return RETURN_UNSUPPORTED;
3489 }
3490
3491 //
3492 // Convert big-endian to little-endian.
3493 //
3494 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
3495 String += 2 * sizeof (LocalGuid.Data3) + 1;
3496
3497 //
3498 // Get iijj.
3499 //
3500 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
3501 if (RETURN_ERROR (Status) || (String[2 * 2] != '-')) {
3502 return RETURN_UNSUPPORTED;
3503 }
3504
3505 String += 2 * 2 + 1;
3506
3507 //
3508 // Get kkllmmnnoopp.
3509 //
3510 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
3511 if (RETURN_ERROR (Status)) {
3512 return RETURN_UNSUPPORTED;
3513 }
3514
3515 CopyGuid (Guid, &LocalGuid);
3516 return RETURN_SUCCESS;
3517}
3518
3550RETURN_STATUS
3551EFIAPI
3553 IN CONST CHAR8 *String,
3554 IN UINTN Length,
3555 OUT UINT8 *Buffer,
3556 IN UINTN MaxBufferSize
3557 )
3558{
3559 UINTN Index;
3560
3561 //
3562 // 1. None of String or Buffer shall be a null pointer.
3563 //
3564 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3565 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
3566
3567 //
3568 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3569 //
3570 if (ASCII_RSIZE_MAX != 0) {
3571 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3572 }
3573
3574 //
3575 // 3. Length shall not be odd.
3576 //
3577 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
3578
3579 //
3580 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3581 //
3582 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
3583
3584 //
3585 // 5. String shall not contains invalid hexadecimal digits.
3586 //
3587 for (Index = 0; Index < Length; Index++) {
3588 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {
3589 break;
3590 }
3591 }
3592
3593 if (Index != Length) {
3594 return RETURN_UNSUPPORTED;
3595 }
3596
3597 //
3598 // Convert the hex string to bytes.
3599 //
3600 for (Index = 0; Index < Length; Index++) {
3601 //
3602 // For even characters, write the upper nibble for each buffer byte,
3603 // and for even characters, the lower nibble.
3604 //
3605 if ((Index & BIT0) == 0) {
3606 Buffer[Index / 2] = (UINT8)InternalAsciiHexCharToUintn (String[Index]) << 4;
3607 } else {
3608 Buffer[Index / 2] |= (UINT8)InternalAsciiHexCharToUintn (String[Index]);
3609 }
3610 }
3611
3612 return RETURN_SUCCESS;
3613}
UINT64 UINTN
#define NULL
Definition: Base.h:312
#define CONST
Definition: Base.h:259
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:989
#define RETURN_ERROR(StatusCode)
Definition: Base.h:957
#define MIN(a, b)
Definition: Base.h:903
#define RETURN_ACCESS_DENIED
Definition: Base.h:1043
#define RETURN_UNSUPPORTED
Definition: Base.h:977
#define RETURN_SUCCESS
Definition: Base.h:962
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1279
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:972
#define RETURN_BAD_BUFFER_SIZE
Definition: Base.h:982
CHAR16 EFIAPI CharToUpper(IN CHAR16 Char)
Definition: String.c:307
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT16 EFIAPI SwapBytes16(IN UINT16 Value)
Definition: SwapBytes16.c:25
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
CHAR8 EFIAPI AsciiCharToUpper(IN CHAR8 Chr)
Definition: String.c:730
BOOLEAN EFIAPI InternalAsciiIsDecimalDigitCharacter(IN CHAR8 Char)
Definition: String.c:570
BOOLEAN EFIAPI InternalIsDecimalDigitCharacter(IN CHAR16 Char)
Definition: String.c:283
BOOLEAN EFIAPI InternalAsciiIsHexaDecimalDigitCharacter(IN CHAR8 Char)
Definition: String.c:593
UINTN EFIAPI InternalAsciiHexCharToUintn(IN CHAR8 Char)
Definition: String.c:752
UINTN EFIAPI InternalHexCharToUintn(IN CHAR16 Char)
Definition: String.c:333
BOOLEAN EFIAPI InternalIsHexaDecimalDigitCharacter(IN CHAR16 Char)
Definition: String.c:360
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(Expression)
Definition: DebugLib.h:391
#define MAX_UINTN
UINTN EFIAPI AsciiStrnLenS(IN CONST CHAR8 *String, IN UINTN MaxSize)
Definition: SafeString.c:1687
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:1866
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
BOOLEAN InternalSafeStringNoAsciiStrOverlap(IN CHAR8 *Str1, IN UINTN Size1, IN CHAR8 *Str2, IN UINTN Size2)
Definition: SafeString.c:91
RETURN_STATUS EFIAPI AsciiStrHexToUint64S(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:2514
RETURN_STATUS EFIAPI AsciiStrCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1955
RETURN_STATUS EFIAPI StrDecimalToUint64S(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:743
UINTN EFIAPI StrnSizeS(IN CONST CHAR16 *String, IN UINTN MaxSize)
Definition: SafeString.c:176
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2633
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
RETURN_STATUS EFIAPI AsciiStrDecimalToUintnS(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINTN *Data)
Definition: SafeString.c:2170
RETURN_STATUS EFIAPI AsciiStrHexToUintnS(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINTN *Data)
Definition: SafeString.c:2390
UINTN EFIAPI StrnLenS(IN CONST CHAR16 *String, IN UINTN MaxSize)
Definition: SafeString.c:119
RETURN_STATUS EFIAPI StrToIpv6Address(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT IPv6_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:1120
RETURN_STATUS EFIAPI StrToIpv4Address(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT IPv4_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:1342
RETURN_STATUS EFIAPI AsciiStrDecimalToUint64S(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:2278
RETURN_STATUS EFIAPI AsciiStrToGuid(IN CONST CHAR8 *String, OUT GUID *Guid)
Definition: SafeString.c:3441
RETURN_STATUS EFIAPI StrToGuid(IN CONST CHAR16 *String, OUT GUID *Guid)
Definition: SafeString.c:1491
RETURN_STATUS EFIAPI AsciiStrToIpv4Address(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT IPv4_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:3296
RETURN_STATUS EFIAPI StrHexToUintnS(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT UINTN *Data)
Definition: SafeString.c:860
UINTN EFIAPI AsciiStrnSizeS(IN CONST CHAR8 *String, IN UINTN MaxSize)
Definition: SafeString.c:1740
RETURN_STATUS EFIAPI StrHexToBytes(IN CONST CHAR16 *String, IN UINTN Length, OUT UINT8 *Buffer, IN UINTN MaxBufferSize)
Definition: SafeString.c:1606
RETURN_STATUS EFIAPI AsciiStrToIpv6Address(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT IPv6_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:3078
RETURN_STATUS EFIAPI StrnCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:507
RETURN_STATUS EFIAPI StrDecimalToUintnS(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT UINTN *Data)
Definition: SafeString.c:631
BOOLEAN InternalSafeStringIsOverlap(IN VOID *Base1, IN UINTN Size1, IN VOID *Base2, IN UINTN Size2)
Definition: SafeString.c:37
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2856
BOOLEAN InternalSafeStringNoStrOverlap(IN CHAR16 *Str1, IN UINTN Size1, IN CHAR16 *Str2, IN UINTN Size2)
Definition: SafeString.c:67
RETURN_STATUS EFIAPI StrHexToUint64S(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:989
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
RETURN_STATUS EFIAPI AsciiStrHexToBytes(IN CONST CHAR8 *String, IN UINTN Length, OUT UINT8 *Buffer, IN UINTN MaxBufferSize)
Definition: SafeString.c:3552
RETURN_STATUS EFIAPI AsciiStrnCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:2051
RETURN_STATUS EFIAPI AsciiStrnToUnicodeStrS(IN CONST CHAR8 *Source, IN UINTN Length, OUT CHAR16 *Destination, IN UINTN DestMax, OUT UINTN *DestinationLength)
Definition: SafeString.c:2955
RETURN_STATUS EFIAPI UnicodeStrnToAsciiStrS(IN CONST CHAR16 *Source, IN UINTN Length, OUT CHAR8 *Destination, IN UINTN DestMax, OUT UINTN *DestinationLength)
Definition: SafeString.c:2740
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1788
Definition: Base.h:213