]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/SafeString.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
1 /** @file
2 Safe String functions.
3
4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
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
25 /**
26 Returns if 2 memory blocks are overlapped.
27
28 @param Base1 Base address of 1st memory block.
29 @param Size1 Size of 1st memory block.
30 @param Base2 Base address of 2nd memory block.
31 @param Size2 Size of 2nd memory block.
32
33 @retval TRUE 2 memory blocks are overlapped.
34 @retval FALSE 2 memory blocks are not overlapped.
35 **/
36 BOOLEAN
37 InternalSafeStringIsOverlap (
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
53 /**
54 Returns if 2 Unicode strings are not overlapped.
55
56 @param Str1 Start address of 1st Unicode string.
57 @param Size1 The number of char in 1st Unicode string,
58 including terminating null char.
59 @param Str2 Start address of 2nd Unicode string.
60 @param Size2 The number of char in 2nd Unicode string,
61 including terminating null char.
62
63 @retval TRUE 2 Unicode strings are NOT overlapped.
64 @retval FALSE 2 Unicode strings are overlapped.
65 **/
66 BOOLEAN
67 InternalSafeStringNoStrOverlap (
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
77 /**
78 Returns if 2 Ascii strings are not overlapped.
79
80 @param Str1 Start address of 1st Ascii string.
81 @param Size1 The number of char in 1st Ascii string,
82 including terminating null char.
83 @param Str2 Start address of 2nd Ascii string.
84 @param Size2 The number of char in 2nd Ascii string,
85 including terminating null char.
86
87 @retval TRUE 2 Ascii strings are NOT overlapped.
88 @retval FALSE 2 Ascii strings are overlapped.
89 **/
90 BOOLEAN
91 InternalSafeStringNoAsciiStrOverlap (
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
101 /**
102 Returns the length of a Null-terminated Unicode string.
103
104 This function is similar as strlen_s defined in C11.
105
106 If String is not aligned on a 16-bit boundary, then ASSERT().
107
108 @param String A pointer to a Null-terminated Unicode string.
109 @param MaxSize The maximum number of Destination Unicode
110 char, including terminating null char.
111
112 @retval 0 If String is NULL.
113 @retval MaxSize If there is no null character in the first MaxSize characters of String.
114 @return The number of characters that percede the terminating null character.
115
116 **/
117 UINTN
118 EFIAPI
119 StrnLenS (
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
153 /**
154 Returns the size of a Null-terminated Unicode string in bytes, including the
155 Null terminator.
156
157 This function returns the size of the Null-terminated Unicode string
158 specified by String in bytes, including the Null terminator.
159
160 If String is not aligned on a 16-bit boundary, then ASSERT().
161
162 @param String A pointer to a Null-terminated Unicode string.
163 @param MaxSize The maximum number of Destination Unicode
164 char, including the Null terminator.
165
166 @retval 0 If String is NULL.
167 @retval (sizeof (CHAR16) * (MaxSize + 1))
168 If there is no Null terminator in the first MaxSize characters of
169 String.
170 @return The size of the Null-terminated Unicode string in bytes, including
171 the Null terminator.
172
173 **/
174 UINTN
175 EFIAPI
176 StrnSizeS (
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
198 /**
199 Copies the string pointed to by Source (including the terminating null char)
200 to the array pointed to by Destination.
201
202 This function is similar as strcpy_s defined in C11.
203
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().
205 If Source is not aligned on a 16-bit boundary, then ASSERT().
206
207 If an error is returned, then the Destination is unmodified.
208
209 @param Destination A pointer to a Null-terminated Unicode string.
210 @param DestMax The maximum number of Destination Unicode
211 char, including terminating null char.
212 @param Source A pointer to a Null-terminated Unicode string.
213
214 @retval RETURN_SUCCESS String is copied.
215 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
216 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
217 If Source is NULL.
218 If PcdMaximumUnicodeStringLength is not zero,
219 and DestMax is greater than
220 PcdMaximumUnicodeStringLength.
221 If DestMax is 0.
222 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
223 **/
224 RETURN_STATUS
225 EFIAPI
226 StrCpyS (
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
279 /**
280 Copies not more than Length successive char from the string pointed to by
281 Source to the array pointed to by Destination. If no null char is copied from
282 Source, then Destination[Length] is always set to null.
283
284 This function is similar as strncpy_s defined in C11.
285
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
288
289 If an error is returned, then the Destination is unmodified.
290
291 @param Destination A pointer to a Null-terminated Unicode string.
292 @param DestMax The maximum number of Destination Unicode
293 char, including terminating null char.
294 @param Source A pointer to a Null-terminated Unicode string.
295 @param Length The maximum number of Unicode characters to copy.
296
297 @retval RETURN_SUCCESS String is copied.
298 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
299 MIN(StrLen(Source), Length).
300 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
301 If Source is NULL.
302 If PcdMaximumUnicodeStringLength is not zero,
303 and DestMax is greater than
304 PcdMaximumUnicodeStringLength.
305 If DestMax is 0.
306 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
307 **/
308 RETURN_STATUS
309 EFIAPI
310 StrnCpyS (
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
374 /**
375 Appends a copy of the string pointed to by Source (including the terminating
376 null char) to the end of the string pointed to by Destination.
377
378 This function is similar as strcat_s defined in C11.
379
380 If Destination is not aligned on a 16-bit boundary, then ASSERT().
381 If Source is not aligned on a 16-bit boundary, then ASSERT().
382
383 If an error is returned, then the Destination is unmodified.
384
385 @param Destination A pointer to a Null-terminated Unicode string.
386 @param DestMax The maximum number of Destination Unicode
387 char, including terminating null char.
388 @param Source A pointer to a Null-terminated Unicode string.
389
390 @retval RETURN_SUCCESS String is appended.
391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
392 StrLen(Destination).
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
394 greater than StrLen(Source).
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
396 If Source is NULL.
397 If PcdMaximumUnicodeStringLength is not zero,
398 and DestMax is greater than
399 PcdMaximumUnicodeStringLength.
400 If DestMax is 0.
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
402 **/
403 RETURN_STATUS
404 EFIAPI
405 StrCatS (
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
473 /**
474 Appends not more than Length successive char from the string pointed to by
475 Source to the end of the string pointed to by Destination. If no null char is
476 copied from Source, then Destination[StrLen(Destination) + Length] is always
477 set to null.
478
479 This function is similar as strncat_s defined in C11.
480
481 If Destination is not aligned on a 16-bit boundary, then ASSERT().
482 If Source is not aligned on a 16-bit boundary, then ASSERT().
483
484 If an error is returned, then the Destination is unmodified.
485
486 @param Destination A pointer to a Null-terminated Unicode string.
487 @param DestMax The maximum number of Destination Unicode
488 char, including terminating null char.
489 @param Source A pointer to a Null-terminated Unicode string.
490 @param Length The maximum number of Unicode characters to copy.
491
492 @retval RETURN_SUCCESS String is appended.
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
494 StrLen(Destination).
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
496 greater than MIN(StrLen(Source), Length).
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
498 If Source is NULL.
499 If PcdMaximumUnicodeStringLength is not zero,
500 and DestMax is greater than
501 PcdMaximumUnicodeStringLength.
502 If DestMax is 0.
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
504 **/
505 RETURN_STATUS
506 EFIAPI
507 StrnCatS (
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
586 /**
587 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
588
589 This function outputs a value of type UINTN by interpreting the contents of
590 the Unicode string specified by String as a decimal number. The format of the
591 input Unicode string String is:
592
593 [spaces] [decimal digits].
594
595 The valid decimal digit character is in the range [0-9]. The function will
596 ignore the pad space, which includes spaces or tab characters, before
597 [decimal digits]. The running zero in the beginning of [decimal digits] will
598 be ignored. Then, the function stops at the first character that is a not a
599 valid decimal character or a Null-terminator, whichever one comes first.
600
601 If String is not aligned in a 16-bit boundary, then ASSERT().
602
603 If String has no valid decimal digits in the above format, then 0 is stored
604 at the location pointed to by Data.
605 If the number represented by String exceeds the range defined by UINTN, then
606 MAX_UINTN is stored at the location pointed to by Data.
607
608 If EndPointer is not NULL, a pointer to the character that stopped the scan
609 is stored at the location pointed to by EndPointer. If String has no valid
610 decimal digits right after the optional pad spaces, the value of String is
611 stored at the location pointed to by EndPointer.
612
613 @param String Pointer to a Null-terminated Unicode string.
614 @param EndPointer Pointer to character that stops scan.
615 @param Data Pointer to the converted value.
616
617 @retval RETURN_SUCCESS Value is translated from String.
618 @retval RETURN_INVALID_PARAMETER If String is NULL.
619 If Data is NULL.
620 If PcdMaximumUnicodeStringLength is not
621 zero, and String contains more than
622 PcdMaximumUnicodeStringLength Unicode
623 characters, not including the
624 Null-terminator.
625 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
626 the range defined by UINTN.
627
628 **/
629 RETURN_STATUS
630 EFIAPI
631 StrDecimalToUintnS (
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
698 /**
699 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
700
701 This function outputs a value of type UINT64 by interpreting the contents of
702 the Unicode string specified by String as a decimal number. The format of the
703 input Unicode string String is:
704
705 [spaces] [decimal digits].
706
707 The valid decimal digit character is in the range [0-9]. The function will
708 ignore the pad space, which includes spaces or tab characters, before
709 [decimal digits]. The running zero in the beginning of [decimal digits] will
710 be ignored. Then, the function stops at the first character that is a not a
711 valid decimal character or a Null-terminator, whichever one comes first.
712
713 If String is not aligned in a 16-bit boundary, then ASSERT().
714
715 If String has no valid decimal digits in the above format, then 0 is stored
716 at the location pointed to by Data.
717 If the number represented by String exceeds the range defined by UINT64, then
718 MAX_UINT64 is stored at the location pointed to by Data.
719
720 If EndPointer is not NULL, a pointer to the character that stopped the scan
721 is stored at the location pointed to by EndPointer. If String has no valid
722 decimal digits right after the optional pad spaces, the value of String is
723 stored at the location pointed to by EndPointer.
724
725 @param String Pointer to a Null-terminated Unicode string.
726 @param EndPointer Pointer to character that stops scan.
727 @param Data Pointer to the converted value.
728
729 @retval RETURN_SUCCESS Value is translated from String.
730 @retval RETURN_INVALID_PARAMETER If String is NULL.
731 If Data is NULL.
732 If PcdMaximumUnicodeStringLength is not
733 zero, and String contains more than
734 PcdMaximumUnicodeStringLength Unicode
735 characters, not including the
736 Null-terminator.
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
738 the range defined by UINT64.
739
740 **/
741 RETURN_STATUS
742 EFIAPI
743 StrDecimalToUint64S (
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
810 /**
811 Convert a Null-terminated Unicode hexadecimal string to a value of type
812 UINTN.
813
814 This function outputs a value of type UINTN by interpreting the contents of
815 the Unicode string specified by String as a hexadecimal number. The format of
816 the input Unicode string String is:
817
818 [spaces][zeros][x][hexadecimal digits].
819
820 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
821 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
822 If "x" appears in the input string, it must be prefixed with at least one 0.
823 The function will ignore the pad space, which includes spaces or tab
824 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
825 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
826 after [x] or the first valid hexadecimal digit. Then, the function stops at
827 the first character that is a not a valid hexadecimal character or NULL,
828 whichever one comes first.
829
830 If String is not aligned in a 16-bit boundary, then ASSERT().
831
832 If String has no valid hexadecimal digits in the above format, then 0 is
833 stored at the location pointed to by Data.
834 If the number represented by String exceeds the range defined by UINTN, then
835 MAX_UINTN is stored at the location pointed to by Data.
836
837 If EndPointer is not NULL, a pointer to the character that stopped the scan
838 is stored at the location pointed to by EndPointer. If String has no valid
839 hexadecimal digits right after the optional pad spaces, the value of String
840 is stored at the location pointed to by EndPointer.
841
842 @param String Pointer to a Null-terminated Unicode string.
843 @param EndPointer Pointer to character that stops scan.
844 @param Data Pointer to the converted value.
845
846 @retval RETURN_SUCCESS Value is translated from String.
847 @retval RETURN_INVALID_PARAMETER If String is NULL.
848 If Data is NULL.
849 If PcdMaximumUnicodeStringLength is not
850 zero, and String contains more than
851 PcdMaximumUnicodeStringLength Unicode
852 characters, not including the
853 Null-terminator.
854 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
855 the range defined by UINTN.
856
857 **/
858 RETURN_STATUS
859 EFIAPI
860 StrHexToUintnS (
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
944 /**
945 Convert a Null-terminated Unicode hexadecimal string to a value of type
946 UINT64.
947
948 This function outputs a value of type UINT64 by interpreting the contents of
949 the Unicode string specified by String as a hexadecimal number. The format of
950 the input Unicode string String is:
951
952 [spaces][zeros][x][hexadecimal digits].
953
954 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
955 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
956 If "x" appears in the input string, it must be prefixed with at least one 0.
957 The function will ignore the pad space, which includes spaces or tab
958 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
959 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
960 after [x] or the first valid hexadecimal digit. Then, the function stops at
961 the first character that is a not a valid hexadecimal character or NULL,
962 whichever one comes first.
963
964 If String is not aligned in a 16-bit boundary, then ASSERT().
965
966 If String has no valid hexadecimal digits in the above format, then 0 is
967 stored at the location pointed to by Data.
968 If the number represented by String exceeds the range defined by UINT64, then
969 MAX_UINT64 is stored at the location pointed to by Data.
970
971 If EndPointer is not NULL, a pointer to the character that stopped the scan
972 is stored at the location pointed to by EndPointer. If String has no valid
973 hexadecimal digits right after the optional pad spaces, the value of String
974 is stored at the location pointed to by EndPointer.
975
976 @param String Pointer to a Null-terminated Unicode string.
977 @param EndPointer Pointer to character that stops scan.
978 @param Data Pointer to the converted value.
979
980 @retval RETURN_SUCCESS Value is translated from String.
981 @retval RETURN_INVALID_PARAMETER If String is NULL.
982 If Data is NULL.
983 If PcdMaximumUnicodeStringLength is not
984 zero, and String contains more than
985 PcdMaximumUnicodeStringLength Unicode
986 characters, not including the
987 Null-terminator.
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
989 the range defined by UINT64.
990
991 **/
992 RETURN_STATUS
993 EFIAPI
994 StrHexToUint64S (
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
1077 /**
1078 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1079
1080 This function outputs a value of type IPv6_ADDRESS and may output a value
1081 of type UINT8 by interpreting the contents of the Unicode string specified
1082 by String. The format of the input Unicode string String is as follows:
1083
1084 X:X:X:X:X:X:X:X[/P]
1085
1086 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1087 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1088 memory address and high byte is stored in high memory address. P contains decimal
1089 digit characters in the range [0-9]. The running zero in the beginning of P will
1090 be ignored. /P is optional.
1091
1092 When /P is not in the String, the function stops at the first character that is
1093 not a valid hexadecimal digit character after eight X's are converted.
1094
1095 When /P is in the String, the function stops at the first character that is not
1096 a valid decimal digit character after P is converted.
1097
1098 "::" can be used to compress one or more groups of X when X contains only 0.
1099 The "::" can only appear once in the String.
1100
1101 If String is not aligned in a 16-bit boundary, then ASSERT().
1102
1103 If EndPointer is not NULL and Address is translated from String, a pointer
1104 to the character that stopped the scan is stored at the location pointed to
1105 by EndPointer.
1106
1107 @param String Pointer to a Null-terminated Unicode string.
1108 @param EndPointer Pointer to character that stops scan.
1109 @param Address Pointer to the converted IPv6 address.
1110 @param PrefixLength Pointer to the converted IPv6 address prefix
1111 length. MAX_UINT8 is returned when /P is
1112 not in the String.
1113
1114 @retval RETURN_SUCCESS Address is translated from String.
1115 @retval RETURN_INVALID_PARAMETER If String is NULL.
1116 If Data is NULL.
1117 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1118 digit characters.
1119 If String contains "::" and number of X
1120 is not less than 8.
1121 If P starts with character that is not a
1122 valid decimal digit character.
1123 If the decimal number converted from P
1124 exceeds 128.
1125
1126 **/
1127 RETURN_STATUS
1128 EFIAPI
1129 StrToIpv6Address (
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
1308 /**
1309 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1310
1311 This function outputs a value of type IPv4_ADDRESS and may output a value
1312 of type UINT8 by interpreting the contents of the Unicode string specified
1313 by String. The format of the input Unicode string String is as follows:
1314
1315 D.D.D.D[/P]
1316
1317 D and P are decimal digit characters in the range [0-9]. The running zero in
1318 the beginning of D and P will be ignored. /P is optional.
1319
1320 When /P is not in the String, the function stops at the first character that is
1321 not a valid decimal digit character after four D's are converted.
1322
1323 When /P is in the String, the function stops at the first character that is not
1324 a valid decimal digit character after P is converted.
1325
1326 If String is not aligned in a 16-bit boundary, then ASSERT().
1327
1328 If EndPointer is not NULL and Address is translated from String, a pointer
1329 to the character that stopped the scan is stored at the location pointed to
1330 by EndPointer.
1331
1332 @param String Pointer to a Null-terminated Unicode string.
1333 @param EndPointer Pointer to character that stops scan.
1334 @param Address Pointer to the converted IPv4 address.
1335 @param PrefixLength Pointer to the converted IPv4 address prefix
1336 length. MAX_UINT8 is returned when /P is
1337 not in the String.
1338
1339 @retval RETURN_SUCCESS Address is translated from String.
1340 @retval RETURN_INVALID_PARAMETER If String is NULL.
1341 If Data is NULL.
1342 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1343 If any decimal number converted from D
1344 exceeds 255.
1345 If the decimal number converted from P
1346 exceeds 32.
1347
1348 **/
1349 RETURN_STATUS
1350 EFIAPI
1351 StrToIpv4Address (
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
1456 /**
1457 Convert a Null-terminated Unicode GUID string to a value of type
1458 EFI_GUID.
1459
1460 This function outputs a GUID value by interpreting the contents of
1461 the Unicode string specified by String. The format of the input
1462 Unicode string String consists of 36 characters, as follows:
1463
1464 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1465
1466 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1467 [A-F], with each pair representing a single byte hexadecimal value.
1468
1469 The mapping between String and the EFI_GUID structure is as follows:
1470 aa Data1[24:31]
1471 bb Data1[16:23]
1472 cc Data1[8:15]
1473 dd Data1[0:7]
1474 ee Data2[8:15]
1475 ff Data2[0:7]
1476 gg Data3[8:15]
1477 hh Data3[0:7]
1478 ii Data4[0:7]
1479 jj Data4[8:15]
1480 kk Data4[16:23]
1481 ll Data4[24:31]
1482 mm Data4[32:39]
1483 nn Data4[40:47]
1484 oo Data4[48:55]
1485 pp Data4[56:63]
1486
1487 If String is not aligned in a 16-bit boundary, then ASSERT().
1488
1489 @param String Pointer to a Null-terminated Unicode string.
1490 @param Guid Pointer to the converted GUID.
1491
1492 @retval RETURN_SUCCESS Guid is translated from String.
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.
1494 If Data is NULL.
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.
1496
1497 **/
1498 RETURN_STATUS
1499 EFIAPI
1500 StrToGuid (
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
1580 /**
1581 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1582
1583 This function outputs a byte array by interpreting the contents of
1584 the Unicode string specified by String in hexadecimal format. The format of
1585 the input Unicode string String is:
1586
1587 [XX]*
1588
1589 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1590 The function decodes every two hexadecimal digit characters as one byte. The
1591 decoding stops after Length of characters and outputs Buffer containing
1592 (Length / 2) bytes.
1593
1594 If String is not aligned in a 16-bit boundary, then ASSERT().
1595
1596 @param String Pointer to a Null-terminated Unicode string.
1597 @param Length The number of Unicode characters to decode.
1598 @param Buffer Pointer to the converted bytes array.
1599 @param MaxBufferSize The maximum size of Buffer.
1600
1601 @retval RETURN_SUCCESS Buffer is translated from String.
1602 @retval RETURN_INVALID_PARAMETER If String is NULL.
1603 If Data is NULL.
1604 If Length is not multiple of 2.
1605 If PcdMaximumUnicodeStringLength is not zero,
1606 and Length is greater than
1607 PcdMaximumUnicodeStringLength.
1608 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1609 a character that is not valid hexadecimal
1610 digit characters, or a Null-terminator.
1611 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1612 **/
1613 RETURN_STATUS
1614 EFIAPI
1615 StrHexToBytes (
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
1680 /**
1681 Returns the length of a Null-terminated Ascii string.
1682
1683 This function is similar as strlen_s defined in C11.
1684
1685 @param String A pointer to a Null-terminated Ascii string.
1686 @param MaxSize The maximum number of Destination Ascii
1687 char, including terminating null char.
1688
1689 @retval 0 If String is NULL.
1690 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1691 @return The number of characters that percede the terminating null character.
1692
1693 **/
1694 UINTN
1695 EFIAPI
1696 AsciiStrnLenS (
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
1728 /**
1729 Returns the size of a Null-terminated Ascii string in bytes, including the
1730 Null terminator.
1731
1732 This function returns the size of the Null-terminated Ascii string specified
1733 by String in bytes, including the Null terminator.
1734
1735 @param String A pointer to a Null-terminated Ascii string.
1736 @param MaxSize The maximum number of Destination Ascii
1737 char, including the Null terminator.
1738
1739 @retval 0 If String is NULL.
1740 @retval (sizeof (CHAR8) * (MaxSize + 1))
1741 If there is no Null terminator in the first MaxSize characters of
1742 String.
1743 @return The size of the Null-terminated Ascii string in bytes, including the
1744 Null terminator.
1745
1746 **/
1747 UINTN
1748 EFIAPI
1749 AsciiStrnSizeS (
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
1772 /**
1773 Copies the string pointed to by Source (including the terminating null char)
1774 to the array pointed to by Destination.
1775
1776 This function is similar as strcpy_s defined in C11.
1777
1778 If an error is returned, then the Destination is unmodified.
1779
1780 @param Destination A pointer to a Null-terminated Ascii string.
1781 @param DestMax The maximum number of Destination Ascii
1782 char, including terminating null char.
1783 @param Source A pointer to a Null-terminated Ascii string.
1784
1785 @retval RETURN_SUCCESS String is copied.
1786 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1787 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1788 If Source is NULL.
1789 If PcdMaximumAsciiStringLength is not zero,
1790 and DestMax is greater than
1791 PcdMaximumAsciiStringLength.
1792 If DestMax is 0.
1793 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1794 **/
1795 RETURN_STATUS
1796 EFIAPI
1797 AsciiStrCpyS (
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
1847 /**
1848 Copies not more than Length successive char from the string pointed to by
1849 Source to the array pointed to by Destination. If no null char is copied from
1850 Source, then Destination[Length] is always set to null.
1851
1852 This function is similar as strncpy_s defined in C11.
1853
1854 If an error is returned, then the Destination is unmodified.
1855
1856 @param Destination A pointer to a Null-terminated Ascii string.
1857 @param DestMax The maximum number of Destination Ascii
1858 char, including terminating null char.
1859 @param Source A pointer to a Null-terminated Ascii string.
1860 @param Length The maximum number of Ascii characters to copy.
1861
1862 @retval RETURN_SUCCESS String is copied.
1863 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1864 MIN(StrLen(Source), Length).
1865 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1866 If Source is NULL.
1867 If PcdMaximumAsciiStringLength is not zero,
1868 and DestMax is greater than
1869 PcdMaximumAsciiStringLength.
1870 If DestMax is 0.
1871 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1872 **/
1873 RETURN_STATUS
1874 EFIAPI
1875 AsciiStrnCpyS (
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
1936 /**
1937 Appends a copy of the string pointed to by Source (including the terminating
1938 null char) to the end of the string pointed to by Destination.
1939
1940 This function is similar as strcat_s defined in C11.
1941
1942 If an error is returned, then the Destination is unmodified.
1943
1944 @param Destination A pointer to a Null-terminated Ascii string.
1945 @param DestMax The maximum number of Destination Ascii
1946 char, including terminating null char.
1947 @param Source A pointer to a Null-terminated Ascii string.
1948
1949 @retval RETURN_SUCCESS String is appended.
1950 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1951 StrLen(Destination).
1952 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1953 greater than StrLen(Source).
1954 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1955 If Source is NULL.
1956 If PcdMaximumAsciiStringLength is not zero,
1957 and DestMax is greater than
1958 PcdMaximumAsciiStringLength.
1959 If DestMax is 0.
1960 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1961 **/
1962 RETURN_STATUS
1963 EFIAPI
1964 AsciiStrCatS (
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
2029 /**
2030 Appends not more than Length successive char from the string pointed to by
2031 Source to the end of the string pointed to by Destination. If no null char is
2032 copied from Source, then Destination[StrLen(Destination) + Length] is always
2033 set to null.
2034
2035 This function is similar as strncat_s defined in C11.
2036
2037 If an error is returned, then the Destination is unmodified.
2038
2039 @param Destination A pointer to a Null-terminated Ascii string.
2040 @param DestMax The maximum number of Destination Ascii
2041 char, including terminating null char.
2042 @param Source A pointer to a Null-terminated Ascii string.
2043 @param Length The maximum number of Ascii characters to copy.
2044
2045 @retval RETURN_SUCCESS String is appended.
2046 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
2047 StrLen(Destination).
2048 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
2049 greater than MIN(StrLen(Source), Length).
2050 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2051 If Source is NULL.
2052 If PcdMaximumAsciiStringLength is not zero,
2053 and DestMax is greater than
2054 PcdMaximumAsciiStringLength.
2055 If DestMax is 0.
2056 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2057 **/
2058 RETURN_STATUS
2059 EFIAPI
2060 AsciiStrnCatS (
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
2136 /**
2137 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2138
2139 This function outputs a value of type UINTN by interpreting the contents of
2140 the Ascii string specified by String as a decimal number. The format of the
2141 input Ascii string String is:
2142
2143 [spaces] [decimal digits].
2144
2145 The valid decimal digit character is in the range [0-9]. The function will
2146 ignore the pad space, which includes spaces or tab characters, before
2147 [decimal digits]. The running zero in the beginning of [decimal digits] will
2148 be ignored. Then, the function stops at the first character that is a not a
2149 valid decimal character or a Null-terminator, whichever one comes first.
2150
2151 If String has no valid decimal digits in the above format, then 0 is stored
2152 at the location pointed to by Data.
2153 If the number represented by String exceeds the range defined by UINTN, then
2154 MAX_UINTN is stored at the location pointed to by Data.
2155
2156 If EndPointer is not NULL, a pointer to the character that stopped the scan
2157 is stored at the location pointed to by EndPointer. If String has no valid
2158 decimal digits right after the optional pad spaces, the value of String is
2159 stored at the location pointed to by EndPointer.
2160
2161 @param String Pointer to a Null-terminated Ascii string.
2162 @param EndPointer Pointer to character that stops scan.
2163 @param Data Pointer to the converted value.
2164
2165 @retval RETURN_SUCCESS Value is translated from String.
2166 @retval RETURN_INVALID_PARAMETER If String is NULL.
2167 If Data is NULL.
2168 If PcdMaximumAsciiStringLength is not zero,
2169 and String contains more than
2170 PcdMaximumAsciiStringLength Ascii
2171 characters, not including the
2172 Null-terminator.
2173 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2174 the range defined by UINTN.
2175
2176 **/
2177 RETURN_STATUS
2178 EFIAPI
2179 AsciiStrDecimalToUintnS (
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
2244 /**
2245 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2246
2247 This function outputs a value of type UINT64 by interpreting the contents of
2248 the Ascii string specified by String as a decimal number. The format of the
2249 input Ascii string String is:
2250
2251 [spaces] [decimal digits].
2252
2253 The valid decimal digit character is in the range [0-9]. The function will
2254 ignore the pad space, which includes spaces or tab characters, before
2255 [decimal digits]. The running zero in the beginning of [decimal digits] will
2256 be ignored. Then, the function stops at the first character that is a not a
2257 valid decimal character or a Null-terminator, whichever one comes first.
2258
2259 If String has no valid decimal digits in the above format, then 0 is stored
2260 at the location pointed to by Data.
2261 If the number represented by String exceeds the range defined by UINT64, then
2262 MAX_UINT64 is stored at the location pointed to by Data.
2263
2264 If EndPointer is not NULL, a pointer to the character that stopped the scan
2265 is stored at the location pointed to by EndPointer. If String has no valid
2266 decimal digits right after the optional pad spaces, the value of String is
2267 stored at the location pointed to by EndPointer.
2268
2269 @param String Pointer to a Null-terminated Ascii string.
2270 @param EndPointer Pointer to character that stops scan.
2271 @param Data Pointer to the converted value.
2272
2273 @retval RETURN_SUCCESS Value is translated from String.
2274 @retval RETURN_INVALID_PARAMETER If String is NULL.
2275 If Data is NULL.
2276 If PcdMaximumAsciiStringLength is not zero,
2277 and String contains more than
2278 PcdMaximumAsciiStringLength Ascii
2279 characters, not including the
2280 Null-terminator.
2281 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2282 the range defined by UINT64.
2283
2284 **/
2285 RETURN_STATUS
2286 EFIAPI
2287 AsciiStrDecimalToUint64S (
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
2352 /**
2353 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2354
2355 This function outputs a value of type UINTN by interpreting the contents of
2356 the Ascii string specified by String as a hexadecimal number. The format of
2357 the input Ascii string String is:
2358
2359 [spaces][zeros][x][hexadecimal digits].
2360
2361 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2362 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2363 "x" appears in the input string, it must be prefixed with at least one 0. The
2364 function will ignore the pad space, which includes spaces or tab characters,
2365 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2366 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2367 the first valid hexadecimal digit. Then, the function stops at the first
2368 character that is a not a valid hexadecimal character or Null-terminator,
2369 whichever on comes first.
2370
2371 If String has no valid hexadecimal digits in the above format, then 0 is
2372 stored at the location pointed to by Data.
2373 If the number represented by String exceeds the range defined by UINTN, then
2374 MAX_UINTN is stored at the location pointed to by Data.
2375
2376 If EndPointer is not NULL, a pointer to the character that stopped the scan
2377 is stored at the location pointed to by EndPointer. If String has no valid
2378 hexadecimal digits right after the optional pad spaces, the value of String
2379 is stored at the location pointed to by EndPointer.
2380
2381 @param String Pointer to a Null-terminated Ascii string.
2382 @param EndPointer Pointer to character that stops scan.
2383 @param Data Pointer to the converted value.
2384
2385 @retval RETURN_SUCCESS Value is translated from String.
2386 @retval RETURN_INVALID_PARAMETER If String is NULL.
2387 If Data is NULL.
2388 If PcdMaximumAsciiStringLength is not zero,
2389 and String contains more than
2390 PcdMaximumAsciiStringLength Ascii
2391 characters, not including the
2392 Null-terminator.
2393 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2394 the range defined by UINTN.
2395
2396 **/
2397 RETURN_STATUS
2398 EFIAPI
2399 AsciiStrHexToUintnS (
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
2454 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
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
2480 /**
2481 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2482
2483 This function outputs a value of type UINT64 by interpreting the contents of
2484 the Ascii string specified by String as a hexadecimal number. The format of
2485 the input Ascii string String is:
2486
2487 [spaces][zeros][x][hexadecimal digits].
2488
2489 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2490 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2491 "x" appears in the input string, it must be prefixed with at least one 0. The
2492 function will ignore the pad space, which includes spaces or tab characters,
2493 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2494 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2495 the first valid hexadecimal digit. Then, the function stops at the first
2496 character that is a not a valid hexadecimal character or Null-terminator,
2497 whichever on comes first.
2498
2499 If String has no valid hexadecimal digits in the above format, then 0 is
2500 stored at the location pointed to by Data.
2501 If the number represented by String exceeds the range defined by UINT64, then
2502 MAX_UINT64 is stored at the location pointed to by Data.
2503
2504 If EndPointer is not NULL, a pointer to the character that stopped the scan
2505 is stored at the location pointed to by EndPointer. If String has no valid
2506 hexadecimal digits right after the optional pad spaces, the value of String
2507 is stored at the location pointed to by EndPointer.
2508
2509 @param String Pointer to a Null-terminated Ascii string.
2510 @param EndPointer Pointer to character that stops scan.
2511 @param Data Pointer to the converted value.
2512
2513 @retval RETURN_SUCCESS Value is translated from String.
2514 @retval RETURN_INVALID_PARAMETER If String is NULL.
2515 If Data is NULL.
2516 If PcdMaximumAsciiStringLength is not zero,
2517 and String contains more than
2518 PcdMaximumAsciiStringLength Ascii
2519 characters, not including the
2520 Null-terminator.
2521 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2522 the range defined by UINT64.
2523
2524 **/
2525 RETURN_STATUS
2526 EFIAPI
2527 AsciiStrHexToUint64S (
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
2582 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
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
2608 /**
2609 Convert a Null-terminated Unicode string to a Null-terminated
2610 ASCII string.
2611
2612 This function is similar to AsciiStrCpyS.
2613
2614 This function converts the content of the Unicode string Source
2615 to the ASCII string Destination by copying the lower 8 bits of
2616 each Unicode character. The function terminates the ASCII string
2617 Destination by appending a Null-terminator character at the end.
2618
2619 The caller is responsible to make sure Destination points to a buffer with size
2620 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2621
2622 If any Unicode characters in Source contain non-zero value in
2623 the upper 8 bits, then ASSERT().
2624
2625 If Source is not aligned on a 16-bit boundary, then ASSERT().
2626
2627 If an error is returned, then the Destination is unmodified.
2628
2629 @param Source The pointer to a Null-terminated Unicode string.
2630 @param Destination The pointer to a Null-terminated ASCII string.
2631 @param DestMax The maximum number of Destination Ascii
2632 char, including terminating null char.
2633
2634 @retval RETURN_SUCCESS String is converted.
2635 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2636 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2637 If Source is NULL.
2638 If PcdMaximumAsciiStringLength is not zero,
2639 and DestMax is greater than
2640 PcdMaximumAsciiStringLength.
2641 If PcdMaximumUnicodeStringLength is not zero,
2642 and DestMax is greater than
2643 PcdMaximumUnicodeStringLength.
2644 If DestMax is 0.
2645 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2646
2647 **/
2648 RETURN_STATUS
2649 EFIAPI
2650 UnicodeStrToAsciiStrS (
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
2710 /**
2711 Convert not more than Length successive characters from a Null-terminated
2712 Unicode string to a Null-terminated Ascii string. If no null char is copied
2713 from Source, then Destination[Length] is always set to null.
2714
2715 This function converts not more than Length successive characters from the
2716 Unicode string Source to the Ascii string Destination by copying the lower 8
2717 bits of each Unicode character. The function terminates the Ascii string
2718 Destination by appending a Null-terminator character at the end.
2719
2720 The caller is responsible to make sure Destination points to a buffer with
2721 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2722 in bytes.
2723
2724 If any Unicode characters in Source contain non-zero value in the upper 8
2725 bits, then ASSERT().
2726 If Source is not aligned on a 16-bit boundary, then ASSERT().
2727
2728 If an error is returned, then Destination and DestinationLength are
2729 unmodified.
2730
2731 @param Source The pointer to a Null-terminated Unicode string.
2732 @param Length The maximum number of Unicode characters to
2733 convert.
2734 @param Destination The pointer to a Null-terminated Ascii string.
2735 @param DestMax The maximum number of Destination Ascii char,
2736 including terminating null char.
2737 @param DestinationLength The number of Unicode characters converted.
2738
2739 @retval RETURN_SUCCESS String is converted.
2740 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2741 If Source is NULL.
2742 If DestinationLength is NULL.
2743 If PcdMaximumAsciiStringLength is not zero,
2744 and Length or DestMax is greater than
2745 PcdMaximumAsciiStringLength.
2746 If PcdMaximumUnicodeStringLength is not
2747 zero, and Length or DestMax is greater than
2748 PcdMaximumUnicodeStringLength.
2749 If DestMax is 0.
2750 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2751 MIN(StrLen(Source), Length).
2752 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2753
2754 **/
2755 RETURN_STATUS
2756 EFIAPI
2757 UnicodeStrnToAsciiStrS (
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
2835 /**
2836 Convert one Null-terminated ASCII string to a Null-terminated
2837 Unicode string.
2838
2839 This function is similar to StrCpyS.
2840
2841 This function converts the contents of the ASCII string Source to the Unicode
2842 string Destination. The function terminates the Unicode string Destination by
2843 appending a Null-terminator character at the end.
2844
2845 The caller is responsible to make sure Destination points to a buffer with size
2846 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2847
2848 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2849
2850 If an error is returned, then the Destination is unmodified.
2851
2852 @param Source The pointer to a Null-terminated ASCII string.
2853 @param Destination The pointer to a Null-terminated Unicode string.
2854 @param DestMax The maximum number of Destination Unicode
2855 char, including terminating null char.
2856
2857 @retval RETURN_SUCCESS String is converted.
2858 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2859 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2860 If Source is NULL.
2861 If PcdMaximumUnicodeStringLength is not zero,
2862 and DestMax is greater than
2863 PcdMaximumUnicodeStringLength.
2864 If PcdMaximumAsciiStringLength is not zero,
2865 and DestMax is greater than
2866 PcdMaximumAsciiStringLength.
2867 If DestMax is 0.
2868 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2869
2870 **/
2871 RETURN_STATUS
2872 EFIAPI
2873 AsciiStrToUnicodeStrS (
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
2928 /**
2929 Convert not more than Length successive characters from a Null-terminated
2930 Ascii string to a Null-terminated Unicode string. If no null char is copied
2931 from Source, then Destination[Length] is always set to null.
2932
2933 This function converts not more than Length successive characters from the
2934 Ascii string Source to the Unicode string Destination. The function
2935 terminates the Unicode string Destination by appending a Null-terminator
2936 character at the end.
2937
2938 The caller is responsible to make sure Destination points to a buffer with
2939 size not smaller than
2940 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2941
2942 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2943
2944 If an error is returned, then Destination and DestinationLength are
2945 unmodified.
2946
2947 @param Source The pointer to a Null-terminated Ascii string.
2948 @param Length The maximum number of Ascii characters to convert.
2949 @param Destination The pointer to a Null-terminated Unicode string.
2950 @param DestMax The maximum number of Destination Unicode char,
2951 including terminating null char.
2952 @param DestinationLength The number of Ascii characters converted.
2953
2954 @retval RETURN_SUCCESS String is converted.
2955 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2956 If Source is NULL.
2957 If DestinationLength is NULL.
2958 If PcdMaximumUnicodeStringLength is not
2959 zero, and Length or DestMax is greater than
2960 PcdMaximumUnicodeStringLength.
2961 If PcdMaximumAsciiStringLength is not zero,
2962 and Length or DestMax is greater than
2963 PcdMaximumAsciiStringLength.
2964 If DestMax is 0.
2965 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2966 MIN(AsciiStrLen(Source), Length).
2967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2968
2969 **/
2970 RETURN_STATUS
2971 EFIAPI
2972 AsciiStrnToUnicodeStrS (
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
3045 /**
3046 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
3047
3048 This function outputs a value of type IPv6_ADDRESS and may output a value
3049 of type UINT8 by interpreting the contents of the ASCII string specified
3050 by String. The format of the input ASCII string String is as follows:
3051
3052 X:X:X:X:X:X:X:X[/P]
3053
3054 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
3055 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
3056 memory address and high byte is stored in high memory address. P contains decimal
3057 digit characters in the range [0-9]. The running zero in the beginning of P will
3058 be ignored. /P is optional.
3059
3060 When /P is not in the String, the function stops at the first character that is
3061 not a valid hexadecimal digit character after eight X's are converted.
3062
3063 When /P is in the String, the function stops at the first character that is not
3064 a valid decimal digit character after P is converted.
3065
3066 "::" can be used to compress one or more groups of X when X contains only 0.
3067 The "::" can only appear once in the String.
3068
3069 If EndPointer is not NULL and Address is translated from String, a pointer
3070 to the character that stopped the scan is stored at the location pointed to
3071 by EndPointer.
3072
3073 @param String Pointer to a Null-terminated ASCII string.
3074 @param EndPointer Pointer to character that stops scan.
3075 @param Address Pointer to the converted IPv6 address.
3076 @param PrefixLength Pointer to the converted IPv6 address prefix
3077 length. MAX_UINT8 is returned when /P is
3078 not in the String.
3079
3080 @retval RETURN_SUCCESS Address is translated from String.
3081 @retval RETURN_INVALID_PARAMETER If String is NULL.
3082 If Data is NULL.
3083 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3084 digit characters.
3085 If String contains "::" and number of X
3086 is not less than 8.
3087 If P starts with character that is not a
3088 valid decimal digit character.
3089 If the decimal number converted from P
3090 exceeds 128.
3091
3092 **/
3093 RETURN_STATUS
3094 EFIAPI
3095 AsciiStrToIpv6Address (
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;) {
3123 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
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
3168 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
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
3272 /**
3273 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3274
3275 This function outputs a value of type IPv4_ADDRESS and may output a value
3276 of type UINT8 by interpreting the contents of the ASCII string specified
3277 by String. The format of the input ASCII string String is as follows:
3278
3279 D.D.D.D[/P]
3280
3281 D and P are decimal digit characters in the range [0-9]. The running zero in
3282 the beginning of D and P will be ignored. /P is optional.
3283
3284 When /P is not in the String, the function stops at the first character that is
3285 not a valid decimal digit character after four D's are converted.
3286
3287 When /P is in the String, the function stops at the first character that is not
3288 a valid decimal digit character after P is converted.
3289
3290 If EndPointer is not NULL and Address is translated from String, a pointer
3291 to the character that stopped the scan is stored at the location pointed to
3292 by EndPointer.
3293
3294 @param String Pointer to a Null-terminated ASCII string.
3295 @param EndPointer Pointer to character that stops scan.
3296 @param Address Pointer to the converted IPv4 address.
3297 @param PrefixLength Pointer to the converted IPv4 address prefix
3298 length. MAX_UINT8 is returned when /P is
3299 not in the String.
3300
3301 @retval RETURN_SUCCESS Address is translated from String.
3302 @retval RETURN_INVALID_PARAMETER If String is NULL.
3303 If Data is NULL.
3304 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3305 If any decimal number converted from D
3306 exceeds 255.
3307 If the decimal number converted from P
3308 exceeds 32.
3309
3310 **/
3311 RETURN_STATUS
3312 EFIAPI
3313 AsciiStrToIpv4Address (
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
3416 /**
3417 Convert a Null-terminated ASCII GUID string to a value of type
3418 EFI_GUID.
3419
3420 This function outputs a GUID value by interpreting the contents of
3421 the ASCII string specified by String. The format of the input
3422 ASCII string String consists of 36 characters, as follows:
3423
3424 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3425
3426 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3427 [A-F], with each pair representing a single byte hexadecimal value.
3428
3429 The mapping between String and the EFI_GUID structure is as follows:
3430 aa Data1[24:31]
3431 bb Data1[16:23]
3432 cc Data1[8:15]
3433 dd Data1[0:7]
3434 ee Data2[8:15]
3435 ff Data2[0:7]
3436 gg Data3[8:15]
3437 hh Data3[0:7]
3438 ii Data4[0:7]
3439 jj Data4[8:15]
3440 kk Data4[16:23]
3441 ll Data4[24:31]
3442 mm Data4[32:39]
3443 nn Data4[40:47]
3444 oo Data4[48:55]
3445 pp Data4[56:63]
3446
3447 @param String Pointer to a Null-terminated ASCII string.
3448 @param Guid Pointer to the converted GUID.
3449
3450 @retval RETURN_SUCCESS Guid is translated from String.
3451 @retval RETURN_INVALID_PARAMETER If String is NULL.
3452 If Data is NULL.
3453 @retval RETURN_UNSUPPORTED If String is not as the above format.
3454
3455 **/
3456 RETURN_STATUS
3457 EFIAPI
3458 AsciiStrToGuid (
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
3536 /**
3537 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3538
3539 This function outputs a byte array by interpreting the contents of
3540 the ASCII string specified by String in hexadecimal format. The format of
3541 the input ASCII string String is:
3542
3543 [XX]*
3544
3545 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3546 The function decodes every two hexadecimal digit characters as one byte. The
3547 decoding stops after Length of characters and outputs Buffer containing
3548 (Length / 2) bytes.
3549
3550 @param String Pointer to a Null-terminated ASCII string.
3551 @param Length The number of ASCII characters to decode.
3552 @param Buffer Pointer to the converted bytes array.
3553 @param MaxBufferSize The maximum size of Buffer.
3554
3555 @retval RETURN_SUCCESS Buffer is translated from String.
3556 @retval RETURN_INVALID_PARAMETER If String is NULL.
3557 If Data is NULL.
3558 If Length is not multiple of 2.
3559 If PcdMaximumAsciiStringLength is not zero,
3560 and Length is greater than
3561 PcdMaximumAsciiStringLength.
3562 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3563 a character that is not valid hexadecimal
3564 digit characters, or a Null-terminator.
3565 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3566 **/
3567 RETURN_STATUS
3568 EFIAPI
3569 AsciiStrHexToBytes (
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 }