TianoCore EDK2 master
Loading...
Searching...
No Matches
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, __func__, 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 BOOLEAN FoundLeadingZero;
867
868 FoundLeadingZero = FALSE;
869 ASSERT (((UINTN)String & BIT0) == 0);
870
871 //
872 // 1. Neither String nor Data shall be a null pointer.
873 //
874 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
875 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
876
877 //
878 // 2. The length of String shall not be greater than RSIZE_MAX.
879 //
880 if (RSIZE_MAX != 0) {
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
882 }
883
884 if (EndPointer != NULL) {
885 *EndPointer = (CHAR16 *)String;
886 }
887
888 //
889 // Ignore the pad spaces (space or tab)
890 //
891 while ((*String == L' ') || (*String == L'\t')) {
892 String++;
893 }
894
895 //
896 // Ignore leading Zeros after the spaces
897 //
898
899 FoundLeadingZero = *String == L'0';
900 while (*String == L'0') {
901 String++;
902 }
903
904 if (CharToUpper (*String) == L'X') {
905 if (!FoundLeadingZero) {
906 *Data = 0;
907 return RETURN_SUCCESS;
908 }
909
910 //
911 // Skip the 'X'
912 //
913 String++;
914 }
915
916 *Data = 0;
917
918 while (InternalIsHexaDecimalDigitCharacter (*String)) {
919 //
920 // If the number represented by String overflows according to the range
921 // defined by UINTN, then MAX_UINTN is stored in *Data and
922 // RETURN_UNSUPPORTED is returned.
923 //
924 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
925 *Data = MAX_UINTN;
926 if (EndPointer != NULL) {
927 *EndPointer = (CHAR16 *)String;
928 }
929
930 return RETURN_UNSUPPORTED;
931 }
932
933 *Data = (*Data << 4) + InternalHexCharToUintn (*String);
934 String++;
935 }
936
937 if (EndPointer != NULL) {
938 *EndPointer = (CHAR16 *)String;
939 }
940
941 return RETURN_SUCCESS;
942}
943
992RETURN_STATUS
993EFIAPI
995 IN CONST CHAR16 *String,
996 OUT CHAR16 **EndPointer OPTIONAL,
997 OUT UINT64 *Data
998 )
999{
1000 BOOLEAN FoundLeadingZero;
1001
1002 FoundLeadingZero = FALSE;
1003 ASSERT (((UINTN)String & BIT0) == 0);
1004
1005 //
1006 // 1. Neither String nor Data shall be a null pointer.
1007 //
1008 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1009 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1010
1011 //
1012 // 2. The length of String shall not be greater than RSIZE_MAX.
1013 //
1014 if (RSIZE_MAX != 0) {
1015 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1016 }
1017
1018 if (EndPointer != NULL) {
1019 *EndPointer = (CHAR16 *)String;
1020 }
1021
1022 //
1023 // Ignore the pad spaces (space or tab)
1024 //
1025 while ((*String == L' ') || (*String == L'\t')) {
1026 String++;
1027 }
1028
1029 //
1030 // Ignore leading Zeros after the spaces
1031 //
1032 FoundLeadingZero = *String == L'0';
1033 while (*String == L'0') {
1034 String++;
1035 }
1036
1037 if (CharToUpper (*String) == L'X') {
1038 if (!FoundLeadingZero) {
1039 *Data = 0;
1040 return RETURN_SUCCESS;
1041 }
1042
1043 //
1044 // Skip the 'X'
1045 //
1046 String++;
1047 }
1048
1049 *Data = 0;
1050
1051 while (InternalIsHexaDecimalDigitCharacter (*String)) {
1052 //
1053 // If the number represented by String overflows according to the range
1054 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1055 // RETURN_UNSUPPORTED is returned.
1056 //
1057 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {
1058 *Data = MAX_UINT64;
1059 if (EndPointer != NULL) {
1060 *EndPointer = (CHAR16 *)String;
1061 }
1062
1063 return RETURN_UNSUPPORTED;
1064 }
1065
1066 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);
1067 String++;
1068 }
1069
1070 if (EndPointer != NULL) {
1071 *EndPointer = (CHAR16 *)String;
1072 }
1073
1074 return RETURN_SUCCESS;
1075}
1076
1127RETURN_STATUS
1128EFIAPI
1130 IN CONST CHAR16 *String,
1131 OUT CHAR16 **EndPointer OPTIONAL,
1132 OUT IPv6_ADDRESS *Address,
1133 OUT UINT8 *PrefixLength OPTIONAL
1134 )
1135{
1136 RETURN_STATUS Status;
1137 UINTN AddressIndex;
1138 UINTN Uintn;
1139 IPv6_ADDRESS LocalAddress;
1140 UINT8 LocalPrefixLength;
1141 CONST CHAR16 *Pointer;
1142 CHAR16 *End;
1143 UINTN CompressStart;
1144 BOOLEAN ExpectPrefix;
1145
1146 LocalPrefixLength = MAX_UINT8;
1147 CompressStart = ARRAY_SIZE (Address->Addr);
1148 ExpectPrefix = FALSE;
1149
1150 ASSERT (((UINTN)String & BIT0) == 0);
1151
1152 //
1153 // 1. None of String or Guid shall be a null pointer.
1154 //
1155 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1156 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1157
1158 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1159 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1160 if (*Pointer != L':') {
1161 //
1162 // ":" or "/" should be followed by digit characters.
1163 //
1164 return RETURN_UNSUPPORTED;
1165 }
1166
1167 //
1168 // Meet second ":" after previous ":" or "/"
1169 // or meet first ":" in the beginning of String.
1170 //
1171 if (ExpectPrefix) {
1172 //
1173 // ":" shall not be after "/"
1174 //
1175 return RETURN_UNSUPPORTED;
1176 }
1177
1178 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
1179 //
1180 // "::" can only appear once.
1181 // "::" can only appear when address is not full length.
1182 //
1183 return RETURN_UNSUPPORTED;
1184 } else {
1185 //
1186 // Remember the start of zero compressing.
1187 //
1188 CompressStart = AddressIndex;
1189 Pointer++;
1190
1191 if (CompressStart == 0) {
1192 if (*Pointer != L':') {
1193 //
1194 // Single ":" shall not be in the beginning of String.
1195 //
1196 return RETURN_UNSUPPORTED;
1197 }
1198
1199 Pointer++;
1200 }
1201 }
1202 }
1203
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1205 if (*Pointer == L'/') {
1206 //
1207 // Might be optional "/P" after "::".
1208 //
1209 if (CompressStart != AddressIndex) {
1210 return RETURN_UNSUPPORTED;
1211 }
1212 } else {
1213 break;
1214 }
1215 } else {
1216 if (!ExpectPrefix) {
1217 //
1218 // Get X.
1219 //
1220 Status = StrHexToUintnS (Pointer, &End, &Uintn);
1221 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
1222 //
1223 // Number of hexadecimal digit characters is no more than 4.
1224 //
1225 return RETURN_UNSUPPORTED;
1226 }
1227
1228 Pointer = End;
1229 //
1230 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1231 //
1232 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
1233 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
1234 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
1235 AddressIndex += 2;
1236 } else {
1237 //
1238 // Get P, then exit the loop.
1239 //
1240 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
1241 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
1242 //
1243 // Prefix length should not exceed 128.
1244 //
1245 return RETURN_UNSUPPORTED;
1246 }
1247
1248 LocalPrefixLength = (UINT8)Uintn;
1249 Pointer = End;
1250 break;
1251 }
1252 }
1253
1254 //
1255 // Skip ':' or "/"
1256 //
1257 if (*Pointer == L'/') {
1258 ExpectPrefix = TRUE;
1259 } else if (*Pointer == L':') {
1260 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1261 //
1262 // Meet additional ":" after all 8 16-bit address
1263 //
1264 break;
1265 }
1266 } else {
1267 //
1268 // Meet other character that is not "/" or ":" after all 8 16-bit address
1269 //
1270 break;
1271 }
1272
1273 Pointer++;
1274 }
1275
1276 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
1277 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
1278 )
1279 {
1280 //
1281 // Full length of address shall not have compressing zeros.
1282 // Non-full length of address shall have compressing zeros.
1283 //
1284 return RETURN_UNSUPPORTED;
1285 }
1286
1287 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
1288 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
1289 if (AddressIndex > CompressStart) {
1290 CopyMem (
1291 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
1292 &LocalAddress.Addr[CompressStart],
1293 AddressIndex - CompressStart
1294 );
1295 }
1296
1297 if (PrefixLength != NULL) {
1298 *PrefixLength = LocalPrefixLength;
1299 }
1300
1301 if (EndPointer != NULL) {
1302 *EndPointer = (CHAR16 *)Pointer;
1303 }
1304
1305 return RETURN_SUCCESS;
1306}
1307
1349RETURN_STATUS
1350EFIAPI
1352 IN CONST CHAR16 *String,
1353 OUT CHAR16 **EndPointer OPTIONAL,
1354 OUT IPv4_ADDRESS *Address,
1355 OUT UINT8 *PrefixLength OPTIONAL
1356 )
1357{
1358 RETURN_STATUS Status;
1359 UINTN AddressIndex;
1360 UINTN Uintn;
1361 IPv4_ADDRESS LocalAddress;
1362 UINT8 LocalPrefixLength;
1363 CHAR16 *Pointer;
1364
1365 LocalPrefixLength = MAX_UINT8;
1366
1367 ASSERT (((UINTN)String & BIT0) == 0);
1368
1369 //
1370 // 1. None of String or Guid shall be a null pointer.
1371 //
1372 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1373 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1374
1375 for (Pointer = (CHAR16 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1376 if (!InternalIsDecimalDigitCharacter (*Pointer)) {
1377 //
1378 // D or P contains invalid characters.
1379 //
1380 break;
1381 }
1382
1383 //
1384 // Get D or P.
1385 //
1386 Status = StrDecimalToUintnS ((CONST CHAR16 *)Pointer, &Pointer, &Uintn);
1387 if (RETURN_ERROR (Status)) {
1388 return RETURN_UNSUPPORTED;
1389 }
1390
1391 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1392 //
1393 // It's P.
1394 //
1395 if (Uintn > 32) {
1396 return RETURN_UNSUPPORTED;
1397 }
1398
1399 LocalPrefixLength = (UINT8)Uintn;
1400 } else {
1401 //
1402 // It's D.
1403 //
1404 if (Uintn > MAX_UINT8) {
1405 return RETURN_UNSUPPORTED;
1406 }
1407
1408 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
1409 AddressIndex++;
1410 }
1411
1412 //
1413 // Check the '.' or '/', depending on the AddressIndex.
1414 //
1415 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1416 if (*Pointer == L'/') {
1417 //
1418 // '/P' is in the String.
1419 // Skip "/" and get P in next loop.
1420 //
1421 Pointer++;
1422 } else {
1423 //
1424 // '/P' is not in the String.
1425 //
1426 break;
1427 }
1428 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1429 if (*Pointer == L'.') {
1430 //
1431 // D should be followed by '.'
1432 //
1433 Pointer++;
1434 } else {
1435 return RETURN_UNSUPPORTED;
1436 }
1437 }
1438 }
1439
1440 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1441 return RETURN_UNSUPPORTED;
1442 }
1443
1444 CopyMem (Address, &LocalAddress, sizeof (*Address));
1445 if (PrefixLength != NULL) {
1446 *PrefixLength = LocalPrefixLength;
1447 }
1448
1449 if (EndPointer != NULL) {
1450 *EndPointer = Pointer;
1451 }
1452
1453 return RETURN_SUCCESS;
1454}
1455
1498RETURN_STATUS
1499EFIAPI
1501 IN CONST CHAR16 *String,
1502 OUT GUID *Guid
1503 )
1504{
1505 RETURN_STATUS Status;
1506 GUID LocalGuid;
1507
1508 ASSERT (((UINTN)String & BIT0) == 0);
1509
1510 //
1511 // 1. None of String or Guid shall be a null pointer.
1512 //
1513 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
1515
1516 //
1517 // Get aabbccdd in big-endian.
1518 //
1519 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
1520 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != L'-')) {
1521 return RETURN_UNSUPPORTED;
1522 }
1523
1524 //
1525 // Convert big-endian to little-endian.
1526 //
1527 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
1528 String += 2 * sizeof (LocalGuid.Data1) + 1;
1529
1530 //
1531 // Get eeff in big-endian.
1532 //
1533 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
1534 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != L'-')) {
1535 return RETURN_UNSUPPORTED;
1536 }
1537
1538 //
1539 // Convert big-endian to little-endian.
1540 //
1541 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
1542 String += 2 * sizeof (LocalGuid.Data2) + 1;
1543
1544 //
1545 // Get gghh in big-endian.
1546 //
1547 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
1548 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != L'-')) {
1549 return RETURN_UNSUPPORTED;
1550 }
1551
1552 //
1553 // Convert big-endian to little-endian.
1554 //
1555 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
1556 String += 2 * sizeof (LocalGuid.Data3) + 1;
1557
1558 //
1559 // Get iijj.
1560 //
1561 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
1562 if (RETURN_ERROR (Status) || (String[2 * 2] != L'-')) {
1563 return RETURN_UNSUPPORTED;
1564 }
1565
1566 String += 2 * 2 + 1;
1567
1568 //
1569 // Get kkllmmnnoopp.
1570 //
1571 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
1572 if (RETURN_ERROR (Status)) {
1573 return RETURN_UNSUPPORTED;
1574 }
1575
1576 CopyGuid (Guid, &LocalGuid);
1577 return RETURN_SUCCESS;
1578}
1579
1613RETURN_STATUS
1614EFIAPI
1616 IN CONST CHAR16 *String,
1617 IN UINTN Length,
1618 OUT UINT8 *Buffer,
1619 IN UINTN MaxBufferSize
1620 )
1621{
1622 UINTN Index;
1623
1624 ASSERT (((UINTN)String & BIT0) == 0);
1625
1626 //
1627 // 1. None of String or Buffer shall be a null pointer.
1628 //
1629 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1630 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
1631
1632 //
1633 // 2. Length shall not be greater than RSIZE_MAX.
1634 //
1635 if (RSIZE_MAX != 0) {
1636 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1637 }
1638
1639 //
1640 // 3. Length shall not be odd.
1641 //
1642 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
1643
1644 //
1645 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1646 //
1647 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
1648
1649 //
1650 // 5. String shall not contains invalid hexadecimal digits.
1651 //
1652 for (Index = 0; Index < Length; Index++) {
1653 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
1654 break;
1655 }
1656 }
1657
1658 if (Index != Length) {
1659 return RETURN_UNSUPPORTED;
1660 }
1661
1662 //
1663 // Convert the hex string to bytes.
1664 //
1665 for (Index = 0; Index < Length; Index++) {
1666 //
1667 // For even characters, write the upper nibble for each buffer byte,
1668 // and for even characters, the lower nibble.
1669 //
1670 if ((Index & BIT0) == 0) {
1671 Buffer[Index / 2] = (UINT8)InternalHexCharToUintn (String[Index]) << 4;
1672 } else {
1673 Buffer[Index / 2] |= (UINT8)InternalHexCharToUintn (String[Index]);
1674 }
1675 }
1676
1677 return RETURN_SUCCESS;
1678}
1679
1694UINTN
1695EFIAPI
1697 IN CONST CHAR8 *String,
1698 IN UINTN MaxSize
1699 )
1700{
1701 UINTN Length;
1702
1703 //
1704 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1705 //
1706 if ((String == NULL) || (MaxSize == 0)) {
1707 return 0;
1708 }
1709
1710 //
1711 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1712 // terminating null character. If there is no null character in the first MaxSize characters of
1713 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1714 // be accessed by AsciiStrnLenS.
1715 //
1716 Length = 0;
1717 while (String[Length] != 0) {
1718 if (Length >= MaxSize - 1) {
1719 return MaxSize;
1720 }
1721
1722 Length++;
1723 }
1724
1725 return Length;
1726}
1727
1747UINTN
1748EFIAPI
1750 IN CONST CHAR8 *String,
1751 IN UINTN MaxSize
1752 )
1753{
1754 //
1755 // If String is a null pointer, then the AsciiStrnSizeS function returns
1756 // zero.
1757 //
1758 if (String == NULL) {
1759 return 0;
1760 }
1761
1762 //
1763 // Otherwise, the AsciiStrnSizeS function returns the size of the
1764 // Null-terminated Ascii string in bytes, including the Null terminator. If
1765 // there is no Null terminator in the first MaxSize characters of String,
1766 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1767 // consistent map with the AsciiStrnLenS function.
1768 //
1769 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
1770}
1771
1795RETURN_STATUS
1796EFIAPI
1798 OUT CHAR8 *Destination,
1799 IN UINTN DestMax,
1800 IN CONST CHAR8 *Source
1801 )
1802{
1803 UINTN SourceLen;
1804
1805 //
1806 // 1. Neither Destination nor Source shall be a null pointer.
1807 //
1808 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1809 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1810
1811 //
1812 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1813 //
1814 if (ASCII_RSIZE_MAX != 0) {
1815 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1816 }
1817
1818 //
1819 // 3. DestMax shall not equal zero.
1820 //
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1822
1823 //
1824 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1825 //
1826 SourceLen = AsciiStrnLenS (Source, DestMax);
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1828
1829 //
1830 // 5. Copying shall not take place between objects that overlap.
1831 //
1832 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1833
1834 //
1835 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1836 // null character) into the array pointed to by Destination.
1837 //
1838 while (*Source != 0) {
1839 *(Destination++) = *(Source++);
1840 }
1841
1842 *Destination = 0;
1843
1844 return RETURN_SUCCESS;
1845}
1846
1873RETURN_STATUS
1874EFIAPI
1876 OUT CHAR8 *Destination,
1877 IN UINTN DestMax,
1878 IN CONST CHAR8 *Source,
1879 IN UINTN Length
1880 )
1881{
1882 UINTN SourceLen;
1883
1884 //
1885 // 1. Neither Destination nor Source shall be a null pointer.
1886 //
1887 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1888 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1889
1890 //
1891 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1892 //
1893 if (ASCII_RSIZE_MAX != 0) {
1894 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1895 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1896 }
1897
1898 //
1899 // 3. DestMax shall not equal zero.
1900 //
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1902
1903 //
1904 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1905 //
1906 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));
1907 if (Length >= DestMax) {
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1909 }
1910
1911 //
1912 // 5. Copying shall not take place between objects that overlap.
1913 //
1914 if (SourceLen > Length) {
1915 SourceLen = Length;
1916 }
1917
1918 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1919
1920 //
1921 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1922 // follow a null character are not copied) from the array pointed to by Source to the array
1923 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1924 // character.
1925 //
1926 while ((SourceLen > 0) && (*Source != 0)) {
1927 *(Destination++) = *(Source++);
1928 SourceLen--;
1929 }
1930
1931 *Destination = 0;
1932
1933 return RETURN_SUCCESS;
1934}
1935
1962RETURN_STATUS
1963EFIAPI
1965 IN OUT CHAR8 *Destination,
1966 IN UINTN DestMax,
1967 IN CONST CHAR8 *Source
1968 )
1969{
1970 UINTN DestLen;
1971 UINTN CopyLen;
1972 UINTN SourceLen;
1973
1974 //
1975 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1976 //
1977 DestLen = AsciiStrnLenS (Destination, DestMax);
1978 CopyLen = DestMax - DestLen;
1979
1980 //
1981 // 1. Neither Destination nor Source shall be a null pointer.
1982 //
1983 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1984 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1985
1986 //
1987 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1988 //
1989 if (ASCII_RSIZE_MAX != 0) {
1990 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1991 }
1992
1993 //
1994 // 3. DestMax shall not equal zero.
1995 //
1996 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1997
1998 //
1999 // 4. CopyLen shall not equal zero.
2000 //
2001 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2002
2003 //
2004 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2005 //
2006 SourceLen = AsciiStrnLenS (Source, CopyLen);
2007 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2008
2009 //
2010 // 6. Copying shall not take place between objects that overlap.
2011 //
2012 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2013
2014 //
2015 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2016 // terminating null character) to the end of the string pointed to by Destination. The initial character
2017 // from Source overwrites the null character at the end of Destination.
2018 //
2019 Destination = Destination + DestLen;
2020 while (*Source != 0) {
2021 *(Destination++) = *(Source++);
2022 }
2023
2024 *Destination = 0;
2025
2026 return RETURN_SUCCESS;
2027}
2028
2058RETURN_STATUS
2059EFIAPI
2061 IN OUT CHAR8 *Destination,
2062 IN UINTN DestMax,
2063 IN CONST CHAR8 *Source,
2064 IN UINTN Length
2065 )
2066{
2067 UINTN DestLen;
2068 UINTN CopyLen;
2069 UINTN SourceLen;
2070
2071 //
2072 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2073 //
2074 DestLen = AsciiStrnLenS (Destination, DestMax);
2075 CopyLen = DestMax - DestLen;
2076
2077 //
2078 // 1. Neither Destination nor Source shall be a null pointer.
2079 //
2080 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2081 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2082
2083 //
2084 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2085 //
2086 if (ASCII_RSIZE_MAX != 0) {
2087 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2088 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2089 }
2090
2091 //
2092 // 3. DestMax shall not equal zero.
2093 //
2094 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2095
2096 //
2097 // 4. CopyLen shall not equal zero.
2098 //
2099 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2100
2101 //
2102 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2103 //
2104 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));
2105 if (Length >= CopyLen) {
2106 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2107 }
2108
2109 //
2110 // 6. Copying shall not take place between objects that overlap.
2111 //
2112 if (SourceLen > Length) {
2113 SourceLen = Length;
2114 }
2115
2116 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2117
2118 //
2119 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2120 // that follow a null character are not copied) from the array pointed to by Source to the end of
2121 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2122 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2123 // a null character.
2124 //
2125 Destination = Destination + DestLen;
2126 while ((SourceLen > 0) && (*Source != 0)) {
2127 *(Destination++) = *(Source++);
2128 SourceLen--;
2129 }
2130
2131 *Destination = 0;
2132
2133 return RETURN_SUCCESS;
2134}
2135
2177RETURN_STATUS
2178EFIAPI
2180 IN CONST CHAR8 *String,
2181 OUT CHAR8 **EndPointer OPTIONAL,
2182 OUT UINTN *Data
2183 )
2184{
2185 //
2186 // 1. Neither String nor Data shall be a null pointer.
2187 //
2188 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2189 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2190
2191 //
2192 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2193 //
2194 if (ASCII_RSIZE_MAX != 0) {
2195 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2196 }
2197
2198 if (EndPointer != NULL) {
2199 *EndPointer = (CHAR8 *)String;
2200 }
2201
2202 //
2203 // Ignore the pad spaces (space or tab)
2204 //
2205 while ((*String == ' ') || (*String == '\t')) {
2206 String++;
2207 }
2208
2209 //
2210 // Ignore leading Zeros after the spaces
2211 //
2212 while (*String == '0') {
2213 String++;
2214 }
2215
2216 *Data = 0;
2217
2218 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2219 //
2220 // If the number represented by String overflows according to the range
2221 // defined by UINTN, then MAX_UINTN is stored in *Data and
2222 // RETURN_UNSUPPORTED is returned.
2223 //
2224 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {
2225 *Data = MAX_UINTN;
2226 if (EndPointer != NULL) {
2227 *EndPointer = (CHAR8 *)String;
2228 }
2229
2230 return RETURN_UNSUPPORTED;
2231 }
2232
2233 *Data = *Data * 10 + (*String - '0');
2234 String++;
2235 }
2236
2237 if (EndPointer != NULL) {
2238 *EndPointer = (CHAR8 *)String;
2239 }
2240
2241 return RETURN_SUCCESS;
2242}
2243
2285RETURN_STATUS
2286EFIAPI
2288 IN CONST CHAR8 *String,
2289 OUT CHAR8 **EndPointer OPTIONAL,
2290 OUT UINT64 *Data
2291 )
2292{
2293 //
2294 // 1. Neither String nor Data shall be a null pointer.
2295 //
2296 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2297 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2298
2299 //
2300 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2301 //
2302 if (ASCII_RSIZE_MAX != 0) {
2303 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2304 }
2305
2306 if (EndPointer != NULL) {
2307 *EndPointer = (CHAR8 *)String;
2308 }
2309
2310 //
2311 // Ignore the pad spaces (space or tab)
2312 //
2313 while ((*String == ' ') || (*String == '\t')) {
2314 String++;
2315 }
2316
2317 //
2318 // Ignore leading Zeros after the spaces
2319 //
2320 while (*String == '0') {
2321 String++;
2322 }
2323
2324 *Data = 0;
2325
2326 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2327 //
2328 // If the number represented by String overflows according to the range
2329 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2330 // RETURN_UNSUPPORTED is returned.
2331 //
2332 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {
2333 *Data = MAX_UINT64;
2334 if (EndPointer != NULL) {
2335 *EndPointer = (CHAR8 *)String;
2336 }
2337
2338 return RETURN_UNSUPPORTED;
2339 }
2340
2341 *Data = MultU64x32 (*Data, 10) + (*String - '0');
2342 String++;
2343 }
2344
2345 if (EndPointer != NULL) {
2346 *EndPointer = (CHAR8 *)String;
2347 }
2348
2349 return RETURN_SUCCESS;
2350}
2351
2397RETURN_STATUS
2398EFIAPI
2400 IN CONST CHAR8 *String,
2401 OUT CHAR8 **EndPointer OPTIONAL,
2402 OUT UINTN *Data
2403 )
2404{
2405 BOOLEAN FoundLeadingZero;
2406
2407 FoundLeadingZero = FALSE;
2408 //
2409 // 1. Neither String nor Data shall be a null pointer.
2410 //
2411 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2412 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2413
2414 //
2415 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2416 //
2417 if (ASCII_RSIZE_MAX != 0) {
2418 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2419 }
2420
2421 if (EndPointer != NULL) {
2422 *EndPointer = (CHAR8 *)String;
2423 }
2424
2425 //
2426 // Ignore the pad spaces (space or tab)
2427 //
2428 while ((*String == ' ') || (*String == '\t')) {
2429 String++;
2430 }
2431
2432 //
2433 // Ignore leading Zeros after the spaces
2434 //
2435 FoundLeadingZero = *String == '0';
2436 while (*String == '0') {
2437 String++;
2438 }
2439
2440 if (AsciiCharToUpper (*String) == 'X') {
2441 if (!FoundLeadingZero) {
2442 *Data = 0;
2443 return RETURN_SUCCESS;
2444 }
2445
2446 //
2447 // Skip the 'X'
2448 //
2449 String++;
2450 }
2451
2452 *Data = 0;
2453
2455 //
2456 // If the number represented by String overflows according to the range
2457 // defined by UINTN, then MAX_UINTN is stored in *Data and
2458 // RETURN_UNSUPPORTED is returned.
2459 //
2460 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {
2461 *Data = MAX_UINTN;
2462 if (EndPointer != NULL) {
2463 *EndPointer = (CHAR8 *)String;
2464 }
2465
2466 return RETURN_UNSUPPORTED;
2467 }
2468
2469 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);
2470 String++;
2471 }
2472
2473 if (EndPointer != NULL) {
2474 *EndPointer = (CHAR8 *)String;
2475 }
2476
2477 return RETURN_SUCCESS;
2478}
2479
2525RETURN_STATUS
2526EFIAPI
2528 IN CONST CHAR8 *String,
2529 OUT CHAR8 **EndPointer OPTIONAL,
2530 OUT UINT64 *Data
2531 )
2532{
2533 BOOLEAN FoundLeadingZero;
2534
2535 FoundLeadingZero = FALSE;
2536 //
2537 // 1. Neither String nor Data shall be a null pointer.
2538 //
2539 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2540 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2541
2542 //
2543 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2544 //
2545 if (ASCII_RSIZE_MAX != 0) {
2546 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2547 }
2548
2549 if (EndPointer != NULL) {
2550 *EndPointer = (CHAR8 *)String;
2551 }
2552
2553 //
2554 // Ignore the pad spaces (space or tab)
2555 //
2556 while ((*String == ' ') || (*String == '\t')) {
2557 String++;
2558 }
2559
2560 //
2561 // Ignore leading Zeros after the spaces
2562 //
2563 FoundLeadingZero = *String == '0';
2564 while (*String == '0') {
2565 String++;
2566 }
2567
2568 if (AsciiCharToUpper (*String) == 'X') {
2569 if (!FoundLeadingZero) {
2570 *Data = 0;
2571 return RETURN_SUCCESS;
2572 }
2573
2574 //
2575 // Skip the 'X'
2576 //
2577 String++;
2578 }
2579
2580 *Data = 0;
2581
2583 //
2584 // If the number represented by String overflows according to the range
2585 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2586 // RETURN_UNSUPPORTED is returned.
2587 //
2588 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {
2589 *Data = MAX_UINT64;
2590 if (EndPointer != NULL) {
2591 *EndPointer = (CHAR8 *)String;
2592 }
2593
2594 return RETURN_UNSUPPORTED;
2595 }
2596
2597 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);
2598 String++;
2599 }
2600
2601 if (EndPointer != NULL) {
2602 *EndPointer = (CHAR8 *)String;
2603 }
2604
2605 return RETURN_SUCCESS;
2606}
2607
2648RETURN_STATUS
2649EFIAPI
2651 IN CONST CHAR16 *Source,
2652 OUT CHAR8 *Destination,
2653 IN UINTN DestMax
2654 )
2655{
2656 UINTN SourceLen;
2657
2658 ASSERT (((UINTN)Source & BIT0) == 0);
2659
2660 //
2661 // 1. Neither Destination nor Source shall be a null pointer.
2662 //
2663 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2664 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2665
2666 //
2667 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2668 //
2669 if (ASCII_RSIZE_MAX != 0) {
2670 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2671 }
2672
2673 if (RSIZE_MAX != 0) {
2674 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2675 }
2676
2677 //
2678 // 3. DestMax shall not equal zero.
2679 //
2680 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2681
2682 //
2683 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2684 //
2685 SourceLen = StrnLenS (Source, DestMax);
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2687
2688 //
2689 // 5. Copying shall not take place between objects that overlap.
2690 //
2691 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2692
2693 //
2694 // convert string
2695 //
2696 while (*Source != '\0') {
2697 //
2698 // If any Unicode characters in Source contain
2699 // non-zero value in the upper 8 bits, then ASSERT().
2700 //
2701 ASSERT (*Source < 0x100);
2702 *(Destination++) = (CHAR8)*(Source++);
2703 }
2704
2705 *Destination = '\0';
2706
2707 return RETURN_SUCCESS;
2708}
2709
2755RETURN_STATUS
2756EFIAPI
2758 IN CONST CHAR16 *Source,
2759 IN UINTN Length,
2760 OUT CHAR8 *Destination,
2761 IN UINTN DestMax,
2762 OUT UINTN *DestinationLength
2763 )
2764{
2765 UINTN SourceLen;
2766
2767 ASSERT (((UINTN)Source & BIT0) == 0);
2768
2769 //
2770 // 1. None of Destination, Source or DestinationLength shall be a null
2771 // pointer.
2772 //
2773 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2774 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2775 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2776
2777 //
2778 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2779 // RSIZE_MAX.
2780 //
2781 if (ASCII_RSIZE_MAX != 0) {
2782 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2783 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2784 }
2785
2786 if (RSIZE_MAX != 0) {
2787 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2788 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2789 }
2790
2791 //
2792 // 3. DestMax shall not equal zero.
2793 //
2794 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2795
2796 //
2797 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2798 // StrnLenS(Source, DestMax).
2799 //
2800 SourceLen = StrnLenS (Source, DestMax);
2801 if (Length >= DestMax) {
2802 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2803 }
2804
2805 //
2806 // 5. Copying shall not take place between objects that overlap.
2807 //
2808 if (SourceLen > Length) {
2809 SourceLen = Length;
2810 }
2811
2812 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2813
2814 *DestinationLength = 0;
2815
2816 //
2817 // Convert string
2818 //
2819 while ((*Source != 0) && (SourceLen > 0)) {
2820 //
2821 // If any Unicode characters in Source contain non-zero value in the upper
2822 // 8 bits, then ASSERT().
2823 //
2824 ASSERT (*Source < 0x100);
2825 *(Destination++) = (CHAR8)*(Source++);
2826 SourceLen--;
2827 (*DestinationLength)++;
2828 }
2829
2830 *Destination = 0;
2831
2832 return RETURN_SUCCESS;
2833}
2834
2871RETURN_STATUS
2872EFIAPI
2874 IN CONST CHAR8 *Source,
2875 OUT CHAR16 *Destination,
2876 IN UINTN DestMax
2877 )
2878{
2879 UINTN SourceLen;
2880
2881 ASSERT (((UINTN)Destination & BIT0) == 0);
2882
2883 //
2884 // 1. Neither Destination nor Source shall be a null pointer.
2885 //
2886 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2887 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2888
2889 //
2890 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2891 //
2892 if (RSIZE_MAX != 0) {
2893 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2894 }
2895
2896 if (ASCII_RSIZE_MAX != 0) {
2897 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2898 }
2899
2900 //
2901 // 3. DestMax shall not equal zero.
2902 //
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2904
2905 //
2906 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2907 //
2908 SourceLen = AsciiStrnLenS (Source, DestMax);
2909 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2910
2911 //
2912 // 5. Copying shall not take place between objects that overlap.
2913 //
2914 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2915
2916 //
2917 // Convert string
2918 //
2919 while (*Source != '\0') {
2920 *(Destination++) = (CHAR16)(UINT8)*(Source++);
2921 }
2922
2923 *Destination = '\0';
2924
2925 return RETURN_SUCCESS;
2926}
2927
2970RETURN_STATUS
2971EFIAPI
2973 IN CONST CHAR8 *Source,
2974 IN UINTN Length,
2975 OUT CHAR16 *Destination,
2976 IN UINTN DestMax,
2977 OUT UINTN *DestinationLength
2978 )
2979{
2980 UINTN SourceLen;
2981
2982 ASSERT (((UINTN)Destination & BIT0) == 0);
2983
2984 //
2985 // 1. None of Destination, Source or DestinationLength shall be a null
2986 // pointer.
2987 //
2988 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2989 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2990 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2991
2992 //
2993 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2994 // RSIZE_MAX.
2995 //
2996 if (RSIZE_MAX != 0) {
2997 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2998 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2999 }
3000
3001 if (ASCII_RSIZE_MAX != 0) {
3002 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3004 }
3005
3006 //
3007 // 3. DestMax shall not equal zero.
3008 //
3009 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
3010
3011 //
3012 // 4. If Length is not less than DestMax, then DestMax shall be greater than
3013 // AsciiStrnLenS(Source, DestMax).
3014 //
3015 SourceLen = AsciiStrnLenS (Source, DestMax);
3016 if (Length >= DestMax) {
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
3018 }
3019
3020 //
3021 // 5. Copying shall not take place between objects that overlap.
3022 //
3023 if (SourceLen > Length) {
3024 SourceLen = Length;
3025 }
3026
3027 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
3028
3029 *DestinationLength = 0;
3030
3031 //
3032 // Convert string
3033 //
3034 while ((*Source != 0) && (SourceLen > 0)) {
3035 *(Destination++) = (CHAR16)(UINT8)*(Source++);
3036 SourceLen--;
3037 (*DestinationLength)++;
3038 }
3039
3040 *Destination = 0;
3041
3042 return RETURN_SUCCESS;
3043}
3044
3093RETURN_STATUS
3094EFIAPI
3096 IN CONST CHAR8 *String,
3097 OUT CHAR8 **EndPointer OPTIONAL,
3098 OUT IPv6_ADDRESS *Address,
3099 OUT UINT8 *PrefixLength OPTIONAL
3100 )
3101{
3102 RETURN_STATUS Status;
3103 UINTN AddressIndex;
3104 UINTN Uintn;
3105 IPv6_ADDRESS LocalAddress;
3106 UINT8 LocalPrefixLength;
3107 CONST CHAR8 *Pointer;
3108 CHAR8 *End;
3109 UINTN CompressStart;
3110 BOOLEAN ExpectPrefix;
3111
3112 LocalPrefixLength = MAX_UINT8;
3113 CompressStart = ARRAY_SIZE (Address->Addr);
3114 ExpectPrefix = FALSE;
3115
3116 //
3117 // None of String or Address shall be a null pointer.
3118 //
3119 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3120 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3121
3122 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3124 if (*Pointer != ':') {
3125 //
3126 // ":" or "/" should be followed by digit characters.
3127 //
3128 return RETURN_UNSUPPORTED;
3129 }
3130
3131 //
3132 // Meet second ":" after previous ":" or "/"
3133 // or meet first ":" in the beginning of String.
3134 //
3135 if (ExpectPrefix) {
3136 //
3137 // ":" shall not be after "/"
3138 //
3139 return RETURN_UNSUPPORTED;
3140 }
3141
3142 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
3143 //
3144 // "::" can only appear once.
3145 // "::" can only appear when address is not full length.
3146 //
3147 return RETURN_UNSUPPORTED;
3148 } else {
3149 //
3150 // Remember the start of zero compressing.
3151 //
3152 CompressStart = AddressIndex;
3153 Pointer++;
3154
3155 if (CompressStart == 0) {
3156 if (*Pointer != ':') {
3157 //
3158 // Single ":" shall not be in the beginning of String.
3159 //
3160 return RETURN_UNSUPPORTED;
3161 }
3162
3163 Pointer++;
3164 }
3165 }
3166 }
3167
3169 if (*Pointer == '/') {
3170 //
3171 // Might be optional "/P" after "::".
3172 //
3173 if (CompressStart != AddressIndex) {
3174 return RETURN_UNSUPPORTED;
3175 }
3176 } else {
3177 break;
3178 }
3179 } else {
3180 if (!ExpectPrefix) {
3181 //
3182 // Get X.
3183 //
3184 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);
3185 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
3186 //
3187 // Number of hexadecimal digit characters is no more than 4.
3188 //
3189 return RETURN_UNSUPPORTED;
3190 }
3191
3192 Pointer = End;
3193 //
3194 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3195 //
3196 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
3197 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
3198 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
3199 AddressIndex += 2;
3200 } else {
3201 //
3202 // Get P, then exit the loop.
3203 //
3204 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);
3205 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
3206 //
3207 // Prefix length should not exceed 128.
3208 //
3209 return RETURN_UNSUPPORTED;
3210 }
3211
3212 LocalPrefixLength = (UINT8)Uintn;
3213 Pointer = End;
3214 break;
3215 }
3216 }
3217
3218 //
3219 // Skip ':' or "/"
3220 //
3221 if (*Pointer == '/') {
3222 ExpectPrefix = TRUE;
3223 } else if (*Pointer == ':') {
3224 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3225 //
3226 // Meet additional ":" after all 8 16-bit address
3227 //
3228 break;
3229 }
3230 } else {
3231 //
3232 // Meet other character that is not "/" or ":" after all 8 16-bit address
3233 //
3234 break;
3235 }
3236
3237 Pointer++;
3238 }
3239
3240 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
3241 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
3242 )
3243 {
3244 //
3245 // Full length of address shall not have compressing zeros.
3246 // Non-full length of address shall have compressing zeros.
3247 //
3248 return RETURN_UNSUPPORTED;
3249 }
3250
3251 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
3252 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
3253 if (AddressIndex > CompressStart) {
3254 CopyMem (
3255 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
3256 &LocalAddress.Addr[CompressStart],
3257 AddressIndex - CompressStart
3258 );
3259 }
3260
3261 if (PrefixLength != NULL) {
3262 *PrefixLength = LocalPrefixLength;
3263 }
3264
3265 if (EndPointer != NULL) {
3266 *EndPointer = (CHAR8 *)Pointer;
3267 }
3268
3269 return RETURN_SUCCESS;
3270}
3271
3311RETURN_STATUS
3312EFIAPI
3314 IN CONST CHAR8 *String,
3315 OUT CHAR8 **EndPointer OPTIONAL,
3316 OUT IPv4_ADDRESS *Address,
3317 OUT UINT8 *PrefixLength OPTIONAL
3318 )
3319{
3320 RETURN_STATUS Status;
3321 UINTN AddressIndex;
3322 UINTN Uintn;
3323 IPv4_ADDRESS LocalAddress;
3324 UINT8 LocalPrefixLength;
3325 CHAR8 *Pointer;
3326
3327 LocalPrefixLength = MAX_UINT8;
3328
3329 //
3330 // None of String or Address shall be a null pointer.
3331 //
3332 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3333 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3334
3335 for (Pointer = (CHAR8 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3336 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {
3337 //
3338 // D or P contains invalid characters.
3339 //
3340 break;
3341 }
3342
3343 //
3344 // Get D or P.
3345 //
3346 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *)Pointer, &Pointer, &Uintn);
3347 if (RETURN_ERROR (Status)) {
3348 return RETURN_UNSUPPORTED;
3349 }
3350
3351 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3352 //
3353 // It's P.
3354 //
3355 if (Uintn > 32) {
3356 return RETURN_UNSUPPORTED;
3357 }
3358
3359 LocalPrefixLength = (UINT8)Uintn;
3360 } else {
3361 //
3362 // It's D.
3363 //
3364 if (Uintn > MAX_UINT8) {
3365 return RETURN_UNSUPPORTED;
3366 }
3367
3368 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
3369 AddressIndex++;
3370 }
3371
3372 //
3373 // Check the '.' or '/', depending on the AddressIndex.
3374 //
3375 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3376 if (*Pointer == '/') {
3377 //
3378 // '/P' is in the String.
3379 // Skip "/" and get P in next loop.
3380 //
3381 Pointer++;
3382 } else {
3383 //
3384 // '/P' is not in the String.
3385 //
3386 break;
3387 }
3388 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3389 if (*Pointer == '.') {
3390 //
3391 // D should be followed by '.'
3392 //
3393 Pointer++;
3394 } else {
3395 return RETURN_UNSUPPORTED;
3396 }
3397 }
3398 }
3399
3400 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3401 return RETURN_UNSUPPORTED;
3402 }
3403
3404 CopyMem (Address, &LocalAddress, sizeof (*Address));
3405 if (PrefixLength != NULL) {
3406 *PrefixLength = LocalPrefixLength;
3407 }
3408
3409 if (EndPointer != NULL) {
3410 *EndPointer = Pointer;
3411 }
3412
3413 return RETURN_SUCCESS;
3414}
3415
3456RETURN_STATUS
3457EFIAPI
3459 IN CONST CHAR8 *String,
3460 OUT GUID *Guid
3461 )
3462{
3463 RETURN_STATUS Status;
3464 GUID LocalGuid;
3465
3466 //
3467 // None of String or Guid shall be a null pointer.
3468 //
3469 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3470 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
3471
3472 //
3473 // Get aabbccdd in big-endian.
3474 //
3475 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
3476 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != '-')) {
3477 return RETURN_UNSUPPORTED;
3478 }
3479
3480 //
3481 // Convert big-endian to little-endian.
3482 //
3483 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
3484 String += 2 * sizeof (LocalGuid.Data1) + 1;
3485
3486 //
3487 // Get eeff in big-endian.
3488 //
3489 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
3490 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != '-')) {
3491 return RETURN_UNSUPPORTED;
3492 }
3493
3494 //
3495 // Convert big-endian to little-endian.
3496 //
3497 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
3498 String += 2 * sizeof (LocalGuid.Data2) + 1;
3499
3500 //
3501 // Get gghh in big-endian.
3502 //
3503 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
3504 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != '-')) {
3505 return RETURN_UNSUPPORTED;
3506 }
3507
3508 //
3509 // Convert big-endian to little-endian.
3510 //
3511 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
3512 String += 2 * sizeof (LocalGuid.Data3) + 1;
3513
3514 //
3515 // Get iijj.
3516 //
3517 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
3518 if (RETURN_ERROR (Status) || (String[2 * 2] != '-')) {
3519 return RETURN_UNSUPPORTED;
3520 }
3521
3522 String += 2 * 2 + 1;
3523
3524 //
3525 // Get kkllmmnnoopp.
3526 //
3527 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
3528 if (RETURN_ERROR (Status)) {
3529 return RETURN_UNSUPPORTED;
3530 }
3531
3532 CopyGuid (Guid, &LocalGuid);
3533 return RETURN_SUCCESS;
3534}
3535
3567RETURN_STATUS
3568EFIAPI
3570 IN CONST CHAR8 *String,
3571 IN UINTN Length,
3572 OUT UINT8 *Buffer,
3573 IN UINTN MaxBufferSize
3574 )
3575{
3576 UINTN Index;
3577
3578 //
3579 // 1. None of String or Buffer shall be a null pointer.
3580 //
3581 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3582 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
3583
3584 //
3585 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3586 //
3587 if (ASCII_RSIZE_MAX != 0) {
3588 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3589 }
3590
3591 //
3592 // 3. Length shall not be odd.
3593 //
3594 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
3595
3596 //
3597 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3598 //
3599 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
3600
3601 //
3602 // 5. String shall not contains invalid hexadecimal digits.
3603 //
3604 for (Index = 0; Index < Length; Index++) {
3605 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {
3606 break;
3607 }
3608 }
3609
3610 if (Index != Length) {
3611 return RETURN_UNSUPPORTED;
3612 }
3613
3614 //
3615 // Convert the hex string to bytes.
3616 //
3617 for (Index = 0; Index < Length; Index++) {
3618 //
3619 // For even characters, write the upper nibble for each buffer byte,
3620 // and for even characters, the lower nibble.
3621 //
3622 if ((Index & BIT0) == 0) {
3623 Buffer[Index / 2] = (UINT8)InternalAsciiHexCharToUintn (String[Index]) << 4;
3624 } else {
3625 Buffer[Index / 2] |= (UINT8)InternalAsciiHexCharToUintn (String[Index]);
3626 }
3627 }
3628
3629 return RETURN_SUCCESS;
3630}
UINT64 UINTN
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:750
BOOLEAN EFIAPI InternalAsciiIsDecimalDigitCharacter(IN CHAR8 Char)
Definition: String.c:590
BOOLEAN EFIAPI InternalIsDecimalDigitCharacter(IN CHAR16 Char)
Definition: String.c:283
BOOLEAN EFIAPI InternalAsciiIsHexaDecimalDigitCharacter(IN CHAR8 Char)
Definition: String.c:613
UINTN EFIAPI InternalAsciiHexCharToUintn(IN CHAR8 Char)
Definition: String.c:772
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 NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define MIN(a, b)
Definition: Base.h:1007
#define RETURN_ACCESS_DENIED
Definition: Base.h:1147
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define RETURN_BAD_BUFFER_SIZE
Definition: Base.h:1086
UINTN EFIAPI AsciiStrnLenS(IN CONST CHAR8 *String, IN UINTN MaxSize)
Definition: SafeString.c:1696
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:1875
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:2527
RETURN_STATUS EFIAPI AsciiStrCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1964
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:2650
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:2179
RETURN_STATUS EFIAPI AsciiStrHexToUintnS(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINTN *Data)
Definition: SafeString.c:2399
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:1129
RETURN_STATUS EFIAPI StrToIpv4Address(IN CONST CHAR16 *String, OUT CHAR16 **EndPointer OPTIONAL, OUT IPv4_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:1351
RETURN_STATUS EFIAPI AsciiStrDecimalToUint64S(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT UINT64 *Data)
Definition: SafeString.c:2287
RETURN_STATUS EFIAPI AsciiStrToGuid(IN CONST CHAR8 *String, OUT GUID *Guid)
Definition: SafeString.c:3458
RETURN_STATUS EFIAPI StrToGuid(IN CONST CHAR16 *String, OUT GUID *Guid)
Definition: SafeString.c:1500
RETURN_STATUS EFIAPI AsciiStrToIpv4Address(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT IPv4_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:3313
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:1749
RETURN_STATUS EFIAPI StrHexToBytes(IN CONST CHAR16 *String, IN UINTN Length, OUT UINT8 *Buffer, IN UINTN MaxBufferSize)
Definition: SafeString.c:1615
RETURN_STATUS EFIAPI AsciiStrToIpv6Address(IN CONST CHAR8 *String, OUT CHAR8 **EndPointer OPTIONAL, OUT IPv6_ADDRESS *Address, OUT UINT8 *PrefixLength OPTIONAL)
Definition: SafeString.c:3095
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:2873
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:994
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:3569
RETURN_STATUS EFIAPI AsciiStrnCatS(IN OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:2060
RETURN_STATUS EFIAPI AsciiStrnToUnicodeStrS(IN CONST CHAR8 *Source, IN UINTN Length, OUT CHAR16 *Destination, IN UINTN DestMax, OUT UINTN *DestinationLength)
Definition: SafeString.c:2972
RETURN_STATUS EFIAPI UnicodeStrnToAsciiStrS(IN CONST CHAR16 *Source, IN UINTN Length, OUT CHAR8 *Destination, IN UINTN DestMax, OUT UINTN *DestinationLength)
Definition: SafeString.c:2757
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
Definition: SafeString.c:1797
Definition: Base.h:213