]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/SafeString.c
MdePkg: Apply uncrustify changes
[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 ASSERT (((UINTN)String & BIT0) == 0);
867
868 //
869 // 1. Neither String nor Data shall be a null pointer.
870 //
871 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
872 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
873
874 //
875 // 2. The length of String shall not be greater than RSIZE_MAX.
876 //
877 if (RSIZE_MAX != 0) {
878 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
879 }
880
881 if (EndPointer != NULL) {
882 *EndPointer = (CHAR16 *)String;
883 }
884
885 //
886 // Ignore the pad spaces (space or tab)
887 //
888 while ((*String == L' ') || (*String == L'\t')) {
889 String++;
890 }
891
892 //
893 // Ignore leading Zeros after the spaces
894 //
895 while (*String == L'0') {
896 String++;
897 }
898
899 if (CharToUpper (*String) == L'X') {
900 if (*(String - 1) != L'0') {
901 *Data = 0;
902 return RETURN_SUCCESS;
903 }
904
905 //
906 // Skip the 'X'
907 //
908 String++;
909 }
910
911 *Data = 0;
912
913 while (InternalIsHexaDecimalDigitCharacter (*String)) {
914 //
915 // If the number represented by String overflows according to the range
916 // defined by UINTN, then MAX_UINTN is stored in *Data and
917 // RETURN_UNSUPPORTED is returned.
918 //
919 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
920 *Data = MAX_UINTN;
921 if (EndPointer != NULL) {
922 *EndPointer = (CHAR16 *)String;
923 }
924
925 return RETURN_UNSUPPORTED;
926 }
927
928 *Data = (*Data << 4) + InternalHexCharToUintn (*String);
929 String++;
930 }
931
932 if (EndPointer != NULL) {
933 *EndPointer = (CHAR16 *)String;
934 }
935
936 return RETURN_SUCCESS;
937 }
938
939 /**
940 Convert a Null-terminated Unicode hexadecimal string to a value of type
941 UINT64.
942
943 This function outputs a value of type UINT64 by interpreting the contents of
944 the Unicode string specified by String as a hexadecimal number. The format of
945 the input Unicode string String is:
946
947 [spaces][zeros][x][hexadecimal digits].
948
949 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
950 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
951 If "x" appears in the input string, it must be prefixed with at least one 0.
952 The function will ignore the pad space, which includes spaces or tab
953 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
954 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
955 after [x] or the first valid hexadecimal digit. Then, the function stops at
956 the first character that is a not a valid hexadecimal character or NULL,
957 whichever one comes first.
958
959 If String is not aligned in a 16-bit boundary, then ASSERT().
960
961 If String has no valid hexadecimal digits in the above format, then 0 is
962 stored at the location pointed to by Data.
963 If the number represented by String exceeds the range defined by UINT64, then
964 MAX_UINT64 is stored at the location pointed to by Data.
965
966 If EndPointer is not NULL, a pointer to the character that stopped the scan
967 is stored at the location pointed to by EndPointer. If String has no valid
968 hexadecimal digits right after the optional pad spaces, the value of String
969 is stored at the location pointed to by EndPointer.
970
971 @param String Pointer to a Null-terminated Unicode string.
972 @param EndPointer Pointer to character that stops scan.
973 @param Data Pointer to the converted value.
974
975 @retval RETURN_SUCCESS Value is translated from String.
976 @retval RETURN_INVALID_PARAMETER If String is NULL.
977 If Data is NULL.
978 If PcdMaximumUnicodeStringLength is not
979 zero, and String contains more than
980 PcdMaximumUnicodeStringLength Unicode
981 characters, not including the
982 Null-terminator.
983 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
984 the range defined by UINT64.
985
986 **/
987 RETURN_STATUS
988 EFIAPI
989 StrHexToUint64S (
990 IN CONST CHAR16 *String,
991 OUT CHAR16 **EndPointer OPTIONAL,
992 OUT UINT64 *Data
993 )
994 {
995 ASSERT (((UINTN)String & BIT0) == 0);
996
997 //
998 // 1. Neither String nor Data shall be a null pointer.
999 //
1000 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1001 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1002
1003 //
1004 // 2. The length of String shall not be greater than RSIZE_MAX.
1005 //
1006 if (RSIZE_MAX != 0) {
1007 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1008 }
1009
1010 if (EndPointer != NULL) {
1011 *EndPointer = (CHAR16 *)String;
1012 }
1013
1014 //
1015 // Ignore the pad spaces (space or tab)
1016 //
1017 while ((*String == L' ') || (*String == L'\t')) {
1018 String++;
1019 }
1020
1021 //
1022 // Ignore leading Zeros after the spaces
1023 //
1024 while (*String == L'0') {
1025 String++;
1026 }
1027
1028 if (CharToUpper (*String) == L'X') {
1029 if (*(String - 1) != L'0') {
1030 *Data = 0;
1031 return RETURN_SUCCESS;
1032 }
1033
1034 //
1035 // Skip the 'X'
1036 //
1037 String++;
1038 }
1039
1040 *Data = 0;
1041
1042 while (InternalIsHexaDecimalDigitCharacter (*String)) {
1043 //
1044 // If the number represented by String overflows according to the range
1045 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1046 // RETURN_UNSUPPORTED is returned.
1047 //
1048 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {
1049 *Data = MAX_UINT64;
1050 if (EndPointer != NULL) {
1051 *EndPointer = (CHAR16 *)String;
1052 }
1053
1054 return RETURN_UNSUPPORTED;
1055 }
1056
1057 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);
1058 String++;
1059 }
1060
1061 if (EndPointer != NULL) {
1062 *EndPointer = (CHAR16 *)String;
1063 }
1064
1065 return RETURN_SUCCESS;
1066 }
1067
1068 /**
1069 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1070
1071 This function outputs a value of type IPv6_ADDRESS and may output a value
1072 of type UINT8 by interpreting the contents of the Unicode string specified
1073 by String. The format of the input Unicode string String is as follows:
1074
1075 X:X:X:X:X:X:X:X[/P]
1076
1077 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1078 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1079 memory address and high byte is stored in high memory address. P contains decimal
1080 digit characters in the range [0-9]. The running zero in the beginning of P will
1081 be ignored. /P is optional.
1082
1083 When /P is not in the String, the function stops at the first character that is
1084 not a valid hexadecimal digit character after eight X's are converted.
1085
1086 When /P is in the String, the function stops at the first character that is not
1087 a valid decimal digit character after P is converted.
1088
1089 "::" can be used to compress one or more groups of X when X contains only 0.
1090 The "::" can only appear once in the String.
1091
1092 If String is not aligned in a 16-bit boundary, then ASSERT().
1093
1094 If EndPointer is not NULL and Address is translated from String, a pointer
1095 to the character that stopped the scan is stored at the location pointed to
1096 by EndPointer.
1097
1098 @param String Pointer to a Null-terminated Unicode string.
1099 @param EndPointer Pointer to character that stops scan.
1100 @param Address Pointer to the converted IPv6 address.
1101 @param PrefixLength Pointer to the converted IPv6 address prefix
1102 length. MAX_UINT8 is returned when /P is
1103 not in the String.
1104
1105 @retval RETURN_SUCCESS Address is translated from String.
1106 @retval RETURN_INVALID_PARAMETER If String is NULL.
1107 If Data is NULL.
1108 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1109 digit characters.
1110 If String contains "::" and number of X
1111 is not less than 8.
1112 If P starts with character that is not a
1113 valid decimal digit character.
1114 If the decimal number converted from P
1115 exceeds 128.
1116
1117 **/
1118 RETURN_STATUS
1119 EFIAPI
1120 StrToIpv6Address (
1121 IN CONST CHAR16 *String,
1122 OUT CHAR16 **EndPointer OPTIONAL,
1123 OUT IPv6_ADDRESS *Address,
1124 OUT UINT8 *PrefixLength OPTIONAL
1125 )
1126 {
1127 RETURN_STATUS Status;
1128 UINTN AddressIndex;
1129 UINTN Uintn;
1130 IPv6_ADDRESS LocalAddress;
1131 UINT8 LocalPrefixLength;
1132 CONST CHAR16 *Pointer;
1133 CHAR16 *End;
1134 UINTN CompressStart;
1135 BOOLEAN ExpectPrefix;
1136
1137 LocalPrefixLength = MAX_UINT8;
1138 CompressStart = ARRAY_SIZE (Address->Addr);
1139 ExpectPrefix = FALSE;
1140
1141 ASSERT (((UINTN)String & BIT0) == 0);
1142
1143 //
1144 // 1. None of String or Guid shall be a null pointer.
1145 //
1146 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1147 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1148
1149 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1150 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1151 if (*Pointer != L':') {
1152 //
1153 // ":" or "/" should be followed by digit characters.
1154 //
1155 return RETURN_UNSUPPORTED;
1156 }
1157
1158 //
1159 // Meet second ":" after previous ":" or "/"
1160 // or meet first ":" in the beginning of String.
1161 //
1162 if (ExpectPrefix) {
1163 //
1164 // ":" shall not be after "/"
1165 //
1166 return RETURN_UNSUPPORTED;
1167 }
1168
1169 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
1170 //
1171 // "::" can only appear once.
1172 // "::" can only appear when address is not full length.
1173 //
1174 return RETURN_UNSUPPORTED;
1175 } else {
1176 //
1177 // Remember the start of zero compressing.
1178 //
1179 CompressStart = AddressIndex;
1180 Pointer++;
1181
1182 if (CompressStart == 0) {
1183 if (*Pointer != L':') {
1184 //
1185 // Single ":" shall not be in the beginning of String.
1186 //
1187 return RETURN_UNSUPPORTED;
1188 }
1189
1190 Pointer++;
1191 }
1192 }
1193 }
1194
1195 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1196 if (*Pointer == L'/') {
1197 //
1198 // Might be optional "/P" after "::".
1199 //
1200 if (CompressStart != AddressIndex) {
1201 return RETURN_UNSUPPORTED;
1202 }
1203 } else {
1204 break;
1205 }
1206 } else {
1207 if (!ExpectPrefix) {
1208 //
1209 // Get X.
1210 //
1211 Status = StrHexToUintnS (Pointer, &End, &Uintn);
1212 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
1213 //
1214 // Number of hexadecimal digit characters is no more than 4.
1215 //
1216 return RETURN_UNSUPPORTED;
1217 }
1218
1219 Pointer = End;
1220 //
1221 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1222 //
1223 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
1224 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
1225 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
1226 AddressIndex += 2;
1227 } else {
1228 //
1229 // Get P, then exit the loop.
1230 //
1231 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
1232 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
1233 //
1234 // Prefix length should not exceed 128.
1235 //
1236 return RETURN_UNSUPPORTED;
1237 }
1238
1239 LocalPrefixLength = (UINT8)Uintn;
1240 Pointer = End;
1241 break;
1242 }
1243 }
1244
1245 //
1246 // Skip ':' or "/"
1247 //
1248 if (*Pointer == L'/') {
1249 ExpectPrefix = TRUE;
1250 } else if (*Pointer == L':') {
1251 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1252 //
1253 // Meet additional ":" after all 8 16-bit address
1254 //
1255 break;
1256 }
1257 } else {
1258 //
1259 // Meet other character that is not "/" or ":" after all 8 16-bit address
1260 //
1261 break;
1262 }
1263
1264 Pointer++;
1265 }
1266
1267 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
1268 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
1269 )
1270 {
1271 //
1272 // Full length of address shall not have compressing zeros.
1273 // Non-full length of address shall have compressing zeros.
1274 //
1275 return RETURN_UNSUPPORTED;
1276 }
1277
1278 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
1279 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
1280 if (AddressIndex > CompressStart) {
1281 CopyMem (
1282 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
1283 &LocalAddress.Addr[CompressStart],
1284 AddressIndex - CompressStart
1285 );
1286 }
1287
1288 if (PrefixLength != NULL) {
1289 *PrefixLength = LocalPrefixLength;
1290 }
1291
1292 if (EndPointer != NULL) {
1293 *EndPointer = (CHAR16 *)Pointer;
1294 }
1295
1296 return RETURN_SUCCESS;
1297 }
1298
1299 /**
1300 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1301
1302 This function outputs a value of type IPv4_ADDRESS and may output a value
1303 of type UINT8 by interpreting the contents of the Unicode string specified
1304 by String. The format of the input Unicode string String is as follows:
1305
1306 D.D.D.D[/P]
1307
1308 D and P are decimal digit characters in the range [0-9]. The running zero in
1309 the beginning of D and P will be ignored. /P is optional.
1310
1311 When /P is not in the String, the function stops at the first character that is
1312 not a valid decimal digit character after four D's are converted.
1313
1314 When /P is in the String, the function stops at the first character that is not
1315 a valid decimal digit character after P is converted.
1316
1317 If String is not aligned in a 16-bit boundary, then ASSERT().
1318
1319 If EndPointer is not NULL and Address is translated from String, a pointer
1320 to the character that stopped the scan is stored at the location pointed to
1321 by EndPointer.
1322
1323 @param String Pointer to a Null-terminated Unicode string.
1324 @param EndPointer Pointer to character that stops scan.
1325 @param Address Pointer to the converted IPv4 address.
1326 @param PrefixLength Pointer to the converted IPv4 address prefix
1327 length. MAX_UINT8 is returned when /P is
1328 not in the String.
1329
1330 @retval RETURN_SUCCESS Address is translated from String.
1331 @retval RETURN_INVALID_PARAMETER If String is NULL.
1332 If Data is NULL.
1333 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1334 If any decimal number converted from D
1335 exceeds 255.
1336 If the decimal number converted from P
1337 exceeds 32.
1338
1339 **/
1340 RETURN_STATUS
1341 EFIAPI
1342 StrToIpv4Address (
1343 IN CONST CHAR16 *String,
1344 OUT CHAR16 **EndPointer OPTIONAL,
1345 OUT IPv4_ADDRESS *Address,
1346 OUT UINT8 *PrefixLength OPTIONAL
1347 )
1348 {
1349 RETURN_STATUS Status;
1350 UINTN AddressIndex;
1351 UINTN Uintn;
1352 IPv4_ADDRESS LocalAddress;
1353 UINT8 LocalPrefixLength;
1354 CHAR16 *Pointer;
1355
1356 LocalPrefixLength = MAX_UINT8;
1357
1358 ASSERT (((UINTN)String & BIT0) == 0);
1359
1360 //
1361 // 1. None of String or Guid shall be a null pointer.
1362 //
1363 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1364 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1365
1366 for (Pointer = (CHAR16 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1367 if (!InternalIsDecimalDigitCharacter (*Pointer)) {
1368 //
1369 // D or P contains invalid characters.
1370 //
1371 break;
1372 }
1373
1374 //
1375 // Get D or P.
1376 //
1377 Status = StrDecimalToUintnS ((CONST CHAR16 *)Pointer, &Pointer, &Uintn);
1378 if (RETURN_ERROR (Status)) {
1379 return RETURN_UNSUPPORTED;
1380 }
1381
1382 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1383 //
1384 // It's P.
1385 //
1386 if (Uintn > 32) {
1387 return RETURN_UNSUPPORTED;
1388 }
1389
1390 LocalPrefixLength = (UINT8)Uintn;
1391 } else {
1392 //
1393 // It's D.
1394 //
1395 if (Uintn > MAX_UINT8) {
1396 return RETURN_UNSUPPORTED;
1397 }
1398
1399 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
1400 AddressIndex++;
1401 }
1402
1403 //
1404 // Check the '.' or '/', depending on the AddressIndex.
1405 //
1406 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1407 if (*Pointer == L'/') {
1408 //
1409 // '/P' is in the String.
1410 // Skip "/" and get P in next loop.
1411 //
1412 Pointer++;
1413 } else {
1414 //
1415 // '/P' is not in the String.
1416 //
1417 break;
1418 }
1419 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1420 if (*Pointer == L'.') {
1421 //
1422 // D should be followed by '.'
1423 //
1424 Pointer++;
1425 } else {
1426 return RETURN_UNSUPPORTED;
1427 }
1428 }
1429 }
1430
1431 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1432 return RETURN_UNSUPPORTED;
1433 }
1434
1435 CopyMem (Address, &LocalAddress, sizeof (*Address));
1436 if (PrefixLength != NULL) {
1437 *PrefixLength = LocalPrefixLength;
1438 }
1439
1440 if (EndPointer != NULL) {
1441 *EndPointer = Pointer;
1442 }
1443
1444 return RETURN_SUCCESS;
1445 }
1446
1447 /**
1448 Convert a Null-terminated Unicode GUID string to a value of type
1449 EFI_GUID.
1450
1451 This function outputs a GUID value by interpreting the contents of
1452 the Unicode string specified by String. The format of the input
1453 Unicode string String consists of 36 characters, as follows:
1454
1455 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1456
1457 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1458 [A-F], with each pair representing a single byte hexadecimal value.
1459
1460 The mapping between String and the EFI_GUID structure is as follows:
1461 aa Data1[24:31]
1462 bb Data1[16:23]
1463 cc Data1[8:15]
1464 dd Data1[0:7]
1465 ee Data2[8:15]
1466 ff Data2[0:7]
1467 gg Data3[8:15]
1468 hh Data3[0:7]
1469 ii Data4[0:7]
1470 jj Data4[8:15]
1471 kk Data4[16:23]
1472 ll Data4[24:31]
1473 mm Data4[32:39]
1474 nn Data4[40:47]
1475 oo Data4[48:55]
1476 pp Data4[56:63]
1477
1478 If String is not aligned in a 16-bit boundary, then ASSERT().
1479
1480 @param String Pointer to a Null-terminated Unicode string.
1481 @param Guid Pointer to the converted GUID.
1482
1483 @retval RETURN_SUCCESS Guid is translated from String.
1484 @retval RETURN_INVALID_PARAMETER If String is NULL.
1485 If Data is NULL.
1486 @retval RETURN_UNSUPPORTED If String is not as the above format.
1487
1488 **/
1489 RETURN_STATUS
1490 EFIAPI
1491 StrToGuid (
1492 IN CONST CHAR16 *String,
1493 OUT GUID *Guid
1494 )
1495 {
1496 RETURN_STATUS Status;
1497 GUID LocalGuid;
1498
1499 ASSERT (((UINTN)String & BIT0) == 0);
1500
1501 //
1502 // 1. None of String or Guid shall be a null pointer.
1503 //
1504 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1505 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
1506
1507 //
1508 // Get aabbccdd in big-endian.
1509 //
1510 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
1511 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != L'-')) {
1512 return RETURN_UNSUPPORTED;
1513 }
1514
1515 //
1516 // Convert big-endian to little-endian.
1517 //
1518 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
1519 String += 2 * sizeof (LocalGuid.Data1) + 1;
1520
1521 //
1522 // Get eeff in big-endian.
1523 //
1524 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
1525 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != L'-')) {
1526 return RETURN_UNSUPPORTED;
1527 }
1528
1529 //
1530 // Convert big-endian to little-endian.
1531 //
1532 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
1533 String += 2 * sizeof (LocalGuid.Data2) + 1;
1534
1535 //
1536 // Get gghh in big-endian.
1537 //
1538 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
1539 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != L'-')) {
1540 return RETURN_UNSUPPORTED;
1541 }
1542
1543 //
1544 // Convert big-endian to little-endian.
1545 //
1546 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
1547 String += 2 * sizeof (LocalGuid.Data3) + 1;
1548
1549 //
1550 // Get iijj.
1551 //
1552 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
1553 if (RETURN_ERROR (Status) || (String[2 * 2] != L'-')) {
1554 return RETURN_UNSUPPORTED;
1555 }
1556
1557 String += 2 * 2 + 1;
1558
1559 //
1560 // Get kkllmmnnoopp.
1561 //
1562 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
1563 if (RETURN_ERROR (Status)) {
1564 return RETURN_UNSUPPORTED;
1565 }
1566
1567 CopyGuid (Guid, &LocalGuid);
1568 return RETURN_SUCCESS;
1569 }
1570
1571 /**
1572 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1573
1574 This function outputs a byte array by interpreting the contents of
1575 the Unicode string specified by String in hexadecimal format. The format of
1576 the input Unicode string String is:
1577
1578 [XX]*
1579
1580 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1581 The function decodes every two hexadecimal digit characters as one byte. The
1582 decoding stops after Length of characters and outputs Buffer containing
1583 (Length / 2) bytes.
1584
1585 If String is not aligned in a 16-bit boundary, then ASSERT().
1586
1587 @param String Pointer to a Null-terminated Unicode string.
1588 @param Length The number of Unicode characters to decode.
1589 @param Buffer Pointer to the converted bytes array.
1590 @param MaxBufferSize The maximum size of Buffer.
1591
1592 @retval RETURN_SUCCESS Buffer is translated from String.
1593 @retval RETURN_INVALID_PARAMETER If String is NULL.
1594 If Data is NULL.
1595 If Length is not multiple of 2.
1596 If PcdMaximumUnicodeStringLength is not zero,
1597 and Length is greater than
1598 PcdMaximumUnicodeStringLength.
1599 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1600 a character that is not valid hexadecimal
1601 digit characters, or a Null-terminator.
1602 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1603 **/
1604 RETURN_STATUS
1605 EFIAPI
1606 StrHexToBytes (
1607 IN CONST CHAR16 *String,
1608 IN UINTN Length,
1609 OUT UINT8 *Buffer,
1610 IN UINTN MaxBufferSize
1611 )
1612 {
1613 UINTN Index;
1614
1615 ASSERT (((UINTN)String & BIT0) == 0);
1616
1617 //
1618 // 1. None of String or Buffer shall be a null pointer.
1619 //
1620 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1621 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
1622
1623 //
1624 // 2. Length shall not be greater than RSIZE_MAX.
1625 //
1626 if (RSIZE_MAX != 0) {
1627 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1628 }
1629
1630 //
1631 // 3. Length shall not be odd.
1632 //
1633 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
1634
1635 //
1636 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1637 //
1638 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
1639
1640 //
1641 // 5. String shall not contains invalid hexadecimal digits.
1642 //
1643 for (Index = 0; Index < Length; Index++) {
1644 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
1645 break;
1646 }
1647 }
1648
1649 if (Index != Length) {
1650 return RETURN_UNSUPPORTED;
1651 }
1652
1653 //
1654 // Convert the hex string to bytes.
1655 //
1656 for (Index = 0; Index < Length; Index++) {
1657 //
1658 // For even characters, write the upper nibble for each buffer byte,
1659 // and for even characters, the lower nibble.
1660 //
1661 if ((Index & BIT0) == 0) {
1662 Buffer[Index / 2] = (UINT8)InternalHexCharToUintn (String[Index]) << 4;
1663 } else {
1664 Buffer[Index / 2] |= (UINT8)InternalHexCharToUintn (String[Index]);
1665 }
1666 }
1667
1668 return RETURN_SUCCESS;
1669 }
1670
1671 /**
1672 Returns the length of a Null-terminated Ascii string.
1673
1674 This function is similar as strlen_s defined in C11.
1675
1676 @param String A pointer to a Null-terminated Ascii string.
1677 @param MaxSize The maximum number of Destination Ascii
1678 char, including terminating null char.
1679
1680 @retval 0 If String is NULL.
1681 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1682 @return The number of characters that percede the terminating null character.
1683
1684 **/
1685 UINTN
1686 EFIAPI
1687 AsciiStrnLenS (
1688 IN CONST CHAR8 *String,
1689 IN UINTN MaxSize
1690 )
1691 {
1692 UINTN Length;
1693
1694 //
1695 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1696 //
1697 if ((String == NULL) || (MaxSize == 0)) {
1698 return 0;
1699 }
1700
1701 //
1702 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1703 // terminating null character. If there is no null character in the first MaxSize characters of
1704 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1705 // be accessed by AsciiStrnLenS.
1706 //
1707 Length = 0;
1708 while (String[Length] != 0) {
1709 if (Length >= MaxSize - 1) {
1710 return MaxSize;
1711 }
1712
1713 Length++;
1714 }
1715
1716 return Length;
1717 }
1718
1719 /**
1720 Returns the size of a Null-terminated Ascii string in bytes, including the
1721 Null terminator.
1722
1723 This function returns the size of the Null-terminated Ascii string specified
1724 by String in bytes, including the Null terminator.
1725
1726 @param String A pointer to a Null-terminated Ascii string.
1727 @param MaxSize The maximum number of Destination Ascii
1728 char, including the Null terminator.
1729
1730 @retval 0 If String is NULL.
1731 @retval (sizeof (CHAR8) * (MaxSize + 1))
1732 If there is no Null terminator in the first MaxSize characters of
1733 String.
1734 @return The size of the Null-terminated Ascii string in bytes, including the
1735 Null terminator.
1736
1737 **/
1738 UINTN
1739 EFIAPI
1740 AsciiStrnSizeS (
1741 IN CONST CHAR8 *String,
1742 IN UINTN MaxSize
1743 )
1744 {
1745 //
1746 // If String is a null pointer, then the AsciiStrnSizeS function returns
1747 // zero.
1748 //
1749 if (String == NULL) {
1750 return 0;
1751 }
1752
1753 //
1754 // Otherwise, the AsciiStrnSizeS function returns the size of the
1755 // Null-terminated Ascii string in bytes, including the Null terminator. If
1756 // there is no Null terminator in the first MaxSize characters of String,
1757 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1758 // consistent map with the AsciiStrnLenS function.
1759 //
1760 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
1761 }
1762
1763 /**
1764 Copies the string pointed to by Source (including the terminating null char)
1765 to the array pointed to by Destination.
1766
1767 This function is similar as strcpy_s defined in C11.
1768
1769 If an error is returned, then the Destination is unmodified.
1770
1771 @param Destination A pointer to a Null-terminated Ascii string.
1772 @param DestMax The maximum number of Destination Ascii
1773 char, including terminating null char.
1774 @param Source A pointer to a Null-terminated Ascii string.
1775
1776 @retval RETURN_SUCCESS String is copied.
1777 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1778 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1779 If Source is NULL.
1780 If PcdMaximumAsciiStringLength is not zero,
1781 and DestMax is greater than
1782 PcdMaximumAsciiStringLength.
1783 If DestMax is 0.
1784 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1785 **/
1786 RETURN_STATUS
1787 EFIAPI
1788 AsciiStrCpyS (
1789 OUT CHAR8 *Destination,
1790 IN UINTN DestMax,
1791 IN CONST CHAR8 *Source
1792 )
1793 {
1794 UINTN SourceLen;
1795
1796 //
1797 // 1. Neither Destination nor Source shall be a null pointer.
1798 //
1799 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1800 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1801
1802 //
1803 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1804 //
1805 if (ASCII_RSIZE_MAX != 0) {
1806 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1807 }
1808
1809 //
1810 // 3. DestMax shall not equal zero.
1811 //
1812 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1813
1814 //
1815 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1816 //
1817 SourceLen = AsciiStrnLenS (Source, DestMax);
1818 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1819
1820 //
1821 // 5. Copying shall not take place between objects that overlap.
1822 //
1823 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1824
1825 //
1826 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1827 // null character) into the array pointed to by Destination.
1828 //
1829 while (*Source != 0) {
1830 *(Destination++) = *(Source++);
1831 }
1832
1833 *Destination = 0;
1834
1835 return RETURN_SUCCESS;
1836 }
1837
1838 /**
1839 Copies not more than Length successive char from the string pointed to by
1840 Source to the array pointed to by Destination. If no null char is copied from
1841 Source, then Destination[Length] is always set to null.
1842
1843 This function is similar as strncpy_s defined in C11.
1844
1845 If an error is returned, then the Destination is unmodified.
1846
1847 @param Destination A pointer to a Null-terminated Ascii string.
1848 @param DestMax The maximum number of Destination Ascii
1849 char, including terminating null char.
1850 @param Source A pointer to a Null-terminated Ascii string.
1851 @param Length The maximum number of Ascii characters to copy.
1852
1853 @retval RETURN_SUCCESS String is copied.
1854 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1855 MIN(StrLen(Source), Length).
1856 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1857 If Source is NULL.
1858 If PcdMaximumAsciiStringLength is not zero,
1859 and DestMax is greater than
1860 PcdMaximumAsciiStringLength.
1861 If DestMax is 0.
1862 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1863 **/
1864 RETURN_STATUS
1865 EFIAPI
1866 AsciiStrnCpyS (
1867 OUT CHAR8 *Destination,
1868 IN UINTN DestMax,
1869 IN CONST CHAR8 *Source,
1870 IN UINTN Length
1871 )
1872 {
1873 UINTN SourceLen;
1874
1875 //
1876 // 1. Neither Destination nor Source shall be a null pointer.
1877 //
1878 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1879 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1880
1881 //
1882 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1883 //
1884 if (ASCII_RSIZE_MAX != 0) {
1885 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1886 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1887 }
1888
1889 //
1890 // 3. DestMax shall not equal zero.
1891 //
1892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1893
1894 //
1895 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1896 //
1897 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));
1898 if (Length >= DestMax) {
1899 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1900 }
1901
1902 //
1903 // 5. Copying shall not take place between objects that overlap.
1904 //
1905 if (SourceLen > Length) {
1906 SourceLen = Length;
1907 }
1908
1909 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1910
1911 //
1912 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1913 // follow a null character are not copied) from the array pointed to by Source to the array
1914 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1915 // character.
1916 //
1917 while ((SourceLen > 0) && (*Source != 0)) {
1918 *(Destination++) = *(Source++);
1919 SourceLen--;
1920 }
1921
1922 *Destination = 0;
1923
1924 return RETURN_SUCCESS;
1925 }
1926
1927 /**
1928 Appends a copy of the string pointed to by Source (including the terminating
1929 null char) to the end of the string pointed to by Destination.
1930
1931 This function is similar as strcat_s defined in C11.
1932
1933 If an error is returned, then the Destination is unmodified.
1934
1935 @param Destination A pointer to a Null-terminated Ascii string.
1936 @param DestMax The maximum number of Destination Ascii
1937 char, including terminating null char.
1938 @param Source A pointer to a Null-terminated Ascii string.
1939
1940 @retval RETURN_SUCCESS String is appended.
1941 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1942 StrLen(Destination).
1943 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1944 greater than StrLen(Source).
1945 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1946 If Source is NULL.
1947 If PcdMaximumAsciiStringLength is not zero,
1948 and DestMax is greater than
1949 PcdMaximumAsciiStringLength.
1950 If DestMax is 0.
1951 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1952 **/
1953 RETURN_STATUS
1954 EFIAPI
1955 AsciiStrCatS (
1956 IN OUT CHAR8 *Destination,
1957 IN UINTN DestMax,
1958 IN CONST CHAR8 *Source
1959 )
1960 {
1961 UINTN DestLen;
1962 UINTN CopyLen;
1963 UINTN SourceLen;
1964
1965 //
1966 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1967 //
1968 DestLen = AsciiStrnLenS (Destination, DestMax);
1969 CopyLen = DestMax - DestLen;
1970
1971 //
1972 // 1. Neither Destination nor Source shall be a null pointer.
1973 //
1974 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1975 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1976
1977 //
1978 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1979 //
1980 if (ASCII_RSIZE_MAX != 0) {
1981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1982 }
1983
1984 //
1985 // 3. DestMax shall not equal zero.
1986 //
1987 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1988
1989 //
1990 // 4. CopyLen shall not equal zero.
1991 //
1992 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
1993
1994 //
1995 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1996 //
1997 SourceLen = AsciiStrnLenS (Source, CopyLen);
1998 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
1999
2000 //
2001 // 6. Copying shall not take place between objects that overlap.
2002 //
2003 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2004
2005 //
2006 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2007 // terminating null character) to the end of the string pointed to by Destination. The initial character
2008 // from Source overwrites the null character at the end of Destination.
2009 //
2010 Destination = Destination + DestLen;
2011 while (*Source != 0) {
2012 *(Destination++) = *(Source++);
2013 }
2014
2015 *Destination = 0;
2016
2017 return RETURN_SUCCESS;
2018 }
2019
2020 /**
2021 Appends not more than Length successive char from the string pointed to by
2022 Source to the end of the string pointed to by Destination. If no null char is
2023 copied from Source, then Destination[StrLen(Destination) + Length] is always
2024 set to null.
2025
2026 This function is similar as strncat_s defined in C11.
2027
2028 If an error is returned, then the Destination is unmodified.
2029
2030 @param Destination A pointer to a Null-terminated Ascii string.
2031 @param DestMax The maximum number of Destination Ascii
2032 char, including terminating null char.
2033 @param Source A pointer to a Null-terminated Ascii string.
2034 @param Length The maximum number of Ascii characters to copy.
2035
2036 @retval RETURN_SUCCESS String is appended.
2037 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
2038 StrLen(Destination).
2039 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
2040 greater than MIN(StrLen(Source), Length).
2041 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2042 If Source is NULL.
2043 If PcdMaximumAsciiStringLength is not zero,
2044 and DestMax is greater than
2045 PcdMaximumAsciiStringLength.
2046 If DestMax is 0.
2047 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2048 **/
2049 RETURN_STATUS
2050 EFIAPI
2051 AsciiStrnCatS (
2052 IN OUT CHAR8 *Destination,
2053 IN UINTN DestMax,
2054 IN CONST CHAR8 *Source,
2055 IN UINTN Length
2056 )
2057 {
2058 UINTN DestLen;
2059 UINTN CopyLen;
2060 UINTN SourceLen;
2061
2062 //
2063 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2064 //
2065 DestLen = AsciiStrnLenS (Destination, DestMax);
2066 CopyLen = DestMax - DestLen;
2067
2068 //
2069 // 1. Neither Destination nor Source shall be a null pointer.
2070 //
2071 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2072 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2073
2074 //
2075 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2076 //
2077 if (ASCII_RSIZE_MAX != 0) {
2078 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2079 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2080 }
2081
2082 //
2083 // 3. DestMax shall not equal zero.
2084 //
2085 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2086
2087 //
2088 // 4. CopyLen shall not equal zero.
2089 //
2090 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2091
2092 //
2093 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2094 //
2095 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));
2096 if (Length >= CopyLen) {
2097 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2098 }
2099
2100 //
2101 // 6. Copying shall not take place between objects that overlap.
2102 //
2103 if (SourceLen > Length) {
2104 SourceLen = Length;
2105 }
2106
2107 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2108
2109 //
2110 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2111 // that follow a null character are not copied) from the array pointed to by Source to the end of
2112 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2113 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2114 // a null character.
2115 //
2116 Destination = Destination + DestLen;
2117 while ((SourceLen > 0) && (*Source != 0)) {
2118 *(Destination++) = *(Source++);
2119 SourceLen--;
2120 }
2121
2122 *Destination = 0;
2123
2124 return RETURN_SUCCESS;
2125 }
2126
2127 /**
2128 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2129
2130 This function outputs a value of type UINTN by interpreting the contents of
2131 the Ascii string specified by String as a decimal number. The format of the
2132 input Ascii string String is:
2133
2134 [spaces] [decimal digits].
2135
2136 The valid decimal digit character is in the range [0-9]. The function will
2137 ignore the pad space, which includes spaces or tab characters, before
2138 [decimal digits]. The running zero in the beginning of [decimal digits] will
2139 be ignored. Then, the function stops at the first character that is a not a
2140 valid decimal character or a Null-terminator, whichever one comes first.
2141
2142 If String has no valid decimal digits in the above format, then 0 is stored
2143 at the location pointed to by Data.
2144 If the number represented by String exceeds the range defined by UINTN, then
2145 MAX_UINTN is stored at the location pointed to by Data.
2146
2147 If EndPointer is not NULL, a pointer to the character that stopped the scan
2148 is stored at the location pointed to by EndPointer. If String has no valid
2149 decimal digits right after the optional pad spaces, the value of String is
2150 stored at the location pointed to by EndPointer.
2151
2152 @param String Pointer to a Null-terminated Ascii string.
2153 @param EndPointer Pointer to character that stops scan.
2154 @param Data Pointer to the converted value.
2155
2156 @retval RETURN_SUCCESS Value is translated from String.
2157 @retval RETURN_INVALID_PARAMETER If String is NULL.
2158 If Data is NULL.
2159 If PcdMaximumAsciiStringLength is not zero,
2160 and String contains more than
2161 PcdMaximumAsciiStringLength Ascii
2162 characters, not including the
2163 Null-terminator.
2164 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2165 the range defined by UINTN.
2166
2167 **/
2168 RETURN_STATUS
2169 EFIAPI
2170 AsciiStrDecimalToUintnS (
2171 IN CONST CHAR8 *String,
2172 OUT CHAR8 **EndPointer OPTIONAL,
2173 OUT UINTN *Data
2174 )
2175 {
2176 //
2177 // 1. Neither String nor Data shall be a null pointer.
2178 //
2179 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2180 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2181
2182 //
2183 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2184 //
2185 if (ASCII_RSIZE_MAX != 0) {
2186 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2187 }
2188
2189 if (EndPointer != NULL) {
2190 *EndPointer = (CHAR8 *)String;
2191 }
2192
2193 //
2194 // Ignore the pad spaces (space or tab)
2195 //
2196 while ((*String == ' ') || (*String == '\t')) {
2197 String++;
2198 }
2199
2200 //
2201 // Ignore leading Zeros after the spaces
2202 //
2203 while (*String == '0') {
2204 String++;
2205 }
2206
2207 *Data = 0;
2208
2209 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2210 //
2211 // If the number represented by String overflows according to the range
2212 // defined by UINTN, then MAX_UINTN is stored in *Data and
2213 // RETURN_UNSUPPORTED is returned.
2214 //
2215 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {
2216 *Data = MAX_UINTN;
2217 if (EndPointer != NULL) {
2218 *EndPointer = (CHAR8 *)String;
2219 }
2220
2221 return RETURN_UNSUPPORTED;
2222 }
2223
2224 *Data = *Data * 10 + (*String - '0');
2225 String++;
2226 }
2227
2228 if (EndPointer != NULL) {
2229 *EndPointer = (CHAR8 *)String;
2230 }
2231
2232 return RETURN_SUCCESS;
2233 }
2234
2235 /**
2236 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2237
2238 This function outputs a value of type UINT64 by interpreting the contents of
2239 the Ascii string specified by String as a decimal number. The format of the
2240 input Ascii string String is:
2241
2242 [spaces] [decimal digits].
2243
2244 The valid decimal digit character is in the range [0-9]. The function will
2245 ignore the pad space, which includes spaces or tab characters, before
2246 [decimal digits]. The running zero in the beginning of [decimal digits] will
2247 be ignored. Then, the function stops at the first character that is a not a
2248 valid decimal character or a Null-terminator, whichever one comes first.
2249
2250 If String has no valid decimal digits in the above format, then 0 is stored
2251 at the location pointed to by Data.
2252 If the number represented by String exceeds the range defined by UINT64, then
2253 MAX_UINT64 is stored at the location pointed to by Data.
2254
2255 If EndPointer is not NULL, a pointer to the character that stopped the scan
2256 is stored at the location pointed to by EndPointer. If String has no valid
2257 decimal digits right after the optional pad spaces, the value of String is
2258 stored at the location pointed to by EndPointer.
2259
2260 @param String Pointer to a Null-terminated Ascii string.
2261 @param EndPointer Pointer to character that stops scan.
2262 @param Data Pointer to the converted value.
2263
2264 @retval RETURN_SUCCESS Value is translated from String.
2265 @retval RETURN_INVALID_PARAMETER If String is NULL.
2266 If Data is NULL.
2267 If PcdMaximumAsciiStringLength is not zero,
2268 and String contains more than
2269 PcdMaximumAsciiStringLength Ascii
2270 characters, not including the
2271 Null-terminator.
2272 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2273 the range defined by UINT64.
2274
2275 **/
2276 RETURN_STATUS
2277 EFIAPI
2278 AsciiStrDecimalToUint64S (
2279 IN CONST CHAR8 *String,
2280 OUT CHAR8 **EndPointer OPTIONAL,
2281 OUT UINT64 *Data
2282 )
2283 {
2284 //
2285 // 1. Neither String nor Data shall be a null pointer.
2286 //
2287 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2288 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2289
2290 //
2291 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2292 //
2293 if (ASCII_RSIZE_MAX != 0) {
2294 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2295 }
2296
2297 if (EndPointer != NULL) {
2298 *EndPointer = (CHAR8 *)String;
2299 }
2300
2301 //
2302 // Ignore the pad spaces (space or tab)
2303 //
2304 while ((*String == ' ') || (*String == '\t')) {
2305 String++;
2306 }
2307
2308 //
2309 // Ignore leading Zeros after the spaces
2310 //
2311 while (*String == '0') {
2312 String++;
2313 }
2314
2315 *Data = 0;
2316
2317 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2318 //
2319 // If the number represented by String overflows according to the range
2320 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2321 // RETURN_UNSUPPORTED is returned.
2322 //
2323 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {
2324 *Data = MAX_UINT64;
2325 if (EndPointer != NULL) {
2326 *EndPointer = (CHAR8 *)String;
2327 }
2328
2329 return RETURN_UNSUPPORTED;
2330 }
2331
2332 *Data = MultU64x32 (*Data, 10) + (*String - '0');
2333 String++;
2334 }
2335
2336 if (EndPointer != NULL) {
2337 *EndPointer = (CHAR8 *)String;
2338 }
2339
2340 return RETURN_SUCCESS;
2341 }
2342
2343 /**
2344 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2345
2346 This function outputs a value of type UINTN by interpreting the contents of
2347 the Ascii string specified by String as a hexadecimal number. The format of
2348 the input Ascii string String is:
2349
2350 [spaces][zeros][x][hexadecimal digits].
2351
2352 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2353 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2354 "x" appears in the input string, it must be prefixed with at least one 0. The
2355 function will ignore the pad space, which includes spaces or tab characters,
2356 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2357 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2358 the first valid hexadecimal digit. Then, the function stops at the first
2359 character that is a not a valid hexadecimal character or Null-terminator,
2360 whichever on comes first.
2361
2362 If String has no valid hexadecimal digits in the above format, then 0 is
2363 stored at the location pointed to by Data.
2364 If the number represented by String exceeds the range defined by UINTN, then
2365 MAX_UINTN is stored at the location pointed to by Data.
2366
2367 If EndPointer is not NULL, a pointer to the character that stopped the scan
2368 is stored at the location pointed to by EndPointer. If String has no valid
2369 hexadecimal digits right after the optional pad spaces, the value of String
2370 is stored at the location pointed to by EndPointer.
2371
2372 @param String Pointer to a Null-terminated Ascii string.
2373 @param EndPointer Pointer to character that stops scan.
2374 @param Data Pointer to the converted value.
2375
2376 @retval RETURN_SUCCESS Value is translated from String.
2377 @retval RETURN_INVALID_PARAMETER If String is NULL.
2378 If Data is NULL.
2379 If PcdMaximumAsciiStringLength is not zero,
2380 and String contains more than
2381 PcdMaximumAsciiStringLength Ascii
2382 characters, not including the
2383 Null-terminator.
2384 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2385 the range defined by UINTN.
2386
2387 **/
2388 RETURN_STATUS
2389 EFIAPI
2390 AsciiStrHexToUintnS (
2391 IN CONST CHAR8 *String,
2392 OUT CHAR8 **EndPointer OPTIONAL,
2393 OUT UINTN *Data
2394 )
2395 {
2396 //
2397 // 1. Neither String nor Data shall be a null pointer.
2398 //
2399 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2400 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2401
2402 //
2403 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2404 //
2405 if (ASCII_RSIZE_MAX != 0) {
2406 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2407 }
2408
2409 if (EndPointer != NULL) {
2410 *EndPointer = (CHAR8 *)String;
2411 }
2412
2413 //
2414 // Ignore the pad spaces (space or tab)
2415 //
2416 while ((*String == ' ') || (*String == '\t')) {
2417 String++;
2418 }
2419
2420 //
2421 // Ignore leading Zeros after the spaces
2422 //
2423 while (*String == '0') {
2424 String++;
2425 }
2426
2427 if (AsciiCharToUpper (*String) == 'X') {
2428 if (*(String - 1) != '0') {
2429 *Data = 0;
2430 return RETURN_SUCCESS;
2431 }
2432
2433 //
2434 // Skip the 'X'
2435 //
2436 String++;
2437 }
2438
2439 *Data = 0;
2440
2441 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
2442 //
2443 // If the number represented by String overflows according to the range
2444 // defined by UINTN, then MAX_UINTN is stored in *Data and
2445 // RETURN_UNSUPPORTED is returned.
2446 //
2447 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {
2448 *Data = MAX_UINTN;
2449 if (EndPointer != NULL) {
2450 *EndPointer = (CHAR8 *)String;
2451 }
2452
2453 return RETURN_UNSUPPORTED;
2454 }
2455
2456 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);
2457 String++;
2458 }
2459
2460 if (EndPointer != NULL) {
2461 *EndPointer = (CHAR8 *)String;
2462 }
2463
2464 return RETURN_SUCCESS;
2465 }
2466
2467 /**
2468 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2469
2470 This function outputs a value of type UINT64 by interpreting the contents of
2471 the Ascii string specified by String as a hexadecimal number. The format of
2472 the input Ascii string String is:
2473
2474 [spaces][zeros][x][hexadecimal digits].
2475
2476 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2477 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2478 "x" appears in the input string, it must be prefixed with at least one 0. The
2479 function will ignore the pad space, which includes spaces or tab characters,
2480 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2481 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2482 the first valid hexadecimal digit. Then, the function stops at the first
2483 character that is a not a valid hexadecimal character or Null-terminator,
2484 whichever on comes first.
2485
2486 If String has no valid hexadecimal digits in the above format, then 0 is
2487 stored at the location pointed to by Data.
2488 If the number represented by String exceeds the range defined by UINT64, then
2489 MAX_UINT64 is stored at the location pointed to by Data.
2490
2491 If EndPointer is not NULL, a pointer to the character that stopped the scan
2492 is stored at the location pointed to by EndPointer. If String has no valid
2493 hexadecimal digits right after the optional pad spaces, the value of String
2494 is stored at the location pointed to by EndPointer.
2495
2496 @param String Pointer to a Null-terminated Ascii string.
2497 @param EndPointer Pointer to character that stops scan.
2498 @param Data Pointer to the converted value.
2499
2500 @retval RETURN_SUCCESS Value is translated from String.
2501 @retval RETURN_INVALID_PARAMETER If String is NULL.
2502 If Data is NULL.
2503 If PcdMaximumAsciiStringLength is not zero,
2504 and String contains more than
2505 PcdMaximumAsciiStringLength Ascii
2506 characters, not including the
2507 Null-terminator.
2508 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2509 the range defined by UINT64.
2510
2511 **/
2512 RETURN_STATUS
2513 EFIAPI
2514 AsciiStrHexToUint64S (
2515 IN CONST CHAR8 *String,
2516 OUT CHAR8 **EndPointer OPTIONAL,
2517 OUT UINT64 *Data
2518 )
2519 {
2520 //
2521 // 1. Neither String nor Data shall be a null pointer.
2522 //
2523 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2524 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2525
2526 //
2527 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2528 //
2529 if (ASCII_RSIZE_MAX != 0) {
2530 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2531 }
2532
2533 if (EndPointer != NULL) {
2534 *EndPointer = (CHAR8 *)String;
2535 }
2536
2537 //
2538 // Ignore the pad spaces (space or tab)
2539 //
2540 while ((*String == ' ') || (*String == '\t')) {
2541 String++;
2542 }
2543
2544 //
2545 // Ignore leading Zeros after the spaces
2546 //
2547 while (*String == '0') {
2548 String++;
2549 }
2550
2551 if (AsciiCharToUpper (*String) == 'X') {
2552 if (*(String - 1) != '0') {
2553 *Data = 0;
2554 return RETURN_SUCCESS;
2555 }
2556
2557 //
2558 // Skip the 'X'
2559 //
2560 String++;
2561 }
2562
2563 *Data = 0;
2564
2565 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
2566 //
2567 // If the number represented by String overflows according to the range
2568 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2569 // RETURN_UNSUPPORTED is returned.
2570 //
2571 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {
2572 *Data = MAX_UINT64;
2573 if (EndPointer != NULL) {
2574 *EndPointer = (CHAR8 *)String;
2575 }
2576
2577 return RETURN_UNSUPPORTED;
2578 }
2579
2580 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);
2581 String++;
2582 }
2583
2584 if (EndPointer != NULL) {
2585 *EndPointer = (CHAR8 *)String;
2586 }
2587
2588 return RETURN_SUCCESS;
2589 }
2590
2591 /**
2592 Convert a Null-terminated Unicode string to a Null-terminated
2593 ASCII string.
2594
2595 This function is similar to AsciiStrCpyS.
2596
2597 This function converts the content of the Unicode string Source
2598 to the ASCII string Destination by copying the lower 8 bits of
2599 each Unicode character. The function terminates the ASCII string
2600 Destination by appending a Null-terminator character at the end.
2601
2602 The caller is responsible to make sure Destination points to a buffer with size
2603 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2604
2605 If any Unicode characters in Source contain non-zero value in
2606 the upper 8 bits, then ASSERT().
2607
2608 If Source is not aligned on a 16-bit boundary, then ASSERT().
2609
2610 If an error is returned, then the Destination is unmodified.
2611
2612 @param Source The pointer to a Null-terminated Unicode string.
2613 @param Destination The pointer to a Null-terminated ASCII string.
2614 @param DestMax The maximum number of Destination Ascii
2615 char, including terminating null char.
2616
2617 @retval RETURN_SUCCESS String is converted.
2618 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2619 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2620 If Source is NULL.
2621 If PcdMaximumAsciiStringLength is not zero,
2622 and DestMax is greater than
2623 PcdMaximumAsciiStringLength.
2624 If PcdMaximumUnicodeStringLength is not zero,
2625 and DestMax is greater than
2626 PcdMaximumUnicodeStringLength.
2627 If DestMax is 0.
2628 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2629
2630 **/
2631 RETURN_STATUS
2632 EFIAPI
2633 UnicodeStrToAsciiStrS (
2634 IN CONST CHAR16 *Source,
2635 OUT CHAR8 *Destination,
2636 IN UINTN DestMax
2637 )
2638 {
2639 UINTN SourceLen;
2640
2641 ASSERT (((UINTN)Source & BIT0) == 0);
2642
2643 //
2644 // 1. Neither Destination nor Source shall be a null pointer.
2645 //
2646 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2647 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2648
2649 //
2650 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2651 //
2652 if (ASCII_RSIZE_MAX != 0) {
2653 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2654 }
2655
2656 if (RSIZE_MAX != 0) {
2657 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2658 }
2659
2660 //
2661 // 3. DestMax shall not equal zero.
2662 //
2663 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2664
2665 //
2666 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2667 //
2668 SourceLen = StrnLenS (Source, DestMax);
2669 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2670
2671 //
2672 // 5. Copying shall not take place between objects that overlap.
2673 //
2674 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2675
2676 //
2677 // convert string
2678 //
2679 while (*Source != '\0') {
2680 //
2681 // If any Unicode characters in Source contain
2682 // non-zero value in the upper 8 bits, then ASSERT().
2683 //
2684 ASSERT (*Source < 0x100);
2685 *(Destination++) = (CHAR8)*(Source++);
2686 }
2687
2688 *Destination = '\0';
2689
2690 return RETURN_SUCCESS;
2691 }
2692
2693 /**
2694 Convert not more than Length successive characters from a Null-terminated
2695 Unicode string to a Null-terminated Ascii string. If no null char is copied
2696 from Source, then Destination[Length] is always set to null.
2697
2698 This function converts not more than Length successive characters from the
2699 Unicode string Source to the Ascii string Destination by copying the lower 8
2700 bits of each Unicode character. The function terminates the Ascii string
2701 Destination by appending a Null-terminator character at the end.
2702
2703 The caller is responsible to make sure Destination points to a buffer with
2704 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2705 in bytes.
2706
2707 If any Unicode characters in Source contain non-zero value in the upper 8
2708 bits, then ASSERT().
2709 If Source is not aligned on a 16-bit boundary, then ASSERT().
2710
2711 If an error is returned, then Destination and DestinationLength are
2712 unmodified.
2713
2714 @param Source The pointer to a Null-terminated Unicode string.
2715 @param Length The maximum number of Unicode characters to
2716 convert.
2717 @param Destination The pointer to a Null-terminated Ascii string.
2718 @param DestMax The maximum number of Destination Ascii char,
2719 including terminating null char.
2720 @param DestinationLength The number of Unicode characters converted.
2721
2722 @retval RETURN_SUCCESS String is converted.
2723 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2724 If Source is NULL.
2725 If DestinationLength is NULL.
2726 If PcdMaximumAsciiStringLength is not zero,
2727 and Length or DestMax is greater than
2728 PcdMaximumAsciiStringLength.
2729 If PcdMaximumUnicodeStringLength is not
2730 zero, and Length or DestMax is greater than
2731 PcdMaximumUnicodeStringLength.
2732 If DestMax is 0.
2733 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2734 MIN(StrLen(Source), Length).
2735 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2736
2737 **/
2738 RETURN_STATUS
2739 EFIAPI
2740 UnicodeStrnToAsciiStrS (
2741 IN CONST CHAR16 *Source,
2742 IN UINTN Length,
2743 OUT CHAR8 *Destination,
2744 IN UINTN DestMax,
2745 OUT UINTN *DestinationLength
2746 )
2747 {
2748 UINTN SourceLen;
2749
2750 ASSERT (((UINTN)Source & BIT0) == 0);
2751
2752 //
2753 // 1. None of Destination, Source or DestinationLength shall be a null
2754 // pointer.
2755 //
2756 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2757 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2758 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2759
2760 //
2761 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2762 // RSIZE_MAX.
2763 //
2764 if (ASCII_RSIZE_MAX != 0) {
2765 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2766 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2767 }
2768
2769 if (RSIZE_MAX != 0) {
2770 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2771 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2772 }
2773
2774 //
2775 // 3. DestMax shall not equal zero.
2776 //
2777 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2778
2779 //
2780 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2781 // StrnLenS(Source, DestMax).
2782 //
2783 SourceLen = StrnLenS (Source, DestMax);
2784 if (Length >= DestMax) {
2785 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2786 }
2787
2788 //
2789 // 5. Copying shall not take place between objects that overlap.
2790 //
2791 if (SourceLen > Length) {
2792 SourceLen = Length;
2793 }
2794
2795 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof (CHAR16)), RETURN_ACCESS_DENIED);
2796
2797 *DestinationLength = 0;
2798
2799 //
2800 // Convert string
2801 //
2802 while ((*Source != 0) && (SourceLen > 0)) {
2803 //
2804 // If any Unicode characters in Source contain non-zero value in the upper
2805 // 8 bits, then ASSERT().
2806 //
2807 ASSERT (*Source < 0x100);
2808 *(Destination++) = (CHAR8)*(Source++);
2809 SourceLen--;
2810 (*DestinationLength)++;
2811 }
2812
2813 *Destination = 0;
2814
2815 return RETURN_SUCCESS;
2816 }
2817
2818 /**
2819 Convert one Null-terminated ASCII string to a Null-terminated
2820 Unicode string.
2821
2822 This function is similar to StrCpyS.
2823
2824 This function converts the contents of the ASCII string Source to the Unicode
2825 string Destination. The function terminates the Unicode string Destination by
2826 appending a Null-terminator character at the end.
2827
2828 The caller is responsible to make sure Destination points to a buffer with size
2829 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2830
2831 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2832
2833 If an error is returned, then the Destination is unmodified.
2834
2835 @param Source The pointer to a Null-terminated ASCII string.
2836 @param Destination The pointer to a Null-terminated Unicode string.
2837 @param DestMax The maximum number of Destination Unicode
2838 char, including terminating null char.
2839
2840 @retval RETURN_SUCCESS String is converted.
2841 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2842 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2843 If Source is NULL.
2844 If PcdMaximumUnicodeStringLength is not zero,
2845 and DestMax is greater than
2846 PcdMaximumUnicodeStringLength.
2847 If PcdMaximumAsciiStringLength is not zero,
2848 and DestMax is greater than
2849 PcdMaximumAsciiStringLength.
2850 If DestMax is 0.
2851 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2852
2853 **/
2854 RETURN_STATUS
2855 EFIAPI
2856 AsciiStrToUnicodeStrS (
2857 IN CONST CHAR8 *Source,
2858 OUT CHAR16 *Destination,
2859 IN UINTN DestMax
2860 )
2861 {
2862 UINTN SourceLen;
2863
2864 ASSERT (((UINTN)Destination & BIT0) == 0);
2865
2866 //
2867 // 1. Neither Destination nor Source shall be a null pointer.
2868 //
2869 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2870 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2871
2872 //
2873 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2874 //
2875 if (RSIZE_MAX != 0) {
2876 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2877 }
2878
2879 if (ASCII_RSIZE_MAX != 0) {
2880 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2881 }
2882
2883 //
2884 // 3. DestMax shall not equal zero.
2885 //
2886 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2887
2888 //
2889 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2890 //
2891 SourceLen = AsciiStrnLenS (Source, DestMax);
2892 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2893
2894 //
2895 // 5. Copying shall not take place between objects that overlap.
2896 //
2897 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2898
2899 //
2900 // Convert string
2901 //
2902 while (*Source != '\0') {
2903 *(Destination++) = (CHAR16)(UINT8)*(Source++);
2904 }
2905
2906 *Destination = '\0';
2907
2908 return RETURN_SUCCESS;
2909 }
2910
2911 /**
2912 Convert not more than Length successive characters from a Null-terminated
2913 Ascii string to a Null-terminated Unicode string. If no null char is copied
2914 from Source, then Destination[Length] is always set to null.
2915
2916 This function converts not more than Length successive characters from the
2917 Ascii string Source to the Unicode string Destination. The function
2918 terminates the Unicode string Destination by appending a Null-terminator
2919 character at the end.
2920
2921 The caller is responsible to make sure Destination points to a buffer with
2922 size not smaller than
2923 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2924
2925 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2926
2927 If an error is returned, then Destination and DestinationLength are
2928 unmodified.
2929
2930 @param Source The pointer to a Null-terminated Ascii string.
2931 @param Length The maximum number of Ascii characters to convert.
2932 @param Destination The pointer to a Null-terminated Unicode string.
2933 @param DestMax The maximum number of Destination Unicode char,
2934 including terminating null char.
2935 @param DestinationLength The number of Ascii characters converted.
2936
2937 @retval RETURN_SUCCESS String is converted.
2938 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2939 If Source is NULL.
2940 If DestinationLength is NULL.
2941 If PcdMaximumUnicodeStringLength is not
2942 zero, and Length or DestMax is greater than
2943 PcdMaximumUnicodeStringLength.
2944 If PcdMaximumAsciiStringLength is not zero,
2945 and Length or DestMax is greater than
2946 PcdMaximumAsciiStringLength.
2947 If DestMax is 0.
2948 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2949 MIN(AsciiStrLen(Source), Length).
2950 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2951
2952 **/
2953 RETURN_STATUS
2954 EFIAPI
2955 AsciiStrnToUnicodeStrS (
2956 IN CONST CHAR8 *Source,
2957 IN UINTN Length,
2958 OUT CHAR16 *Destination,
2959 IN UINTN DestMax,
2960 OUT UINTN *DestinationLength
2961 )
2962 {
2963 UINTN SourceLen;
2964
2965 ASSERT (((UINTN)Destination & BIT0) == 0);
2966
2967 //
2968 // 1. None of Destination, Source or DestinationLength shall be a null
2969 // pointer.
2970 //
2971 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2972 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2973 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2974
2975 //
2976 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2977 // RSIZE_MAX.
2978 //
2979 if (RSIZE_MAX != 0) {
2980 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2981 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2982 }
2983
2984 if (ASCII_RSIZE_MAX != 0) {
2985 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2986 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2987 }
2988
2989 //
2990 // 3. DestMax shall not equal zero.
2991 //
2992 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2993
2994 //
2995 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2996 // AsciiStrnLenS(Source, DestMax).
2997 //
2998 SourceLen = AsciiStrnLenS (Source, DestMax);
2999 if (Length >= DestMax) {
3000 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
3001 }
3002
3003 //
3004 // 5. Copying shall not take place between objects that overlap.
3005 //
3006 if (SourceLen > Length) {
3007 SourceLen = Length;
3008 }
3009
3010 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof (CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
3011
3012 *DestinationLength = 0;
3013
3014 //
3015 // Convert string
3016 //
3017 while ((*Source != 0) && (SourceLen > 0)) {
3018 *(Destination++) = (CHAR16)(UINT8)*(Source++);
3019 SourceLen--;
3020 (*DestinationLength)++;
3021 }
3022
3023 *Destination = 0;
3024
3025 return RETURN_SUCCESS;
3026 }
3027
3028 /**
3029 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
3030
3031 This function outputs a value of type IPv6_ADDRESS and may output a value
3032 of type UINT8 by interpreting the contents of the ASCII string specified
3033 by String. The format of the input ASCII string String is as follows:
3034
3035 X:X:X:X:X:X:X:X[/P]
3036
3037 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
3038 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
3039 memory address and high byte is stored in high memory address. P contains decimal
3040 digit characters in the range [0-9]. The running zero in the beginning of P will
3041 be ignored. /P is optional.
3042
3043 When /P is not in the String, the function stops at the first character that is
3044 not a valid hexadecimal digit character after eight X's are converted.
3045
3046 When /P is in the String, the function stops at the first character that is not
3047 a valid decimal digit character after P is converted.
3048
3049 "::" can be used to compress one or more groups of X when X contains only 0.
3050 The "::" can only appear once in the String.
3051
3052 If EndPointer is not NULL and Address is translated from String, a pointer
3053 to the character that stopped the scan is stored at the location pointed to
3054 by EndPointer.
3055
3056 @param String Pointer to a Null-terminated ASCII string.
3057 @param EndPointer Pointer to character that stops scan.
3058 @param Address Pointer to the converted IPv6 address.
3059 @param PrefixLength Pointer to the converted IPv6 address prefix
3060 length. MAX_UINT8 is returned when /P is
3061 not in the String.
3062
3063 @retval RETURN_SUCCESS Address is translated from String.
3064 @retval RETURN_INVALID_PARAMETER If String is NULL.
3065 If Data is NULL.
3066 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3067 digit characters.
3068 If String contains "::" and number of X
3069 is not less than 8.
3070 If P starts with character that is not a
3071 valid decimal digit character.
3072 If the decimal number converted from P
3073 exceeds 128.
3074
3075 **/
3076 RETURN_STATUS
3077 EFIAPI
3078 AsciiStrToIpv6Address (
3079 IN CONST CHAR8 *String,
3080 OUT CHAR8 **EndPointer OPTIONAL,
3081 OUT IPv6_ADDRESS *Address,
3082 OUT UINT8 *PrefixLength OPTIONAL
3083 )
3084 {
3085 RETURN_STATUS Status;
3086 UINTN AddressIndex;
3087 UINTN Uintn;
3088 IPv6_ADDRESS LocalAddress;
3089 UINT8 LocalPrefixLength;
3090 CONST CHAR8 *Pointer;
3091 CHAR8 *End;
3092 UINTN CompressStart;
3093 BOOLEAN ExpectPrefix;
3094
3095 LocalPrefixLength = MAX_UINT8;
3096 CompressStart = ARRAY_SIZE (Address->Addr);
3097 ExpectPrefix = FALSE;
3098
3099 //
3100 // None of String or Address shall be a null pointer.
3101 //
3102 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3103 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3104
3105 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3106 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
3107 if (*Pointer != ':') {
3108 //
3109 // ":" or "/" should be followed by digit characters.
3110 //
3111 return RETURN_UNSUPPORTED;
3112 }
3113
3114 //
3115 // Meet second ":" after previous ":" or "/"
3116 // or meet first ":" in the beginning of String.
3117 //
3118 if (ExpectPrefix) {
3119 //
3120 // ":" shall not be after "/"
3121 //
3122 return RETURN_UNSUPPORTED;
3123 }
3124
3125 if ((CompressStart != ARRAY_SIZE (Address->Addr)) || (AddressIndex == ARRAY_SIZE (Address->Addr))) {
3126 //
3127 // "::" can only appear once.
3128 // "::" can only appear when address is not full length.
3129 //
3130 return RETURN_UNSUPPORTED;
3131 } else {
3132 //
3133 // Remember the start of zero compressing.
3134 //
3135 CompressStart = AddressIndex;
3136 Pointer++;
3137
3138 if (CompressStart == 0) {
3139 if (*Pointer != ':') {
3140 //
3141 // Single ":" shall not be in the beginning of String.
3142 //
3143 return RETURN_UNSUPPORTED;
3144 }
3145
3146 Pointer++;
3147 }
3148 }
3149 }
3150
3151 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
3152 if (*Pointer == '/') {
3153 //
3154 // Might be optional "/P" after "::".
3155 //
3156 if (CompressStart != AddressIndex) {
3157 return RETURN_UNSUPPORTED;
3158 }
3159 } else {
3160 break;
3161 }
3162 } else {
3163 if (!ExpectPrefix) {
3164 //
3165 // Get X.
3166 //
3167 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);
3168 if (RETURN_ERROR (Status) || (End - Pointer > 4)) {
3169 //
3170 // Number of hexadecimal digit characters is no more than 4.
3171 //
3172 return RETURN_UNSUPPORTED;
3173 }
3174
3175 Pointer = End;
3176 //
3177 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3178 //
3179 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
3180 LocalAddress.Addr[AddressIndex] = (UINT8)((UINT16)Uintn >> 8);
3181 LocalAddress.Addr[AddressIndex + 1] = (UINT8)Uintn;
3182 AddressIndex += 2;
3183 } else {
3184 //
3185 // Get P, then exit the loop.
3186 //
3187 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);
3188 if (RETURN_ERROR (Status) || (End == Pointer) || (Uintn > 128)) {
3189 //
3190 // Prefix length should not exceed 128.
3191 //
3192 return RETURN_UNSUPPORTED;
3193 }
3194
3195 LocalPrefixLength = (UINT8)Uintn;
3196 Pointer = End;
3197 break;
3198 }
3199 }
3200
3201 //
3202 // Skip ':' or "/"
3203 //
3204 if (*Pointer == '/') {
3205 ExpectPrefix = TRUE;
3206 } else if (*Pointer == ':') {
3207 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3208 //
3209 // Meet additional ":" after all 8 16-bit address
3210 //
3211 break;
3212 }
3213 } else {
3214 //
3215 // Meet other character that is not "/" or ":" after all 8 16-bit address
3216 //
3217 break;
3218 }
3219
3220 Pointer++;
3221 }
3222
3223 if (((AddressIndex == ARRAY_SIZE (Address->Addr)) && (CompressStart != ARRAY_SIZE (Address->Addr))) ||
3224 ((AddressIndex != ARRAY_SIZE (Address->Addr)) && (CompressStart == ARRAY_SIZE (Address->Addr)))
3225 )
3226 {
3227 //
3228 // Full length of address shall not have compressing zeros.
3229 // Non-full length of address shall have compressing zeros.
3230 //
3231 return RETURN_UNSUPPORTED;
3232 }
3233
3234 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
3235 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
3236 if (AddressIndex > CompressStart) {
3237 CopyMem (
3238 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
3239 &LocalAddress.Addr[CompressStart],
3240 AddressIndex - CompressStart
3241 );
3242 }
3243
3244 if (PrefixLength != NULL) {
3245 *PrefixLength = LocalPrefixLength;
3246 }
3247
3248 if (EndPointer != NULL) {
3249 *EndPointer = (CHAR8 *)Pointer;
3250 }
3251
3252 return RETURN_SUCCESS;
3253 }
3254
3255 /**
3256 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3257
3258 This function outputs a value of type IPv4_ADDRESS and may output a value
3259 of type UINT8 by interpreting the contents of the ASCII string specified
3260 by String. The format of the input ASCII string String is as follows:
3261
3262 D.D.D.D[/P]
3263
3264 D and P are decimal digit characters in the range [0-9]. The running zero in
3265 the beginning of D and P will be ignored. /P is optional.
3266
3267 When /P is not in the String, the function stops at the first character that is
3268 not a valid decimal digit character after four D's are converted.
3269
3270 When /P is in the String, the function stops at the first character that is not
3271 a valid decimal digit character after P is converted.
3272
3273 If EndPointer is not NULL and Address is translated from String, a pointer
3274 to the character that stopped the scan is stored at the location pointed to
3275 by EndPointer.
3276
3277 @param String Pointer to a Null-terminated ASCII string.
3278 @param EndPointer Pointer to character that stops scan.
3279 @param Address Pointer to the converted IPv4 address.
3280 @param PrefixLength Pointer to the converted IPv4 address prefix
3281 length. MAX_UINT8 is returned when /P is
3282 not in the String.
3283
3284 @retval RETURN_SUCCESS Address is translated from String.
3285 @retval RETURN_INVALID_PARAMETER If String is NULL.
3286 If Data is NULL.
3287 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3288 If any decimal number converted from D
3289 exceeds 255.
3290 If the decimal number converted from P
3291 exceeds 32.
3292
3293 **/
3294 RETURN_STATUS
3295 EFIAPI
3296 AsciiStrToIpv4Address (
3297 IN CONST CHAR8 *String,
3298 OUT CHAR8 **EndPointer OPTIONAL,
3299 OUT IPv4_ADDRESS *Address,
3300 OUT UINT8 *PrefixLength OPTIONAL
3301 )
3302 {
3303 RETURN_STATUS Status;
3304 UINTN AddressIndex;
3305 UINTN Uintn;
3306 IPv4_ADDRESS LocalAddress;
3307 UINT8 LocalPrefixLength;
3308 CHAR8 *Pointer;
3309
3310 LocalPrefixLength = MAX_UINT8;
3311
3312 //
3313 // None of String or Address shall be a null pointer.
3314 //
3315 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3316 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3317
3318 for (Pointer = (CHAR8 *)String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3319 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {
3320 //
3321 // D or P contains invalid characters.
3322 //
3323 break;
3324 }
3325
3326 //
3327 // Get D or P.
3328 //
3329 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *)Pointer, &Pointer, &Uintn);
3330 if (RETURN_ERROR (Status)) {
3331 return RETURN_UNSUPPORTED;
3332 }
3333
3334 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3335 //
3336 // It's P.
3337 //
3338 if (Uintn > 32) {
3339 return RETURN_UNSUPPORTED;
3340 }
3341
3342 LocalPrefixLength = (UINT8)Uintn;
3343 } else {
3344 //
3345 // It's D.
3346 //
3347 if (Uintn > MAX_UINT8) {
3348 return RETURN_UNSUPPORTED;
3349 }
3350
3351 LocalAddress.Addr[AddressIndex] = (UINT8)Uintn;
3352 AddressIndex++;
3353 }
3354
3355 //
3356 // Check the '.' or '/', depending on the AddressIndex.
3357 //
3358 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3359 if (*Pointer == '/') {
3360 //
3361 // '/P' is in the String.
3362 // Skip "/" and get P in next loop.
3363 //
3364 Pointer++;
3365 } else {
3366 //
3367 // '/P' is not in the String.
3368 //
3369 break;
3370 }
3371 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3372 if (*Pointer == '.') {
3373 //
3374 // D should be followed by '.'
3375 //
3376 Pointer++;
3377 } else {
3378 return RETURN_UNSUPPORTED;
3379 }
3380 }
3381 }
3382
3383 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3384 return RETURN_UNSUPPORTED;
3385 }
3386
3387 CopyMem (Address, &LocalAddress, sizeof (*Address));
3388 if (PrefixLength != NULL) {
3389 *PrefixLength = LocalPrefixLength;
3390 }
3391
3392 if (EndPointer != NULL) {
3393 *EndPointer = Pointer;
3394 }
3395
3396 return RETURN_SUCCESS;
3397 }
3398
3399 /**
3400 Convert a Null-terminated ASCII GUID string to a value of type
3401 EFI_GUID.
3402
3403 This function outputs a GUID value by interpreting the contents of
3404 the ASCII string specified by String. The format of the input
3405 ASCII string String consists of 36 characters, as follows:
3406
3407 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3408
3409 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3410 [A-F], with each pair representing a single byte hexadecimal value.
3411
3412 The mapping between String and the EFI_GUID structure is as follows:
3413 aa Data1[24:31]
3414 bb Data1[16:23]
3415 cc Data1[8:15]
3416 dd Data1[0:7]
3417 ee Data2[8:15]
3418 ff Data2[0:7]
3419 gg Data3[8:15]
3420 hh Data3[0:7]
3421 ii Data4[0:7]
3422 jj Data4[8:15]
3423 kk Data4[16:23]
3424 ll Data4[24:31]
3425 mm Data4[32:39]
3426 nn Data4[40:47]
3427 oo Data4[48:55]
3428 pp Data4[56:63]
3429
3430 @param String Pointer to a Null-terminated ASCII string.
3431 @param Guid Pointer to the converted GUID.
3432
3433 @retval RETURN_SUCCESS Guid is translated from String.
3434 @retval RETURN_INVALID_PARAMETER If String is NULL.
3435 If Data is NULL.
3436 @retval RETURN_UNSUPPORTED If String is not as the above format.
3437
3438 **/
3439 RETURN_STATUS
3440 EFIAPI
3441 AsciiStrToGuid (
3442 IN CONST CHAR8 *String,
3443 OUT GUID *Guid
3444 )
3445 {
3446 RETURN_STATUS Status;
3447 GUID LocalGuid;
3448
3449 //
3450 // None of String or Guid shall be a null pointer.
3451 //
3452 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3453 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
3454
3455 //
3456 // Get aabbccdd in big-endian.
3457 //
3458 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)&LocalGuid.Data1, sizeof (LocalGuid.Data1));
3459 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data1)] != '-')) {
3460 return RETURN_UNSUPPORTED;
3461 }
3462
3463 //
3464 // Convert big-endian to little-endian.
3465 //
3466 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
3467 String += 2 * sizeof (LocalGuid.Data1) + 1;
3468
3469 //
3470 // Get eeff in big-endian.
3471 //
3472 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)&LocalGuid.Data2, sizeof (LocalGuid.Data2));
3473 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data2)] != '-')) {
3474 return RETURN_UNSUPPORTED;
3475 }
3476
3477 //
3478 // Convert big-endian to little-endian.
3479 //
3480 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
3481 String += 2 * sizeof (LocalGuid.Data2) + 1;
3482
3483 //
3484 // Get gghh in big-endian.
3485 //
3486 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)&LocalGuid.Data3, sizeof (LocalGuid.Data3));
3487 if (RETURN_ERROR (Status) || (String[2 * sizeof (LocalGuid.Data3)] != '-')) {
3488 return RETURN_UNSUPPORTED;
3489 }
3490
3491 //
3492 // Convert big-endian to little-endian.
3493 //
3494 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
3495 String += 2 * sizeof (LocalGuid.Data3) + 1;
3496
3497 //
3498 // Get iijj.
3499 //
3500 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
3501 if (RETURN_ERROR (Status) || (String[2 * 2] != '-')) {
3502 return RETURN_UNSUPPORTED;
3503 }
3504
3505 String += 2 * 2 + 1;
3506
3507 //
3508 // Get kkllmmnnoopp.
3509 //
3510 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
3511 if (RETURN_ERROR (Status)) {
3512 return RETURN_UNSUPPORTED;
3513 }
3514
3515 CopyGuid (Guid, &LocalGuid);
3516 return RETURN_SUCCESS;
3517 }
3518
3519 /**
3520 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3521
3522 This function outputs a byte array by interpreting the contents of
3523 the ASCII string specified by String in hexadecimal format. The format of
3524 the input ASCII string String is:
3525
3526 [XX]*
3527
3528 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3529 The function decodes every two hexadecimal digit characters as one byte. The
3530 decoding stops after Length of characters and outputs Buffer containing
3531 (Length / 2) bytes.
3532
3533 @param String Pointer to a Null-terminated ASCII string.
3534 @param Length The number of ASCII characters to decode.
3535 @param Buffer Pointer to the converted bytes array.
3536 @param MaxBufferSize The maximum size of Buffer.
3537
3538 @retval RETURN_SUCCESS Buffer is translated from String.
3539 @retval RETURN_INVALID_PARAMETER If String is NULL.
3540 If Data is NULL.
3541 If Length is not multiple of 2.
3542 If PcdMaximumAsciiStringLength is not zero,
3543 and Length is greater than
3544 PcdMaximumAsciiStringLength.
3545 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3546 a character that is not valid hexadecimal
3547 digit characters, or a Null-terminator.
3548 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3549 **/
3550 RETURN_STATUS
3551 EFIAPI
3552 AsciiStrHexToBytes (
3553 IN CONST CHAR8 *String,
3554 IN UINTN Length,
3555 OUT UINT8 *Buffer,
3556 IN UINTN MaxBufferSize
3557 )
3558 {
3559 UINTN Index;
3560
3561 //
3562 // 1. None of String or Buffer shall be a null pointer.
3563 //
3564 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3565 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
3566
3567 //
3568 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3569 //
3570 if (ASCII_RSIZE_MAX != 0) {
3571 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3572 }
3573
3574 //
3575 // 3. Length shall not be odd.
3576 //
3577 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
3578
3579 //
3580 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3581 //
3582 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
3583
3584 //
3585 // 5. String shall not contains invalid hexadecimal digits.
3586 //
3587 for (Index = 0; Index < Length; Index++) {
3588 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {
3589 break;
3590 }
3591 }
3592
3593 if (Index != Length) {
3594 return RETURN_UNSUPPORTED;
3595 }
3596
3597 //
3598 // Convert the hex string to bytes.
3599 //
3600 for (Index = 0; Index < Length; Index++) {
3601 //
3602 // For even characters, write the upper nibble for each buffer byte,
3603 // and for even characters, the lower nibble.
3604 //
3605 if ((Index & BIT0) == 0) {
3606 Buffer[Index / 2] = (UINT8)InternalAsciiHexCharToUintn (String[Index]) << 4;
3607 } else {
3608 Buffer[Index / 2] |= (UINT8)InternalAsciiHexCharToUintn (String[Index]);
3609 }
3610 }
3611
3612 return RETURN_SUCCESS;
3613 }