]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/SafeString.c
MdePkg/BaseLib: BaseLib for RISCV64 architecture
[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 ASSERT (Expression); \
18 if (!(Expression)) { \
19 return Status; \
20 } \
21 } while (FALSE)
22
23 /**
24 Returns if 2 memory blocks are overlapped.
25
26 @param Base1 Base address of 1st memory block.
27 @param Size1 Size of 1st memory block.
28 @param Base2 Base address of 2nd memory block.
29 @param Size2 Size of 2nd memory block.
30
31 @retval TRUE 2 memory blocks are overlapped.
32 @retval FALSE 2 memory blocks are not overlapped.
33 **/
34 BOOLEAN
35 InternalSafeStringIsOverlap (
36 IN VOID *Base1,
37 IN UINTN Size1,
38 IN VOID *Base2,
39 IN UINTN Size2
40 )
41 {
42 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
43 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
44 return TRUE;
45 }
46 return FALSE;
47 }
48
49 /**
50 Returns if 2 Unicode strings are not overlapped.
51
52 @param Str1 Start address of 1st Unicode string.
53 @param Size1 The number of char in 1st Unicode string,
54 including terminating null char.
55 @param Str2 Start address of 2nd Unicode string.
56 @param Size2 The number of char in 2nd Unicode string,
57 including terminating null char.
58
59 @retval TRUE 2 Unicode strings are NOT overlapped.
60 @retval FALSE 2 Unicode strings are overlapped.
61 **/
62 BOOLEAN
63 InternalSafeStringNoStrOverlap (
64 IN CHAR16 *Str1,
65 IN UINTN Size1,
66 IN CHAR16 *Str2,
67 IN UINTN Size2
68 )
69 {
70 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
71 }
72
73 /**
74 Returns if 2 Ascii strings are not overlapped.
75
76 @param Str1 Start address of 1st Ascii string.
77 @param Size1 The number of char in 1st Ascii string,
78 including terminating null char.
79 @param Str2 Start address of 2nd Ascii string.
80 @param Size2 The number of char in 2nd Ascii string,
81 including terminating null char.
82
83 @retval TRUE 2 Ascii strings are NOT overlapped.
84 @retval FALSE 2 Ascii strings are overlapped.
85 **/
86 BOOLEAN
87 InternalSafeStringNoAsciiStrOverlap (
88 IN CHAR8 *Str1,
89 IN UINTN Size1,
90 IN CHAR8 *Str2,
91 IN UINTN Size2
92 )
93 {
94 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);
95 }
96
97 /**
98 Returns the length of a Null-terminated Unicode string.
99
100 This function is similar as strlen_s defined in C11.
101
102 If String is not aligned on a 16-bit boundary, then ASSERT().
103
104 @param String A pointer to a Null-terminated Unicode string.
105 @param MaxSize The maximum number of Destination Unicode
106 char, including terminating null char.
107
108 @retval 0 If String is NULL.
109 @retval MaxSize If there is no null character in the first MaxSize characters of String.
110 @return The number of characters that percede the terminating null character.
111
112 **/
113 UINTN
114 EFIAPI
115 StrnLenS (
116 IN CONST CHAR16 *String,
117 IN UINTN MaxSize
118 )
119 {
120 UINTN Length;
121
122 ASSERT (((UINTN) String & BIT0) == 0);
123
124 //
125 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
126 //
127 if ((String == NULL) || (MaxSize == 0)) {
128 return 0;
129 }
130
131 //
132 // Otherwise, the StrnLenS function returns the number of characters that precede the
133 // terminating null character. If there is no null character in the first MaxSize characters of
134 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
135 // be accessed by StrnLenS.
136 //
137 Length = 0;
138 while (String[Length] != 0) {
139 if (Length >= MaxSize - 1) {
140 return MaxSize;
141 }
142 Length++;
143 }
144 return Length;
145 }
146
147 /**
148 Returns the size of a Null-terminated Unicode string in bytes, including the
149 Null terminator.
150
151 This function returns the size of the Null-terminated Unicode string
152 specified by String in bytes, including the Null terminator.
153
154 If String is not aligned on a 16-bit boundary, then ASSERT().
155
156 @param String A pointer to a Null-terminated Unicode string.
157 @param MaxSize The maximum number of Destination Unicode
158 char, including the Null terminator.
159
160 @retval 0 If String is NULL.
161 @retval (sizeof (CHAR16) * (MaxSize + 1))
162 If there is no Null terminator in the first MaxSize characters of
163 String.
164 @return The size of the Null-terminated Unicode string in bytes, including
165 the Null terminator.
166
167 **/
168 UINTN
169 EFIAPI
170 StrnSizeS (
171 IN CONST CHAR16 *String,
172 IN UINTN MaxSize
173 )
174 {
175 //
176 // If String is a null pointer, then the StrnSizeS function returns zero.
177 //
178 if (String == NULL) {
179 return 0;
180 }
181
182 //
183 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
184 // Unicode string in bytes, including the Null terminator. If there is no
185 // Null terminator in the first MaxSize characters of String, then StrnSizeS
186 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
187 // the StrnLenS function.
188 //
189 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);
190 }
191
192 /**
193 Copies the string pointed to by Source (including the terminating null char)
194 to the array pointed to by Destination.
195
196 This function is similar as strcpy_s defined in C11.
197
198 If Destination is not aligned on a 16-bit boundary, then ASSERT().
199 If Source is not aligned on a 16-bit boundary, then ASSERT().
200 If an error would be returned, then the function will also ASSERT().
201
202 If an error is returned, then the Destination is unmodified.
203
204 @param Destination A pointer to a Null-terminated Unicode string.
205 @param DestMax The maximum number of Destination Unicode
206 char, including terminating null char.
207 @param Source A pointer to a Null-terminated Unicode string.
208
209 @retval RETURN_SUCCESS String is copied.
210 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
211 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
212 If Source is NULL.
213 If PcdMaximumUnicodeStringLength is not zero,
214 and DestMax is greater than
215 PcdMaximumUnicodeStringLength.
216 If DestMax is 0.
217 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
218 **/
219 RETURN_STATUS
220 EFIAPI
221 StrCpyS (
222 OUT CHAR16 *Destination,
223 IN UINTN DestMax,
224 IN CONST CHAR16 *Source
225 )
226 {
227 UINTN SourceLen;
228
229 ASSERT (((UINTN) Destination & BIT0) == 0);
230 ASSERT (((UINTN) Source & BIT0) == 0);
231
232 //
233 // 1. Neither Destination nor Source shall be a null pointer.
234 //
235 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
236 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
237
238 //
239 // 2. DestMax shall not be greater than RSIZE_MAX.
240 //
241 if (RSIZE_MAX != 0) {
242 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
243 }
244
245 //
246 // 3. DestMax shall not equal zero.
247 //
248 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
249
250 //
251 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
252 //
253 SourceLen = StrnLenS (Source, DestMax);
254 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
255
256 //
257 // 5. Copying shall not take place between objects that overlap.
258 //
259 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
260
261 //
262 // The StrCpyS function copies the string pointed to by Source (including the terminating
263 // null character) into the array pointed to by Destination.
264 //
265 while (*Source != 0) {
266 *(Destination++) = *(Source++);
267 }
268 *Destination = 0;
269
270 return RETURN_SUCCESS;
271 }
272
273 /**
274 Copies not more than Length successive char from the string pointed to by
275 Source to the array pointed to by Destination. If no null char is copied from
276 Source, then Destination[Length] is always set to null.
277
278 This function is similar as strncpy_s defined in C11.
279
280 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
281 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
282 If an error would be returned, then the function will also ASSERT().
283
284 If an error is returned, then the Destination is unmodified.
285
286 @param Destination A pointer to a Null-terminated Unicode string.
287 @param DestMax The maximum number of Destination Unicode
288 char, including terminating null char.
289 @param Source A pointer to a Null-terminated Unicode string.
290 @param Length The maximum number of Unicode characters to copy.
291
292 @retval RETURN_SUCCESS String is copied.
293 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
294 MIN(StrLen(Source), Length).
295 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
296 If Source is NULL.
297 If PcdMaximumUnicodeStringLength is not zero,
298 and DestMax is greater than
299 PcdMaximumUnicodeStringLength.
300 If DestMax is 0.
301 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
302 **/
303 RETURN_STATUS
304 EFIAPI
305 StrnCpyS (
306 OUT CHAR16 *Destination,
307 IN UINTN DestMax,
308 IN CONST CHAR16 *Source,
309 IN UINTN Length
310 )
311 {
312 UINTN SourceLen;
313
314 ASSERT (((UINTN) Destination & BIT0) == 0);
315 ASSERT (((UINTN) Source & BIT0) == 0);
316
317 //
318 // 1. Neither Destination nor Source shall be a null pointer.
319 //
320 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
321 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
322
323 //
324 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
325 //
326 if (RSIZE_MAX != 0) {
327 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
328 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
329 }
330
331 //
332 // 3. DestMax shall not equal zero.
333 //
334 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
335
336 //
337 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
338 //
339 SourceLen = StrnLenS (Source, MIN (DestMax, Length));
340 if (Length >= DestMax) {
341 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
342 }
343
344 //
345 // 5. Copying shall not take place between objects that overlap.
346 //
347 if (SourceLen > Length) {
348 SourceLen = Length;
349 }
350 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
351
352 //
353 // The StrnCpyS function copies not more than Length successive characters (characters that
354 // follow a null character are not copied) from the array pointed to by Source to the array
355 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
356 // character.
357 //
358 while ((SourceLen > 0) && (*Source != 0)) {
359 *(Destination++) = *(Source++);
360 SourceLen--;
361 }
362 *Destination = 0;
363
364 return RETURN_SUCCESS;
365 }
366
367 /**
368 Appends a copy of the string pointed to by Source (including the terminating
369 null char) to the end of the string pointed to by Destination.
370
371 This function is similar as strcat_s defined in C11.
372
373 If Destination is not aligned on a 16-bit boundary, then ASSERT().
374 If Source is not aligned on a 16-bit boundary, then ASSERT().
375 If an error would be returned, then the function will also ASSERT().
376
377 If an error is returned, then the Destination is unmodified.
378
379 @param Destination A pointer to a Null-terminated Unicode string.
380 @param DestMax The maximum number of Destination Unicode
381 char, including terminating null char.
382 @param Source A pointer to a Null-terminated Unicode string.
383
384 @retval RETURN_SUCCESS String is appended.
385 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
386 StrLen(Destination).
387 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
388 greater than StrLen(Source).
389 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
390 If Source is NULL.
391 If PcdMaximumUnicodeStringLength is not zero,
392 and DestMax is greater than
393 PcdMaximumUnicodeStringLength.
394 If DestMax is 0.
395 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
396 **/
397 RETURN_STATUS
398 EFIAPI
399 StrCatS (
400 IN OUT CHAR16 *Destination,
401 IN UINTN DestMax,
402 IN CONST CHAR16 *Source
403 )
404 {
405 UINTN DestLen;
406 UINTN CopyLen;
407 UINTN SourceLen;
408
409 ASSERT (((UINTN) Destination & BIT0) == 0);
410 ASSERT (((UINTN) Source & BIT0) == 0);
411
412 //
413 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
414 //
415 DestLen = StrnLenS (Destination, DestMax);
416 CopyLen = DestMax - DestLen;
417
418 //
419 // 1. Neither Destination nor Source shall be a null pointer.
420 //
421 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
422 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
423
424 //
425 // 2. DestMax shall not be greater than RSIZE_MAX.
426 //
427 if (RSIZE_MAX != 0) {
428 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
429 }
430
431 //
432 // 3. DestMax shall not equal zero.
433 //
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
435
436 //
437 // 4. CopyLen shall not equal zero.
438 //
439 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
440
441 //
442 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
443 //
444 SourceLen = StrnLenS (Source, CopyLen);
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
446
447 //
448 // 6. Copying shall not take place between objects that overlap.
449 //
450 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
451
452 //
453 // The StrCatS function appends a copy of the string pointed to by Source (including the
454 // terminating null character) to the end of the string pointed to by Destination. The initial character
455 // from Source overwrites the null character at the end of Destination.
456 //
457 Destination = Destination + DestLen;
458 while (*Source != 0) {
459 *(Destination++) = *(Source++);
460 }
461 *Destination = 0;
462
463 return RETURN_SUCCESS;
464 }
465
466 /**
467 Appends not more than Length successive char from the string pointed to by
468 Source to the end of the string pointed to by Destination. If no null char is
469 copied from Source, then Destination[StrLen(Destination) + Length] is always
470 set to null.
471
472 This function is similar as strncat_s defined in C11.
473
474 If Destination is not aligned on a 16-bit boundary, then ASSERT().
475 If Source is not aligned on a 16-bit boundary, then ASSERT().
476 If an error would be returned, then the function will also ASSERT().
477
478 If an error is returned, then the Destination is unmodified.
479
480 @param Destination A pointer to a Null-terminated Unicode string.
481 @param DestMax The maximum number of Destination Unicode
482 char, including terminating null char.
483 @param Source A pointer to a Null-terminated Unicode string.
484 @param Length The maximum number of Unicode characters to copy.
485
486 @retval RETURN_SUCCESS String is appended.
487 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
488 StrLen(Destination).
489 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
490 greater than MIN(StrLen(Source), Length).
491 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
492 If Source is NULL.
493 If PcdMaximumUnicodeStringLength is not zero,
494 and DestMax is greater than
495 PcdMaximumUnicodeStringLength.
496 If DestMax is 0.
497 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
498 **/
499 RETURN_STATUS
500 EFIAPI
501 StrnCatS (
502 IN OUT CHAR16 *Destination,
503 IN UINTN DestMax,
504 IN CONST CHAR16 *Source,
505 IN UINTN Length
506 )
507 {
508 UINTN DestLen;
509 UINTN CopyLen;
510 UINTN SourceLen;
511
512 ASSERT (((UINTN) Destination & BIT0) == 0);
513 ASSERT (((UINTN) Source & BIT0) == 0);
514
515 //
516 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
517 //
518 DestLen = StrnLenS (Destination, DestMax);
519 CopyLen = DestMax - DestLen;
520
521 //
522 // 1. Neither Destination nor Source shall be a null pointer.
523 //
524 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
525 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
526
527 //
528 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
529 //
530 if (RSIZE_MAX != 0) {
531 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
532 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
533 }
534
535 //
536 // 3. DestMax shall not equal zero.
537 //
538 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
539
540 //
541 // 4. CopyLen shall not equal zero.
542 //
543 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
544
545 //
546 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
547 //
548 SourceLen = StrnLenS (Source, MIN (CopyLen, Length));
549 if (Length >= CopyLen) {
550 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
551 }
552
553 //
554 // 6. Copying shall not take place between objects that overlap.
555 //
556 if (SourceLen > Length) {
557 SourceLen = Length;
558 }
559 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
560
561 //
562 // The StrnCatS function appends not more than Length successive characters (characters
563 // that follow a null character are not copied) from the array pointed to by Source to the end of
564 // the string pointed to by Destination. The initial character from Source overwrites the null character at
565 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
566 // a null character.
567 //
568 Destination = Destination + DestLen;
569 while ((SourceLen > 0) && (*Source != 0)) {
570 *(Destination++) = *(Source++);
571 SourceLen--;
572 }
573 *Destination = 0;
574
575 return RETURN_SUCCESS;
576 }
577
578 /**
579 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
580
581 This function outputs a value of type UINTN by interpreting the contents of
582 the Unicode string specified by String as a decimal number. The format of the
583 input Unicode string String is:
584
585 [spaces] [decimal digits].
586
587 The valid decimal digit character is in the range [0-9]. The function will
588 ignore the pad space, which includes spaces or tab characters, before
589 [decimal digits]. The running zero in the beginning of [decimal digits] will
590 be ignored. Then, the function stops at the first character that is a not a
591 valid decimal character or a Null-terminator, whichever one comes first.
592
593 If String is NULL, then ASSERT().
594 If Data is NULL, then ASSERT().
595 If String is not aligned in a 16-bit boundary, then ASSERT().
596 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
597 PcdMaximumUnicodeStringLength Unicode characters, not including the
598 Null-terminator, then ASSERT().
599
600 If String has no valid decimal digits in the above format, then 0 is stored
601 at the location pointed to by Data.
602 If the number represented by String exceeds the range defined by UINTN, then
603 MAX_UINTN is stored at the location pointed to by Data.
604
605 If EndPointer is not NULL, a pointer to the character that stopped the scan
606 is stored at the location pointed to by EndPointer. If String has no valid
607 decimal digits right after the optional pad spaces, the value of String is
608 stored at the location pointed to by EndPointer.
609
610 @param String Pointer to a Null-terminated Unicode string.
611 @param EndPointer Pointer to character that stops scan.
612 @param Data Pointer to the converted value.
613
614 @retval RETURN_SUCCESS Value is translated from String.
615 @retval RETURN_INVALID_PARAMETER If String is NULL.
616 If Data is NULL.
617 If PcdMaximumUnicodeStringLength is not
618 zero, and String contains more than
619 PcdMaximumUnicodeStringLength Unicode
620 characters, not including the
621 Null-terminator.
622 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
623 the range defined by UINTN.
624
625 **/
626 RETURN_STATUS
627 EFIAPI
628 StrDecimalToUintnS (
629 IN CONST CHAR16 *String,
630 OUT CHAR16 **EndPointer, OPTIONAL
631 OUT UINTN *Data
632 )
633 {
634 ASSERT (((UINTN) String & BIT0) == 0);
635
636 //
637 // 1. Neither String nor Data shall be a null pointer.
638 //
639 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
640 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
641
642 //
643 // 2. The length of String shall not be greater than RSIZE_MAX.
644 //
645 if (RSIZE_MAX != 0) {
646 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
647 }
648
649 if (EndPointer != NULL) {
650 *EndPointer = (CHAR16 *) String;
651 }
652
653 //
654 // Ignore the pad spaces (space or tab)
655 //
656 while ((*String == L' ') || (*String == L'\t')) {
657 String++;
658 }
659
660 //
661 // Ignore leading Zeros after the spaces
662 //
663 while (*String == L'0') {
664 String++;
665 }
666
667 *Data = 0;
668
669 while (InternalIsDecimalDigitCharacter (*String)) {
670 //
671 // If the number represented by String overflows according to the range
672 // defined by UINTN, then MAX_UINTN is stored in *Data and
673 // RETURN_UNSUPPORTED is returned.
674 //
675 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {
676 *Data = MAX_UINTN;
677 if (EndPointer != NULL) {
678 *EndPointer = (CHAR16 *) String;
679 }
680 return RETURN_UNSUPPORTED;
681 }
682
683 *Data = *Data * 10 + (*String - L'0');
684 String++;
685 }
686
687 if (EndPointer != NULL) {
688 *EndPointer = (CHAR16 *) String;
689 }
690 return RETURN_SUCCESS;
691 }
692
693 /**
694 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
695
696 This function outputs a value of type UINT64 by interpreting the contents of
697 the Unicode string specified by String as a decimal number. The format of the
698 input Unicode string String is:
699
700 [spaces] [decimal digits].
701
702 The valid decimal digit character is in the range [0-9]. The function will
703 ignore the pad space, which includes spaces or tab characters, before
704 [decimal digits]. The running zero in the beginning of [decimal digits] will
705 be ignored. Then, the function stops at the first character that is a not a
706 valid decimal character or a Null-terminator, whichever one comes first.
707
708 If String is NULL, then ASSERT().
709 If Data is NULL, then ASSERT().
710 If String is not aligned in a 16-bit boundary, then ASSERT().
711 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
712 PcdMaximumUnicodeStringLength Unicode characters, not including the
713 Null-terminator, 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 return RETURN_UNSUPPORTED;
796 }
797
798 *Data = MultU64x32 (*Data, 10) + (*String - L'0');
799 String++;
800 }
801
802 if (EndPointer != NULL) {
803 *EndPointer = (CHAR16 *) String;
804 }
805 return RETURN_SUCCESS;
806 }
807
808 /**
809 Convert a Null-terminated Unicode hexadecimal string to a value of type
810 UINTN.
811
812 This function outputs a value of type UINTN by interpreting the contents of
813 the Unicode string specified by String as a hexadecimal number. The format of
814 the input Unicode string String is:
815
816 [spaces][zeros][x][hexadecimal digits].
817
818 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
819 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
820 If "x" appears in the input string, it must be prefixed with at least one 0.
821 The function will ignore the pad space, which includes spaces or tab
822 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
823 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
824 after [x] or the first valid hexadecimal digit. Then, the function stops at
825 the first character that is a not a valid hexadecimal character or NULL,
826 whichever one comes first.
827
828 If String is NULL, then ASSERT().
829 If Data is NULL, then ASSERT().
830 If String is not aligned in a 16-bit boundary, then ASSERT().
831 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
832 PcdMaximumUnicodeStringLength Unicode characters, not including the
833 Null-terminator, then ASSERT().
834
835 If String has no valid hexadecimal digits in the above format, then 0 is
836 stored at the location pointed to by Data.
837 If the number represented by String exceeds the range defined by UINTN, then
838 MAX_UINTN is stored at the location pointed to by Data.
839
840 If EndPointer is not NULL, a pointer to the character that stopped the scan
841 is stored at the location pointed to by EndPointer. If String has no valid
842 hexadecimal digits right after the optional pad spaces, the value of String
843 is stored at the location pointed to by EndPointer.
844
845 @param String Pointer to a Null-terminated Unicode string.
846 @param EndPointer Pointer to character that stops scan.
847 @param Data Pointer to the converted value.
848
849 @retval RETURN_SUCCESS Value is translated from String.
850 @retval RETURN_INVALID_PARAMETER If String is NULL.
851 If Data is NULL.
852 If PcdMaximumUnicodeStringLength is not
853 zero, and String contains more than
854 PcdMaximumUnicodeStringLength Unicode
855 characters, not including the
856 Null-terminator.
857 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
858 the range defined by UINTN.
859
860 **/
861 RETURN_STATUS
862 EFIAPI
863 StrHexToUintnS (
864 IN CONST CHAR16 *String,
865 OUT CHAR16 **EndPointer, OPTIONAL
866 OUT UINTN *Data
867 )
868 {
869 ASSERT (((UINTN) String & BIT0) == 0);
870
871 //
872 // 1. Neither String nor Data shall be a null pointer.
873 //
874 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
875 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
876
877 //
878 // 2. The length of String shall not be greater than RSIZE_MAX.
879 //
880 if (RSIZE_MAX != 0) {
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
882 }
883
884 if (EndPointer != NULL) {
885 *EndPointer = (CHAR16 *) String;
886 }
887
888 //
889 // Ignore the pad spaces (space or tab)
890 //
891 while ((*String == L' ') || (*String == L'\t')) {
892 String++;
893 }
894
895 //
896 // Ignore leading Zeros after the spaces
897 //
898 while (*String == L'0') {
899 String++;
900 }
901
902 if (CharToUpper (*String) == L'X') {
903 if (*(String - 1) != L'0') {
904 *Data = 0;
905 return RETURN_SUCCESS;
906 }
907 //
908 // Skip the 'X'
909 //
910 String++;
911 }
912
913 *Data = 0;
914
915 while (InternalIsHexaDecimalDigitCharacter (*String)) {
916 //
917 // If the number represented by String overflows according to the range
918 // defined by UINTN, then MAX_UINTN is stored in *Data and
919 // RETURN_UNSUPPORTED is returned.
920 //
921 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
922 *Data = MAX_UINTN;
923 if (EndPointer != NULL) {
924 *EndPointer = (CHAR16 *) String;
925 }
926 return RETURN_UNSUPPORTED;
927 }
928
929 *Data = (*Data << 4) + InternalHexCharToUintn (*String);
930 String++;
931 }
932
933 if (EndPointer != NULL) {
934 *EndPointer = (CHAR16 *) String;
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 NULL, then ASSERT().
960 If Data is NULL, then ASSERT().
961 If String is not aligned in a 16-bit boundary, then ASSERT().
962 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
963 PcdMaximumUnicodeStringLength Unicode characters, not including the
964 Null-terminator, then ASSERT().
965
966 If String has no valid hexadecimal digits in the above format, then 0 is
967 stored at the location pointed to by Data.
968 If the number represented by String exceeds the range defined by UINT64, then
969 MAX_UINT64 is stored at the location pointed to by Data.
970
971 If EndPointer is not NULL, a pointer to the character that stopped the scan
972 is stored at the location pointed to by EndPointer. If String has no valid
973 hexadecimal digits right after the optional pad spaces, the value of String
974 is stored at the location pointed to by EndPointer.
975
976 @param String Pointer to a Null-terminated Unicode string.
977 @param EndPointer Pointer to character that stops scan.
978 @param Data Pointer to the converted value.
979
980 @retval RETURN_SUCCESS Value is translated from String.
981 @retval RETURN_INVALID_PARAMETER If String is NULL.
982 If Data is NULL.
983 If PcdMaximumUnicodeStringLength is not
984 zero, and String contains more than
985 PcdMaximumUnicodeStringLength Unicode
986 characters, not including the
987 Null-terminator.
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
989 the range defined by UINT64.
990
991 **/
992 RETURN_STATUS
993 EFIAPI
994 StrHexToUint64S (
995 IN CONST CHAR16 *String,
996 OUT CHAR16 **EndPointer, OPTIONAL
997 OUT UINT64 *Data
998 )
999 {
1000 ASSERT (((UINTN) String & BIT0) == 0);
1001
1002 //
1003 // 1. Neither String nor Data shall be a null pointer.
1004 //
1005 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1006 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1007
1008 //
1009 // 2. The length of String shall not be greater than RSIZE_MAX.
1010 //
1011 if (RSIZE_MAX != 0) {
1012 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1013 }
1014
1015 if (EndPointer != NULL) {
1016 *EndPointer = (CHAR16 *) String;
1017 }
1018
1019 //
1020 // Ignore the pad spaces (space or tab)
1021 //
1022 while ((*String == L' ') || (*String == L'\t')) {
1023 String++;
1024 }
1025
1026 //
1027 // Ignore leading Zeros after the spaces
1028 //
1029 while (*String == L'0') {
1030 String++;
1031 }
1032
1033 if (CharToUpper (*String) == L'X') {
1034 if (*(String - 1) != L'0') {
1035 *Data = 0;
1036 return RETURN_SUCCESS;
1037 }
1038 //
1039 // Skip the 'X'
1040 //
1041 String++;
1042 }
1043
1044 *Data = 0;
1045
1046 while (InternalIsHexaDecimalDigitCharacter (*String)) {
1047 //
1048 // If the number represented by String overflows according to the range
1049 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1050 // RETURN_UNSUPPORTED is returned.
1051 //
1052 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {
1053 *Data = MAX_UINT64;
1054 if (EndPointer != NULL) {
1055 *EndPointer = (CHAR16 *) String;
1056 }
1057 return RETURN_UNSUPPORTED;
1058 }
1059
1060 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);
1061 String++;
1062 }
1063
1064 if (EndPointer != NULL) {
1065 *EndPointer = (CHAR16 *) String;
1066 }
1067 return RETURN_SUCCESS;
1068 }
1069
1070 /**
1071 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1072
1073 This function outputs a value of type IPv6_ADDRESS and may output a value
1074 of type UINT8 by interpreting the contents of the Unicode string specified
1075 by String. The format of the input Unicode string String is as follows:
1076
1077 X:X:X:X:X:X:X:X[/P]
1078
1079 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1080 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1081 memory address and high byte is stored in high memory address. P contains decimal
1082 digit characters in the range [0-9]. The running zero in the beginning of P will
1083 be ignored. /P is optional.
1084
1085 When /P is not in the String, the function stops at the first character that is
1086 not a valid hexadecimal digit character after eight X's are converted.
1087
1088 When /P is in the String, the function stops at the first character that is not
1089 a valid decimal digit character after P is converted.
1090
1091 "::" can be used to compress one or more groups of X when X contains only 0.
1092 The "::" can only appear once in the String.
1093
1094 If String is NULL, then ASSERT().
1095
1096 If Address is NULL, then ASSERT().
1097
1098 If String is not aligned in a 16-bit boundary, then ASSERT().
1099
1100 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1101 PcdMaximumUnicodeStringLength Unicode characters, not including the
1102 Null-terminator, then ASSERT().
1103
1104 If EndPointer is not NULL and Address is translated from String, a pointer
1105 to the character that stopped the scan is stored at the location pointed to
1106 by EndPointer.
1107
1108 @param String Pointer to a Null-terminated Unicode string.
1109 @param EndPointer Pointer to character that stops scan.
1110 @param Address Pointer to the converted IPv6 address.
1111 @param PrefixLength Pointer to the converted IPv6 address prefix
1112 length. MAX_UINT8 is returned when /P is
1113 not in the String.
1114
1115 @retval RETURN_SUCCESS Address is translated from String.
1116 @retval RETURN_INVALID_PARAMETER If String is NULL.
1117 If Data is NULL.
1118 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1119 digit characters.
1120 If String contains "::" and number of X
1121 is not less than 8.
1122 If P starts with character that is not a
1123 valid decimal digit character.
1124 If the decimal number converted from P
1125 exceeds 128.
1126
1127 **/
1128 RETURN_STATUS
1129 EFIAPI
1130 StrToIpv6Address (
1131 IN CONST CHAR16 *String,
1132 OUT CHAR16 **EndPointer, OPTIONAL
1133 OUT IPv6_ADDRESS *Address,
1134 OUT UINT8 *PrefixLength OPTIONAL
1135 )
1136 {
1137 RETURN_STATUS Status;
1138 UINTN AddressIndex;
1139 UINTN Uintn;
1140 IPv6_ADDRESS LocalAddress;
1141 UINT8 LocalPrefixLength;
1142 CONST CHAR16 *Pointer;
1143 CHAR16 *End;
1144 UINTN CompressStart;
1145 BOOLEAN ExpectPrefix;
1146
1147 LocalPrefixLength = MAX_UINT8;
1148 CompressStart = ARRAY_SIZE (Address->Addr);
1149 ExpectPrefix = FALSE;
1150
1151 ASSERT (((UINTN) String & BIT0) == 0);
1152
1153 //
1154 // 1. None of String or Guid shall be a null pointer.
1155 //
1156 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1157 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1158
1159 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1160 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1161 if (*Pointer != L':') {
1162 //
1163 // ":" or "/" should be followed by digit characters.
1164 //
1165 return RETURN_UNSUPPORTED;
1166 }
1167
1168 //
1169 // Meet second ":" after previous ":" or "/"
1170 // or meet first ":" in the beginning of String.
1171 //
1172 if (ExpectPrefix) {
1173 //
1174 // ":" shall not be after "/"
1175 //
1176 return RETURN_UNSUPPORTED;
1177 }
1178
1179 if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
1180 //
1181 // "::" can only appear once.
1182 // "::" can only appear when address is not full length.
1183 //
1184 return RETURN_UNSUPPORTED;
1185 } else {
1186 //
1187 // Remember the start of zero compressing.
1188 //
1189 CompressStart = AddressIndex;
1190 Pointer++;
1191
1192 if (CompressStart == 0) {
1193 if (*Pointer != L':') {
1194 //
1195 // Single ":" shall not be in the beginning of String.
1196 //
1197 return RETURN_UNSUPPORTED;
1198 }
1199 Pointer++;
1200 }
1201 }
1202 }
1203
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
1205 if (*Pointer == L'/') {
1206 //
1207 // Might be optional "/P" after "::".
1208 //
1209 if (CompressStart != AddressIndex) {
1210 return RETURN_UNSUPPORTED;
1211 }
1212 } else {
1213 break;
1214 }
1215 } else {
1216 if (!ExpectPrefix) {
1217 //
1218 // Get X.
1219 //
1220 Status = StrHexToUintnS (Pointer, &End, &Uintn);
1221 if (RETURN_ERROR (Status) || End - Pointer > 4) {
1222 //
1223 // Number of hexadecimal digit characters is no more than 4.
1224 //
1225 return RETURN_UNSUPPORTED;
1226 }
1227 Pointer = End;
1228 //
1229 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1230 //
1231 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
1232 LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
1233 LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
1234 AddressIndex += 2;
1235 } else {
1236 //
1237 // Get P, then exit the loop.
1238 //
1239 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
1240 if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
1241 //
1242 // Prefix length should not exceed 128.
1243 //
1244 return RETURN_UNSUPPORTED;
1245 }
1246 LocalPrefixLength = (UINT8) Uintn;
1247 Pointer = End;
1248 break;
1249 }
1250 }
1251
1252 //
1253 // Skip ':' or "/"
1254 //
1255 if (*Pointer == L'/') {
1256 ExpectPrefix = TRUE;
1257 } else if (*Pointer == L':') {
1258 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1259 //
1260 // Meet additional ":" after all 8 16-bit address
1261 //
1262 break;
1263 }
1264 } else {
1265 //
1266 // Meet other character that is not "/" or ":" after all 8 16-bit address
1267 //
1268 break;
1269 }
1270 Pointer++;
1271 }
1272
1273 if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
1274 (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
1275 ) {
1276 //
1277 // Full length of address shall not have compressing zeros.
1278 // Non-full length of address shall have compressing zeros.
1279 //
1280 return RETURN_UNSUPPORTED;
1281 }
1282 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
1283 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
1284 if (AddressIndex > CompressStart) {
1285 CopyMem (
1286 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
1287 &LocalAddress.Addr[CompressStart],
1288 AddressIndex - CompressStart
1289 );
1290 }
1291
1292 if (PrefixLength != NULL) {
1293 *PrefixLength = LocalPrefixLength;
1294 }
1295 if (EndPointer != NULL) {
1296 *EndPointer = (CHAR16 *) Pointer;
1297 }
1298
1299 return RETURN_SUCCESS;
1300 }
1301
1302 /**
1303 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1304
1305 This function outputs a value of type IPv4_ADDRESS and may output a value
1306 of type UINT8 by interpreting the contents of the Unicode string specified
1307 by String. The format of the input Unicode string String is as follows:
1308
1309 D.D.D.D[/P]
1310
1311 D and P are decimal digit characters in the range [0-9]. The running zero in
1312 the beginning of D and P will be ignored. /P is optional.
1313
1314 When /P is not in the String, the function stops at the first character that is
1315 not a valid decimal digit character after four D's are converted.
1316
1317 When /P is in the String, the function stops at the first character that is not
1318 a valid decimal digit character after P is converted.
1319
1320 If String is NULL, then ASSERT().
1321
1322 If Address is NULL, then ASSERT().
1323
1324 If String is not aligned in a 16-bit boundary, then ASSERT().
1325
1326 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1327 PcdMaximumUnicodeStringLength Unicode characters, not including the
1328 Null-terminator, then ASSERT().
1329
1330 If EndPointer is not NULL and Address is translated from String, a pointer
1331 to the character that stopped the scan is stored at the location pointed to
1332 by EndPointer.
1333
1334 @param String Pointer to a Null-terminated Unicode string.
1335 @param EndPointer Pointer to character that stops scan.
1336 @param Address Pointer to the converted IPv4 address.
1337 @param PrefixLength Pointer to the converted IPv4 address prefix
1338 length. MAX_UINT8 is returned when /P is
1339 not in the String.
1340
1341 @retval RETURN_SUCCESS Address is translated from String.
1342 @retval RETURN_INVALID_PARAMETER If String is NULL.
1343 If Data is NULL.
1344 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1345 If any decimal number converted from D
1346 exceeds 255.
1347 If the decimal number converted from P
1348 exceeds 32.
1349
1350 **/
1351 RETURN_STATUS
1352 EFIAPI
1353 StrToIpv4Address (
1354 IN CONST CHAR16 *String,
1355 OUT CHAR16 **EndPointer, OPTIONAL
1356 OUT IPv4_ADDRESS *Address,
1357 OUT UINT8 *PrefixLength OPTIONAL
1358 )
1359 {
1360 RETURN_STATUS Status;
1361 UINTN AddressIndex;
1362 UINTN Uintn;
1363 IPv4_ADDRESS LocalAddress;
1364 UINT8 LocalPrefixLength;
1365 CHAR16 *Pointer;
1366
1367 LocalPrefixLength = MAX_UINT8;
1368
1369 ASSERT (((UINTN) String & BIT0) == 0);
1370
1371 //
1372 // 1. None of String or Guid shall be a null pointer.
1373 //
1374 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1375 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
1376
1377 for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
1378 if (!InternalIsDecimalDigitCharacter (*Pointer)) {
1379 //
1380 // D or P contains invalid characters.
1381 //
1382 break;
1383 }
1384
1385 //
1386 // Get D or P.
1387 //
1388 Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);
1389 if (RETURN_ERROR (Status)) {
1390 return RETURN_UNSUPPORTED;
1391 }
1392 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1393 //
1394 // It's P.
1395 //
1396 if (Uintn > 32) {
1397 return RETURN_UNSUPPORTED;
1398 }
1399 LocalPrefixLength = (UINT8) Uintn;
1400 } else {
1401 //
1402 // It's D.
1403 //
1404 if (Uintn > MAX_UINT8) {
1405 return RETURN_UNSUPPORTED;
1406 }
1407 LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
1408 AddressIndex++;
1409 }
1410
1411 //
1412 // Check the '.' or '/', depending on the AddressIndex.
1413 //
1414 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
1415 if (*Pointer == L'/') {
1416 //
1417 // '/P' is in the String.
1418 // Skip "/" and get P in next loop.
1419 //
1420 Pointer++;
1421 } else {
1422 //
1423 // '/P' is not in the String.
1424 //
1425 break;
1426 }
1427 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1428 if (*Pointer == L'.') {
1429 //
1430 // D should be followed by '.'
1431 //
1432 Pointer++;
1433 } else {
1434 return RETURN_UNSUPPORTED;
1435 }
1436 }
1437 }
1438
1439 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
1440 return RETURN_UNSUPPORTED;
1441 }
1442
1443 CopyMem (Address, &LocalAddress, sizeof (*Address));
1444 if (PrefixLength != NULL) {
1445 *PrefixLength = LocalPrefixLength;
1446 }
1447 if (EndPointer != NULL) {
1448 *EndPointer = Pointer;
1449 }
1450
1451 return RETURN_SUCCESS;
1452 }
1453
1454 /**
1455 Convert a Null-terminated Unicode GUID string to a value of type
1456 EFI_GUID.
1457
1458 This function outputs a GUID value by interpreting the contents of
1459 the Unicode string specified by String. The format of the input
1460 Unicode string String consists of 36 characters, as follows:
1461
1462 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1463
1464 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1465 [A-F], with each pair representing a single byte hexadecimal value.
1466
1467 The mapping between String and the EFI_GUID structure is as follows:
1468 aa Data1[24:31]
1469 bb Data1[16:23]
1470 cc Data1[8:15]
1471 dd Data1[0:7]
1472 ee Data2[8:15]
1473 ff Data2[0:7]
1474 gg Data3[8:15]
1475 hh Data3[0:7]
1476 ii Data4[0:7]
1477 jj Data4[8:15]
1478 kk Data4[16:23]
1479 ll Data4[24:31]
1480 mm Data4[32:39]
1481 nn Data4[40:47]
1482 oo Data4[48:55]
1483 pp Data4[56:63]
1484
1485 If String is NULL, then ASSERT().
1486 If Guid is NULL, then ASSERT().
1487 If String is not aligned in a 16-bit boundary, then ASSERT().
1488
1489 @param String Pointer to a Null-terminated Unicode string.
1490 @param Guid Pointer to the converted GUID.
1491
1492 @retval RETURN_SUCCESS Guid is translated from String.
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.
1494 If Data is NULL.
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.
1496
1497 **/
1498 RETURN_STATUS
1499 EFIAPI
1500 StrToGuid (
1501 IN CONST CHAR16 *String,
1502 OUT GUID *Guid
1503 )
1504 {
1505 RETURN_STATUS Status;
1506 GUID LocalGuid;
1507
1508 ASSERT (((UINTN) String & BIT0) == 0);
1509
1510 //
1511 // 1. None of String or Guid shall be a null pointer.
1512 //
1513 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
1515
1516 //
1517 // Get aabbccdd in big-endian.
1518 //
1519 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
1520 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
1521 return RETURN_UNSUPPORTED;
1522 }
1523 //
1524 // Convert big-endian to little-endian.
1525 //
1526 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
1527 String += 2 * sizeof (LocalGuid.Data1) + 1;
1528
1529 //
1530 // Get eeff in big-endian.
1531 //
1532 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
1533 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
1534 return RETURN_UNSUPPORTED;
1535 }
1536 //
1537 // Convert big-endian to little-endian.
1538 //
1539 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
1540 String += 2 * sizeof (LocalGuid.Data2) + 1;
1541
1542 //
1543 // Get gghh in big-endian.
1544 //
1545 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
1546 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
1547 return RETURN_UNSUPPORTED;
1548 }
1549 //
1550 // Convert big-endian to little-endian.
1551 //
1552 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
1553 String += 2 * sizeof (LocalGuid.Data3) + 1;
1554
1555 //
1556 // Get iijj.
1557 //
1558 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
1559 if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
1560 return RETURN_UNSUPPORTED;
1561 }
1562 String += 2 * 2 + 1;
1563
1564 //
1565 // Get kkllmmnnoopp.
1566 //
1567 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
1568 if (RETURN_ERROR (Status)) {
1569 return RETURN_UNSUPPORTED;
1570 }
1571
1572 CopyGuid (Guid, &LocalGuid);
1573 return RETURN_SUCCESS;
1574 }
1575
1576 /**
1577 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1578
1579 This function outputs a byte array by interpreting the contents of
1580 the Unicode string specified by String in hexadecimal format. The format of
1581 the input Unicode string String is:
1582
1583 [XX]*
1584
1585 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1586 The function decodes every two hexadecimal digit characters as one byte. The
1587 decoding stops after Length of characters and outputs Buffer containing
1588 (Length / 2) bytes.
1589
1590 If String is not aligned in a 16-bit boundary, then ASSERT().
1591
1592 If String is NULL, then ASSERT().
1593
1594 If Buffer is NULL, then ASSERT().
1595
1596 If Length is not multiple of 2, then ASSERT().
1597
1598 If PcdMaximumUnicodeStringLength is not zero and Length is greater than
1599 PcdMaximumUnicodeStringLength, then ASSERT().
1600
1601 If MaxBufferSize is less than (Length / 2), then ASSERT().
1602
1603 @param String Pointer to a Null-terminated Unicode string.
1604 @param Length The number of Unicode characters to decode.
1605 @param Buffer Pointer to the converted bytes array.
1606 @param MaxBufferSize The maximum size of Buffer.
1607
1608 @retval RETURN_SUCCESS Buffer is translated from String.
1609 @retval RETURN_INVALID_PARAMETER If String is NULL.
1610 If Data is NULL.
1611 If Length is not multiple of 2.
1612 If PcdMaximumUnicodeStringLength is not zero,
1613 and Length is greater than
1614 PcdMaximumUnicodeStringLength.
1615 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1616 a character that is not valid hexadecimal
1617 digit characters, or a Null-terminator.
1618 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1619 **/
1620 RETURN_STATUS
1621 EFIAPI
1622 StrHexToBytes (
1623 IN CONST CHAR16 *String,
1624 IN UINTN Length,
1625 OUT UINT8 *Buffer,
1626 IN UINTN MaxBufferSize
1627 )
1628 {
1629 UINTN Index;
1630
1631 ASSERT (((UINTN) String & BIT0) == 0);
1632
1633 //
1634 // 1. None of String or Buffer shall be a null pointer.
1635 //
1636 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1637 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
1638
1639 //
1640 // 2. Length shall not be greater than RSIZE_MAX.
1641 //
1642 if (RSIZE_MAX != 0) {
1643 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1644 }
1645
1646 //
1647 // 3. Length shall not be odd.
1648 //
1649 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
1650
1651 //
1652 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1653 //
1654 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
1655
1656 //
1657 // 5. String shall not contains invalid hexadecimal digits.
1658 //
1659 for (Index = 0; Index < Length; Index++) {
1660 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
1661 break;
1662 }
1663 }
1664 if (Index != Length) {
1665 return RETURN_UNSUPPORTED;
1666 }
1667
1668 //
1669 // Convert the hex string to bytes.
1670 //
1671 for(Index = 0; Index < Length; Index++) {
1672
1673 //
1674 // For even characters, write the upper nibble for each buffer byte,
1675 // and for even characters, the lower nibble.
1676 //
1677 if ((Index & BIT0) == 0) {
1678 Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
1679 } else {
1680 Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
1681 }
1682 }
1683 return RETURN_SUCCESS;
1684 }
1685
1686 /**
1687 Returns the length of a Null-terminated Ascii string.
1688
1689 This function is similar as strlen_s defined in C11.
1690
1691 @param String A pointer to a Null-terminated Ascii string.
1692 @param MaxSize The maximum number of Destination Ascii
1693 char, including terminating null char.
1694
1695 @retval 0 If String is NULL.
1696 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1697 @return The number of characters that percede the terminating null character.
1698
1699 **/
1700 UINTN
1701 EFIAPI
1702 AsciiStrnLenS (
1703 IN CONST CHAR8 *String,
1704 IN UINTN MaxSize
1705 )
1706 {
1707 UINTN Length;
1708
1709 //
1710 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1711 //
1712 if ((String == NULL) || (MaxSize == 0)) {
1713 return 0;
1714 }
1715
1716 //
1717 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1718 // terminating null character. If there is no null character in the first MaxSize characters of
1719 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1720 // be accessed by AsciiStrnLenS.
1721 //
1722 Length = 0;
1723 while (String[Length] != 0) {
1724 if (Length >= MaxSize - 1) {
1725 return MaxSize;
1726 }
1727 Length++;
1728 }
1729 return Length;
1730 }
1731
1732 /**
1733 Returns the size of a Null-terminated Ascii string in bytes, including the
1734 Null terminator.
1735
1736 This function returns the size of the Null-terminated Ascii string specified
1737 by String in bytes, including the Null terminator.
1738
1739 @param String A pointer to a Null-terminated Ascii string.
1740 @param MaxSize The maximum number of Destination Ascii
1741 char, including the Null terminator.
1742
1743 @retval 0 If String is NULL.
1744 @retval (sizeof (CHAR8) * (MaxSize + 1))
1745 If there is no Null terminator in the first MaxSize characters of
1746 String.
1747 @return The size of the Null-terminated Ascii string in bytes, including the
1748 Null terminator.
1749
1750 **/
1751 UINTN
1752 EFIAPI
1753 AsciiStrnSizeS (
1754 IN CONST CHAR8 *String,
1755 IN UINTN MaxSize
1756 )
1757 {
1758 //
1759 // If String is a null pointer, then the AsciiStrnSizeS function returns
1760 // zero.
1761 //
1762 if (String == NULL) {
1763 return 0;
1764 }
1765
1766 //
1767 // Otherwise, the AsciiStrnSizeS function returns the size of the
1768 // Null-terminated Ascii string in bytes, including the Null terminator. If
1769 // there is no Null terminator in the first MaxSize characters of String,
1770 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1771 // consistent map with the AsciiStrnLenS function.
1772 //
1773 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
1774 }
1775
1776 /**
1777 Copies the string pointed to by Source (including the terminating null char)
1778 to the array pointed to by Destination.
1779
1780 This function is similar as strcpy_s defined in C11.
1781
1782 If an error would be returned, then the function will also ASSERT().
1783
1784 If an error is returned, then the Destination is unmodified.
1785
1786 @param Destination A pointer to a Null-terminated Ascii string.
1787 @param DestMax The maximum number of Destination Ascii
1788 char, including terminating null char.
1789 @param Source A pointer to a Null-terminated Ascii string.
1790
1791 @retval RETURN_SUCCESS String is copied.
1792 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1793 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1794 If Source is NULL.
1795 If PcdMaximumAsciiStringLength is not zero,
1796 and DestMax is greater than
1797 PcdMaximumAsciiStringLength.
1798 If DestMax is 0.
1799 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1800 **/
1801 RETURN_STATUS
1802 EFIAPI
1803 AsciiStrCpyS (
1804 OUT CHAR8 *Destination,
1805 IN UINTN DestMax,
1806 IN CONST CHAR8 *Source
1807 )
1808 {
1809 UINTN SourceLen;
1810
1811 //
1812 // 1. Neither Destination nor Source shall be a null pointer.
1813 //
1814 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1815 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1816
1817 //
1818 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1819 //
1820 if (ASCII_RSIZE_MAX != 0) {
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1822 }
1823
1824 //
1825 // 3. DestMax shall not equal zero.
1826 //
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1828
1829 //
1830 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1831 //
1832 SourceLen = AsciiStrnLenS (Source, DestMax);
1833 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1834
1835 //
1836 // 5. Copying shall not take place between objects that overlap.
1837 //
1838 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1839
1840 //
1841 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1842 // null character) into the array pointed to by Destination.
1843 //
1844 while (*Source != 0) {
1845 *(Destination++) = *(Source++);
1846 }
1847 *Destination = 0;
1848
1849 return RETURN_SUCCESS;
1850 }
1851
1852 /**
1853 Copies not more than Length successive char from the string pointed to by
1854 Source to the array pointed to by Destination. If no null char is copied from
1855 Source, then Destination[Length] is always set to null.
1856
1857 This function is similar as strncpy_s defined in C11.
1858
1859 If an error would be returned, then the function will also ASSERT().
1860
1861 If an error is returned, then the Destination is unmodified.
1862
1863 @param Destination A pointer to a Null-terminated Ascii string.
1864 @param DestMax The maximum number of Destination Ascii
1865 char, including terminating null char.
1866 @param Source A pointer to a Null-terminated Ascii string.
1867 @param Length The maximum number of Ascii characters to copy.
1868
1869 @retval RETURN_SUCCESS String is copied.
1870 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1871 MIN(StrLen(Source), Length).
1872 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1873 If Source is NULL.
1874 If PcdMaximumAsciiStringLength is not zero,
1875 and DestMax is greater than
1876 PcdMaximumAsciiStringLength.
1877 If DestMax is 0.
1878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1879 **/
1880 RETURN_STATUS
1881 EFIAPI
1882 AsciiStrnCpyS (
1883 OUT CHAR8 *Destination,
1884 IN UINTN DestMax,
1885 IN CONST CHAR8 *Source,
1886 IN UINTN Length
1887 )
1888 {
1889 UINTN SourceLen;
1890
1891 //
1892 // 1. Neither Destination nor Source shall be a null pointer.
1893 //
1894 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1895 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1896
1897 //
1898 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1899 //
1900 if (ASCII_RSIZE_MAX != 0) {
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1902 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1903 }
1904
1905 //
1906 // 3. DestMax shall not equal zero.
1907 //
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1909
1910 //
1911 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1912 //
1913 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));
1914 if (Length >= DestMax) {
1915 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1916 }
1917
1918 //
1919 // 5. Copying shall not take place between objects that overlap.
1920 //
1921 if (SourceLen > Length) {
1922 SourceLen = Length;
1923 }
1924 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1925
1926 //
1927 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1928 // follow a null character are not copied) from the array pointed to by Source to the array
1929 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1930 // character.
1931 //
1932 while ((SourceLen > 0) && (*Source != 0)) {
1933 *(Destination++) = *(Source++);
1934 SourceLen--;
1935 }
1936 *Destination = 0;
1937
1938 return RETURN_SUCCESS;
1939 }
1940
1941 /**
1942 Appends a copy of the string pointed to by Source (including the terminating
1943 null char) to the end of the string pointed to by Destination.
1944
1945 This function is similar as strcat_s defined in C11.
1946
1947 If an error would be returned, then the function will also ASSERT().
1948
1949 If an error is returned, then the Destination is unmodified.
1950
1951 @param Destination A pointer to a Null-terminated Ascii string.
1952 @param DestMax The maximum number of Destination Ascii
1953 char, including terminating null char.
1954 @param Source A pointer to a Null-terminated Ascii string.
1955
1956 @retval RETURN_SUCCESS String is appended.
1957 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1958 StrLen(Destination).
1959 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1960 greater than StrLen(Source).
1961 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1962 If Source is NULL.
1963 If PcdMaximumAsciiStringLength is not zero,
1964 and DestMax is greater than
1965 PcdMaximumAsciiStringLength.
1966 If DestMax is 0.
1967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1968 **/
1969 RETURN_STATUS
1970 EFIAPI
1971 AsciiStrCatS (
1972 IN OUT CHAR8 *Destination,
1973 IN UINTN DestMax,
1974 IN CONST CHAR8 *Source
1975 )
1976 {
1977 UINTN DestLen;
1978 UINTN CopyLen;
1979 UINTN SourceLen;
1980
1981 //
1982 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1983 //
1984 DestLen = AsciiStrnLenS (Destination, DestMax);
1985 CopyLen = DestMax - DestLen;
1986
1987 //
1988 // 1. Neither Destination nor Source shall be a null pointer.
1989 //
1990 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1991 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1992
1993 //
1994 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1995 //
1996 if (ASCII_RSIZE_MAX != 0) {
1997 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1998 }
1999
2000 //
2001 // 3. DestMax shall not equal zero.
2002 //
2003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2004
2005 //
2006 // 4. CopyLen shall not equal zero.
2007 //
2008 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2009
2010 //
2011 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2012 //
2013 SourceLen = AsciiStrnLenS (Source, CopyLen);
2014 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2015
2016 //
2017 // 6. Copying shall not take place between objects that overlap.
2018 //
2019 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2020
2021 //
2022 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2023 // terminating null character) to the end of the string pointed to by Destination. The initial character
2024 // from Source overwrites the null character at the end of Destination.
2025 //
2026 Destination = Destination + DestLen;
2027 while (*Source != 0) {
2028 *(Destination++) = *(Source++);
2029 }
2030 *Destination = 0;
2031
2032 return RETURN_SUCCESS;
2033 }
2034
2035 /**
2036 Appends not more than Length successive char from the string pointed to by
2037 Source to the end of the string pointed to by Destination. If no null char is
2038 copied from Source, then Destination[StrLen(Destination) + Length] is always
2039 set to null.
2040
2041 This function is similar as strncat_s defined in C11.
2042
2043 If an error would be returned, then the function will also ASSERT().
2044
2045 If an error is returned, then the Destination is unmodified.
2046
2047 @param Destination A pointer to a Null-terminated Ascii string.
2048 @param DestMax The maximum number of Destination Ascii
2049 char, including terminating null char.
2050 @param Source A pointer to a Null-terminated Ascii string.
2051 @param Length The maximum number of Ascii characters to copy.
2052
2053 @retval RETURN_SUCCESS String is appended.
2054 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
2055 StrLen(Destination).
2056 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
2057 greater than MIN(StrLen(Source), Length).
2058 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2059 If Source is NULL.
2060 If PcdMaximumAsciiStringLength is not zero,
2061 and DestMax is greater than
2062 PcdMaximumAsciiStringLength.
2063 If DestMax is 0.
2064 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2065 **/
2066 RETURN_STATUS
2067 EFIAPI
2068 AsciiStrnCatS (
2069 IN OUT CHAR8 *Destination,
2070 IN UINTN DestMax,
2071 IN CONST CHAR8 *Source,
2072 IN UINTN Length
2073 )
2074 {
2075 UINTN DestLen;
2076 UINTN CopyLen;
2077 UINTN SourceLen;
2078
2079 //
2080 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2081 //
2082 DestLen = AsciiStrnLenS (Destination, DestMax);
2083 CopyLen = DestMax - DestLen;
2084
2085 //
2086 // 1. Neither Destination nor Source shall be a null pointer.
2087 //
2088 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2089 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2090
2091 //
2092 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2093 //
2094 if (ASCII_RSIZE_MAX != 0) {
2095 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2096 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2097 }
2098
2099 //
2100 // 3. DestMax shall not equal zero.
2101 //
2102 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2103
2104 //
2105 // 4. CopyLen shall not equal zero.
2106 //
2107 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
2108
2109 //
2110 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2111 //
2112 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));
2113 if (Length >= CopyLen) {
2114 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
2115 }
2116
2117 //
2118 // 6. Copying shall not take place between objects that overlap.
2119 //
2120 if (SourceLen > Length) {
2121 SourceLen = Length;
2122 }
2123 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2124
2125 //
2126 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2127 // that follow a null character are not copied) from the array pointed to by Source to the end of
2128 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2129 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2130 // a null character.
2131 //
2132 Destination = Destination + DestLen;
2133 while ((SourceLen > 0) && (*Source != 0)) {
2134 *(Destination++) = *(Source++);
2135 SourceLen--;
2136 }
2137 *Destination = 0;
2138
2139 return RETURN_SUCCESS;
2140 }
2141
2142 /**
2143 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2144
2145 This function outputs a value of type UINTN by interpreting the contents of
2146 the Ascii string specified by String as a decimal number. The format of the
2147 input Ascii string String is:
2148
2149 [spaces] [decimal digits].
2150
2151 The valid decimal digit character is in the range [0-9]. The function will
2152 ignore the pad space, which includes spaces or tab characters, before
2153 [decimal digits]. The running zero in the beginning of [decimal digits] will
2154 be ignored. Then, the function stops at the first character that is a not a
2155 valid decimal character or a Null-terminator, whichever one comes first.
2156
2157 If String is NULL, then ASSERT().
2158 If Data is NULL, then ASSERT().
2159 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2160 PcdMaximumAsciiStringLength Ascii characters, not including the
2161 Null-terminator, then ASSERT().
2162
2163 If String has no valid decimal digits in the above format, then 0 is stored
2164 at the location pointed to by Data.
2165 If the number represented by String exceeds the range defined by UINTN, then
2166 MAX_UINTN is stored at the location pointed to by Data.
2167
2168 If EndPointer is not NULL, a pointer to the character that stopped the scan
2169 is stored at the location pointed to by EndPointer. If String has no valid
2170 decimal digits right after the optional pad spaces, the value of String is
2171 stored at the location pointed to by EndPointer.
2172
2173 @param String Pointer to a Null-terminated Ascii string.
2174 @param EndPointer Pointer to character that stops scan.
2175 @param Data Pointer to the converted value.
2176
2177 @retval RETURN_SUCCESS Value is translated from String.
2178 @retval RETURN_INVALID_PARAMETER If String is NULL.
2179 If Data is NULL.
2180 If PcdMaximumAsciiStringLength is not zero,
2181 and String contains more than
2182 PcdMaximumAsciiStringLength Ascii
2183 characters, not including the
2184 Null-terminator.
2185 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2186 the range defined by UINTN.
2187
2188 **/
2189 RETURN_STATUS
2190 EFIAPI
2191 AsciiStrDecimalToUintnS (
2192 IN CONST CHAR8 *String,
2193 OUT CHAR8 **EndPointer, OPTIONAL
2194 OUT UINTN *Data
2195 )
2196 {
2197 //
2198 // 1. Neither String nor Data shall be a null pointer.
2199 //
2200 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2201 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2202
2203 //
2204 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2205 //
2206 if (ASCII_RSIZE_MAX != 0) {
2207 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2208 }
2209
2210 if (EndPointer != NULL) {
2211 *EndPointer = (CHAR8 *) String;
2212 }
2213
2214 //
2215 // Ignore the pad spaces (space or tab)
2216 //
2217 while ((*String == ' ') || (*String == '\t')) {
2218 String++;
2219 }
2220
2221 //
2222 // Ignore leading Zeros after the spaces
2223 //
2224 while (*String == '0') {
2225 String++;
2226 }
2227
2228 *Data = 0;
2229
2230 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2231 //
2232 // If the number represented by String overflows according to the range
2233 // defined by UINTN, then MAX_UINTN is stored in *Data and
2234 // RETURN_UNSUPPORTED is returned.
2235 //
2236 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {
2237 *Data = MAX_UINTN;
2238 if (EndPointer != NULL) {
2239 *EndPointer = (CHAR8 *) String;
2240 }
2241 return RETURN_UNSUPPORTED;
2242 }
2243
2244 *Data = *Data * 10 + (*String - '0');
2245 String++;
2246 }
2247
2248 if (EndPointer != NULL) {
2249 *EndPointer = (CHAR8 *) String;
2250 }
2251 return RETURN_SUCCESS;
2252 }
2253
2254 /**
2255 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2256
2257 This function outputs a value of type UINT64 by interpreting the contents of
2258 the Ascii string specified by String as a decimal number. The format of the
2259 input Ascii string String is:
2260
2261 [spaces] [decimal digits].
2262
2263 The valid decimal digit character is in the range [0-9]. The function will
2264 ignore the pad space, which includes spaces or tab characters, before
2265 [decimal digits]. The running zero in the beginning of [decimal digits] will
2266 be ignored. Then, the function stops at the first character that is a not a
2267 valid decimal character or a Null-terminator, whichever one comes first.
2268
2269 If String is NULL, then ASSERT().
2270 If Data is NULL, then ASSERT().
2271 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2272 PcdMaximumAsciiStringLength Ascii characters, not including the
2273 Null-terminator, then ASSERT().
2274
2275 If String has no valid decimal digits in the above format, then 0 is stored
2276 at the location pointed to by Data.
2277 If the number represented by String exceeds the range defined by UINT64, then
2278 MAX_UINT64 is stored at the location pointed to by Data.
2279
2280 If EndPointer is not NULL, a pointer to the character that stopped the scan
2281 is stored at the location pointed to by EndPointer. If String has no valid
2282 decimal digits right after the optional pad spaces, the value of String is
2283 stored at the location pointed to by EndPointer.
2284
2285 @param String Pointer to a Null-terminated Ascii string.
2286 @param EndPointer Pointer to character that stops scan.
2287 @param Data Pointer to the converted value.
2288
2289 @retval RETURN_SUCCESS Value is translated from String.
2290 @retval RETURN_INVALID_PARAMETER If String is NULL.
2291 If Data is NULL.
2292 If PcdMaximumAsciiStringLength is not zero,
2293 and String contains more than
2294 PcdMaximumAsciiStringLength Ascii
2295 characters, not including the
2296 Null-terminator.
2297 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2298 the range defined by UINT64.
2299
2300 **/
2301 RETURN_STATUS
2302 EFIAPI
2303 AsciiStrDecimalToUint64S (
2304 IN CONST CHAR8 *String,
2305 OUT CHAR8 **EndPointer, OPTIONAL
2306 OUT UINT64 *Data
2307 )
2308 {
2309 //
2310 // 1. Neither String nor Data shall be a null pointer.
2311 //
2312 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2313 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2314
2315 //
2316 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2317 //
2318 if (ASCII_RSIZE_MAX != 0) {
2319 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2320 }
2321
2322 if (EndPointer != NULL) {
2323 *EndPointer = (CHAR8 *) String;
2324 }
2325
2326 //
2327 // Ignore the pad spaces (space or tab)
2328 //
2329 while ((*String == ' ') || (*String == '\t')) {
2330 String++;
2331 }
2332
2333 //
2334 // Ignore leading Zeros after the spaces
2335 //
2336 while (*String == '0') {
2337 String++;
2338 }
2339
2340 *Data = 0;
2341
2342 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
2343 //
2344 // If the number represented by String overflows according to the range
2345 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2346 // RETURN_UNSUPPORTED is returned.
2347 //
2348 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {
2349 *Data = MAX_UINT64;
2350 if (EndPointer != NULL) {
2351 *EndPointer = (CHAR8 *) String;
2352 }
2353 return RETURN_UNSUPPORTED;
2354 }
2355
2356 *Data = MultU64x32 (*Data, 10) + (*String - '0');
2357 String++;
2358 }
2359
2360 if (EndPointer != NULL) {
2361 *EndPointer = (CHAR8 *) String;
2362 }
2363 return RETURN_SUCCESS;
2364 }
2365
2366 /**
2367 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2368
2369 This function outputs a value of type UINTN by interpreting the contents of
2370 the Ascii string specified by String as a hexadecimal number. The format of
2371 the input Ascii string String is:
2372
2373 [spaces][zeros][x][hexadecimal digits].
2374
2375 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2376 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2377 "x" appears in the input string, it must be prefixed with at least one 0. The
2378 function will ignore the pad space, which includes spaces or tab characters,
2379 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2380 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2381 the first valid hexadecimal digit. Then, the function stops at the first
2382 character that is a not a valid hexadecimal character or Null-terminator,
2383 whichever on comes first.
2384
2385 If String is NULL, then ASSERT().
2386 If Data is NULL, then ASSERT().
2387 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2388 PcdMaximumAsciiStringLength Ascii characters, not including the
2389 Null-terminator, then ASSERT().
2390
2391 If String has no valid hexadecimal digits in the above format, then 0 is
2392 stored at the location pointed to by Data.
2393 If the number represented by String exceeds the range defined by UINTN, then
2394 MAX_UINTN is stored at the location pointed to by Data.
2395
2396 If EndPointer is not NULL, a pointer to the character that stopped the scan
2397 is stored at the location pointed to by EndPointer. If String has no valid
2398 hexadecimal digits right after the optional pad spaces, the value of String
2399 is stored at the location pointed to by EndPointer.
2400
2401 @param String Pointer to a Null-terminated Ascii string.
2402 @param EndPointer Pointer to character that stops scan.
2403 @param Data Pointer to the converted value.
2404
2405 @retval RETURN_SUCCESS Value is translated from String.
2406 @retval RETURN_INVALID_PARAMETER If String is NULL.
2407 If Data is NULL.
2408 If PcdMaximumAsciiStringLength is not zero,
2409 and String contains more than
2410 PcdMaximumAsciiStringLength Ascii
2411 characters, not including the
2412 Null-terminator.
2413 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2414 the range defined by UINTN.
2415
2416 **/
2417 RETURN_STATUS
2418 EFIAPI
2419 AsciiStrHexToUintnS (
2420 IN CONST CHAR8 *String,
2421 OUT CHAR8 **EndPointer, OPTIONAL
2422 OUT UINTN *Data
2423 )
2424 {
2425 //
2426 // 1. Neither String nor Data shall be a null pointer.
2427 //
2428 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2429 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2430
2431 //
2432 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2433 //
2434 if (ASCII_RSIZE_MAX != 0) {
2435 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2436 }
2437
2438 if (EndPointer != NULL) {
2439 *EndPointer = (CHAR8 *) String;
2440 }
2441
2442 //
2443 // Ignore the pad spaces (space or tab)
2444 //
2445 while ((*String == ' ') || (*String == '\t')) {
2446 String++;
2447 }
2448
2449 //
2450 // Ignore leading Zeros after the spaces
2451 //
2452 while (*String == '0') {
2453 String++;
2454 }
2455
2456 if (AsciiCharToUpper (*String) == 'X') {
2457 if (*(String - 1) != '0') {
2458 *Data = 0;
2459 return RETURN_SUCCESS;
2460 }
2461 //
2462 // Skip the 'X'
2463 //
2464 String++;
2465 }
2466
2467 *Data = 0;
2468
2469 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
2470 //
2471 // If the number represented by String overflows according to the range
2472 // defined by UINTN, then MAX_UINTN is stored in *Data and
2473 // RETURN_UNSUPPORTED is returned.
2474 //
2475 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {
2476 *Data = MAX_UINTN;
2477 if (EndPointer != NULL) {
2478 *EndPointer = (CHAR8 *) String;
2479 }
2480 return RETURN_UNSUPPORTED;
2481 }
2482
2483 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);
2484 String++;
2485 }
2486
2487 if (EndPointer != NULL) {
2488 *EndPointer = (CHAR8 *) String;
2489 }
2490 return RETURN_SUCCESS;
2491 }
2492
2493 /**
2494 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2495
2496 This function outputs a value of type UINT64 by interpreting the contents of
2497 the Ascii string specified by String as a hexadecimal number. The format of
2498 the input Ascii string String is:
2499
2500 [spaces][zeros][x][hexadecimal digits].
2501
2502 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2503 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2504 "x" appears in the input string, it must be prefixed with at least one 0. The
2505 function will ignore the pad space, which includes spaces or tab characters,
2506 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2507 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2508 the first valid hexadecimal digit. Then, the function stops at the first
2509 character that is a not a valid hexadecimal character or Null-terminator,
2510 whichever on comes first.
2511
2512 If String is NULL, then ASSERT().
2513 If Data is NULL, then ASSERT().
2514 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2515 PcdMaximumAsciiStringLength Ascii characters, not including the
2516 Null-terminator, then ASSERT().
2517
2518 If String has no valid hexadecimal digits in the above format, then 0 is
2519 stored at the location pointed to by Data.
2520 If the number represented by String exceeds the range defined by UINT64, then
2521 MAX_UINT64 is stored at the location pointed to by Data.
2522
2523 If EndPointer is not NULL, a pointer to the character that stopped the scan
2524 is stored at the location pointed to by EndPointer. If String has no valid
2525 hexadecimal digits right after the optional pad spaces, the value of String
2526 is stored at the location pointed to by EndPointer.
2527
2528 @param String Pointer to a Null-terminated Ascii string.
2529 @param EndPointer Pointer to character that stops scan.
2530 @param Data Pointer to the converted value.
2531
2532 @retval RETURN_SUCCESS Value is translated from String.
2533 @retval RETURN_INVALID_PARAMETER If String is NULL.
2534 If Data is NULL.
2535 If PcdMaximumAsciiStringLength is not zero,
2536 and String contains more than
2537 PcdMaximumAsciiStringLength Ascii
2538 characters, not including the
2539 Null-terminator.
2540 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2541 the range defined by UINT64.
2542
2543 **/
2544 RETURN_STATUS
2545 EFIAPI
2546 AsciiStrHexToUint64S (
2547 IN CONST CHAR8 *String,
2548 OUT CHAR8 **EndPointer, OPTIONAL
2549 OUT UINT64 *Data
2550 )
2551 {
2552 //
2553 // 1. Neither String nor Data shall be a null pointer.
2554 //
2555 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
2556 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
2557
2558 //
2559 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2560 //
2561 if (ASCII_RSIZE_MAX != 0) {
2562 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2563 }
2564
2565 if (EndPointer != NULL) {
2566 *EndPointer = (CHAR8 *) String;
2567 }
2568
2569 //
2570 // Ignore the pad spaces (space or tab)
2571 //
2572 while ((*String == ' ') || (*String == '\t')) {
2573 String++;
2574 }
2575
2576 //
2577 // Ignore leading Zeros after the spaces
2578 //
2579 while (*String == '0') {
2580 String++;
2581 }
2582
2583 if (AsciiCharToUpper (*String) == 'X') {
2584 if (*(String - 1) != '0') {
2585 *Data = 0;
2586 return RETURN_SUCCESS;
2587 }
2588 //
2589 // Skip the 'X'
2590 //
2591 String++;
2592 }
2593
2594 *Data = 0;
2595
2596 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
2597 //
2598 // If the number represented by String overflows according to the range
2599 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2600 // RETURN_UNSUPPORTED is returned.
2601 //
2602 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {
2603 *Data = MAX_UINT64;
2604 if (EndPointer != NULL) {
2605 *EndPointer = (CHAR8 *) String;
2606 }
2607 return RETURN_UNSUPPORTED;
2608 }
2609
2610 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);
2611 String++;
2612 }
2613
2614 if (EndPointer != NULL) {
2615 *EndPointer = (CHAR8 *) String;
2616 }
2617 return RETURN_SUCCESS;
2618 }
2619
2620 /**
2621 Convert a Null-terminated Unicode string to a Null-terminated
2622 ASCII string.
2623
2624 This function is similar to AsciiStrCpyS.
2625
2626 This function converts the content of the Unicode string Source
2627 to the ASCII string Destination by copying the lower 8 bits of
2628 each Unicode character. The function terminates the ASCII string
2629 Destination by appending a Null-terminator character at the end.
2630
2631 The caller is responsible to make sure Destination points to a buffer with size
2632 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2633
2634 If any Unicode characters in Source contain non-zero value in
2635 the upper 8 bits, then ASSERT().
2636
2637 If Source is not aligned on a 16-bit boundary, then ASSERT().
2638 If an error would be returned, then the function will also ASSERT().
2639
2640 If an error is returned, then the Destination is unmodified.
2641
2642 @param Source The pointer to a Null-terminated Unicode string.
2643 @param Destination The pointer to a Null-terminated ASCII string.
2644 @param DestMax The maximum number of Destination Ascii
2645 char, including terminating null char.
2646
2647 @retval RETURN_SUCCESS String is converted.
2648 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2649 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2650 If Source is NULL.
2651 If PcdMaximumAsciiStringLength is not zero,
2652 and DestMax is greater than
2653 PcdMaximumAsciiStringLength.
2654 If PcdMaximumUnicodeStringLength is not zero,
2655 and DestMax is greater than
2656 PcdMaximumUnicodeStringLength.
2657 If DestMax is 0.
2658 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2659
2660 **/
2661 RETURN_STATUS
2662 EFIAPI
2663 UnicodeStrToAsciiStrS (
2664 IN CONST CHAR16 *Source,
2665 OUT CHAR8 *Destination,
2666 IN UINTN DestMax
2667 )
2668 {
2669 UINTN SourceLen;
2670
2671 ASSERT (((UINTN) Source & BIT0) == 0);
2672
2673 //
2674 // 1. Neither Destination nor Source shall be a null pointer.
2675 //
2676 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2677 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2678
2679 //
2680 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2681 //
2682 if (ASCII_RSIZE_MAX != 0) {
2683 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2684 }
2685 if (RSIZE_MAX != 0) {
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2687 }
2688
2689 //
2690 // 3. DestMax shall not equal zero.
2691 //
2692 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2693
2694 //
2695 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2696 //
2697 SourceLen = StrnLenS (Source, DestMax);
2698 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2699
2700 //
2701 // 5. Copying shall not take place between objects that overlap.
2702 //
2703 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
2704
2705 //
2706 // convert string
2707 //
2708 while (*Source != '\0') {
2709 //
2710 // If any Unicode characters in Source contain
2711 // non-zero value in the upper 8 bits, then ASSERT().
2712 //
2713 ASSERT (*Source < 0x100);
2714 *(Destination++) = (CHAR8) *(Source++);
2715 }
2716 *Destination = '\0';
2717
2718 return RETURN_SUCCESS;
2719 }
2720
2721 /**
2722 Convert not more than Length successive characters from a Null-terminated
2723 Unicode string to a Null-terminated Ascii string. If no null char is copied
2724 from Source, then Destination[Length] is always set to null.
2725
2726 This function converts not more than Length successive characters from the
2727 Unicode string Source to the Ascii string Destination by copying the lower 8
2728 bits of each Unicode character. The function terminates the Ascii string
2729 Destination by appending a Null-terminator character at the end.
2730
2731 The caller is responsible to make sure Destination points to a buffer with
2732 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2733 in bytes.
2734
2735 If any Unicode characters in Source contain non-zero value in the upper 8
2736 bits, then ASSERT().
2737 If Source is not aligned on a 16-bit boundary, then ASSERT().
2738 If an error would be returned, then the function will also ASSERT().
2739
2740 If an error is returned, then Destination and DestinationLength are
2741 unmodified.
2742
2743 @param Source The pointer to a Null-terminated Unicode string.
2744 @param Length The maximum number of Unicode characters to
2745 convert.
2746 @param Destination The pointer to a Null-terminated Ascii string.
2747 @param DestMax The maximum number of Destination Ascii char,
2748 including terminating null char.
2749 @param DestinationLength The number of Unicode characters converted.
2750
2751 @retval RETURN_SUCCESS String is converted.
2752 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2753 If Source is NULL.
2754 If DestinationLength is NULL.
2755 If PcdMaximumAsciiStringLength is not zero,
2756 and Length or DestMax is greater than
2757 PcdMaximumAsciiStringLength.
2758 If PcdMaximumUnicodeStringLength is not
2759 zero, and Length or DestMax is greater than
2760 PcdMaximumUnicodeStringLength.
2761 If DestMax is 0.
2762 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2763 MIN(StrLen(Source), Length).
2764 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2765
2766 **/
2767 RETURN_STATUS
2768 EFIAPI
2769 UnicodeStrnToAsciiStrS (
2770 IN CONST CHAR16 *Source,
2771 IN UINTN Length,
2772 OUT CHAR8 *Destination,
2773 IN UINTN DestMax,
2774 OUT UINTN *DestinationLength
2775 )
2776 {
2777 UINTN SourceLen;
2778
2779 ASSERT (((UINTN) Source & BIT0) == 0);
2780
2781 //
2782 // 1. None of Destination, Source or DestinationLength shall be a null
2783 // pointer.
2784 //
2785 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2786 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2787 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2788
2789 //
2790 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2791 // RSIZE_MAX.
2792 //
2793 if (ASCII_RSIZE_MAX != 0) {
2794 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2795 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2796 }
2797 if (RSIZE_MAX != 0) {
2798 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2799 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2800 }
2801
2802 //
2803 // 3. DestMax shall not equal zero.
2804 //
2805 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2806
2807 //
2808 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2809 // StrnLenS(Source, DestMax).
2810 //
2811 SourceLen = StrnLenS (Source, DestMax);
2812 if (Length >= DestMax) {
2813 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2814 }
2815
2816 //
2817 // 5. Copying shall not take place between objects that overlap.
2818 //
2819 if (SourceLen > Length) {
2820 SourceLen = Length;
2821 }
2822 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
2823
2824 *DestinationLength = 0;
2825
2826 //
2827 // Convert string
2828 //
2829 while ((*Source != 0) && (SourceLen > 0)) {
2830 //
2831 // If any Unicode characters in Source contain non-zero value in the upper
2832 // 8 bits, then ASSERT().
2833 //
2834 ASSERT (*Source < 0x100);
2835 *(Destination++) = (CHAR8) *(Source++);
2836 SourceLen--;
2837 (*DestinationLength)++;
2838 }
2839 *Destination = 0;
2840
2841 return RETURN_SUCCESS;
2842 }
2843
2844 /**
2845 Convert one Null-terminated ASCII string to a Null-terminated
2846 Unicode string.
2847
2848 This function is similar to StrCpyS.
2849
2850 This function converts the contents of the ASCII string Source to the Unicode
2851 string Destination. The function terminates the Unicode string Destination by
2852 appending a Null-terminator character at the end.
2853
2854 The caller is responsible to make sure Destination points to a buffer with size
2855 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2856
2857 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2858 If an error would be returned, then the function will also ASSERT().
2859
2860 If an error is returned, then the Destination is unmodified.
2861
2862 @param Source The pointer to a Null-terminated ASCII string.
2863 @param Destination The pointer to a Null-terminated Unicode string.
2864 @param DestMax The maximum number of Destination Unicode
2865 char, including terminating null char.
2866
2867 @retval RETURN_SUCCESS String is converted.
2868 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2869 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2870 If Source is NULL.
2871 If PcdMaximumUnicodeStringLength is not zero,
2872 and DestMax is greater than
2873 PcdMaximumUnicodeStringLength.
2874 If PcdMaximumAsciiStringLength is not zero,
2875 and DestMax is greater than
2876 PcdMaximumAsciiStringLength.
2877 If DestMax is 0.
2878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2879
2880 **/
2881 RETURN_STATUS
2882 EFIAPI
2883 AsciiStrToUnicodeStrS (
2884 IN CONST CHAR8 *Source,
2885 OUT CHAR16 *Destination,
2886 IN UINTN DestMax
2887 )
2888 {
2889 UINTN SourceLen;
2890
2891 ASSERT (((UINTN) Destination & BIT0) == 0);
2892
2893 //
2894 // 1. Neither Destination nor Source shall be a null pointer.
2895 //
2896 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2897 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2898
2899 //
2900 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2901 //
2902 if (RSIZE_MAX != 0) {
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2904 }
2905 if (ASCII_RSIZE_MAX != 0) {
2906 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2907 }
2908
2909 //
2910 // 3. DestMax shall not equal zero.
2911 //
2912 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2913
2914 //
2915 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2916 //
2917 SourceLen = AsciiStrnLenS (Source, DestMax);
2918 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2919
2920 //
2921 // 5. Copying shall not take place between objects that overlap.
2922 //
2923 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2924
2925 //
2926 // Convert string
2927 //
2928 while (*Source != '\0') {
2929 *(Destination++) = (CHAR16)(UINT8)*(Source++);
2930 }
2931 *Destination = '\0';
2932
2933 return RETURN_SUCCESS;
2934 }
2935
2936 /**
2937 Convert not more than Length successive characters from a Null-terminated
2938 Ascii string to a Null-terminated Unicode string. If no null char is copied
2939 from Source, then Destination[Length] is always set to null.
2940
2941 This function converts not more than Length successive characters from the
2942 Ascii string Source to the Unicode string Destination. The function
2943 terminates the Unicode string Destination by appending a Null-terminator
2944 character at the end.
2945
2946 The caller is responsible to make sure Destination points to a buffer with
2947 size not smaller than
2948 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2949
2950 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2951 If an error would be returned, then the function will also ASSERT().
2952
2953 If an error is returned, then Destination and DestinationLength are
2954 unmodified.
2955
2956 @param Source The pointer to a Null-terminated Ascii string.
2957 @param Length The maximum number of Ascii characters to convert.
2958 @param Destination The pointer to a Null-terminated Unicode string.
2959 @param DestMax The maximum number of Destination Unicode char,
2960 including terminating null char.
2961 @param DestinationLength The number of Ascii characters converted.
2962
2963 @retval RETURN_SUCCESS String is converted.
2964 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2965 If Source is NULL.
2966 If DestinationLength is NULL.
2967 If PcdMaximumUnicodeStringLength is not
2968 zero, and Length or DestMax is greater than
2969 PcdMaximumUnicodeStringLength.
2970 If PcdMaximumAsciiStringLength is not zero,
2971 and Length or DestMax is greater than
2972 PcdMaximumAsciiStringLength.
2973 If DestMax is 0.
2974 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2975 MIN(AsciiStrLen(Source), Length).
2976 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2977
2978 **/
2979 RETURN_STATUS
2980 EFIAPI
2981 AsciiStrnToUnicodeStrS (
2982 IN CONST CHAR8 *Source,
2983 IN UINTN Length,
2984 OUT CHAR16 *Destination,
2985 IN UINTN DestMax,
2986 OUT UINTN *DestinationLength
2987 )
2988 {
2989 UINTN SourceLen;
2990
2991 ASSERT (((UINTN) Destination & BIT0) == 0);
2992
2993 //
2994 // 1. None of Destination, Source or DestinationLength shall be a null
2995 // pointer.
2996 //
2997 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2998 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2999 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
3000
3001 //
3002 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
3003 // RSIZE_MAX.
3004 //
3005 if (RSIZE_MAX != 0) {
3006 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
3007 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
3008 }
3009 if (ASCII_RSIZE_MAX != 0) {
3010 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3011 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3012 }
3013
3014 //
3015 // 3. DestMax shall not equal zero.
3016 //
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
3018
3019 //
3020 // 4. If Length is not less than DestMax, then DestMax shall be greater than
3021 // AsciiStrnLenS(Source, DestMax).
3022 //
3023 SourceLen = AsciiStrnLenS (Source, DestMax);
3024 if (Length >= DestMax) {
3025 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
3026 }
3027
3028 //
3029 // 5. Copying shall not take place between objects that overlap.
3030 //
3031 if (SourceLen > Length) {
3032 SourceLen = Length;
3033 }
3034 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
3035
3036 *DestinationLength = 0;
3037
3038 //
3039 // Convert string
3040 //
3041 while ((*Source != 0) && (SourceLen > 0)) {
3042 *(Destination++) = (CHAR16)(UINT8)*(Source++);
3043 SourceLen--;
3044 (*DestinationLength)++;
3045 }
3046 *Destination = 0;
3047
3048 return RETURN_SUCCESS;
3049 }
3050
3051 /**
3052 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
3053
3054 This function outputs a value of type IPv6_ADDRESS and may output a value
3055 of type UINT8 by interpreting the contents of the ASCII string specified
3056 by String. The format of the input ASCII string String is as follows:
3057
3058 X:X:X:X:X:X:X:X[/P]
3059
3060 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
3061 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
3062 memory address and high byte is stored in high memory address. P contains decimal
3063 digit characters in the range [0-9]. The running zero in the beginning of P will
3064 be ignored. /P is optional.
3065
3066 When /P is not in the String, the function stops at the first character that is
3067 not a valid hexadecimal digit character after eight X's are converted.
3068
3069 When /P is in the String, the function stops at the first character that is not
3070 a valid decimal digit character after P is converted.
3071
3072 "::" can be used to compress one or more groups of X when X contains only 0.
3073 The "::" can only appear once in the String.
3074
3075 If String is NULL, then ASSERT().
3076
3077 If Address is NULL, then ASSERT().
3078
3079 If EndPointer is not NULL and Address is translated from String, a pointer
3080 to the character that stopped the scan is stored at the location pointed to
3081 by EndPointer.
3082
3083 @param String Pointer to a Null-terminated ASCII string.
3084 @param EndPointer Pointer to character that stops scan.
3085 @param Address Pointer to the converted IPv6 address.
3086 @param PrefixLength Pointer to the converted IPv6 address prefix
3087 length. MAX_UINT8 is returned when /P is
3088 not in the String.
3089
3090 @retval RETURN_SUCCESS Address is translated from String.
3091 @retval RETURN_INVALID_PARAMETER If String is NULL.
3092 If Data is NULL.
3093 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3094 digit characters.
3095 If String contains "::" and number of X
3096 is not less than 8.
3097 If P starts with character that is not a
3098 valid decimal digit character.
3099 If the decimal number converted from P
3100 exceeds 128.
3101
3102 **/
3103 RETURN_STATUS
3104 EFIAPI
3105 AsciiStrToIpv6Address (
3106 IN CONST CHAR8 *String,
3107 OUT CHAR8 **EndPointer, OPTIONAL
3108 OUT IPv6_ADDRESS *Address,
3109 OUT UINT8 *PrefixLength OPTIONAL
3110 )
3111 {
3112 RETURN_STATUS Status;
3113 UINTN AddressIndex;
3114 UINTN Uintn;
3115 IPv6_ADDRESS LocalAddress;
3116 UINT8 LocalPrefixLength;
3117 CONST CHAR8 *Pointer;
3118 CHAR8 *End;
3119 UINTN CompressStart;
3120 BOOLEAN ExpectPrefix;
3121
3122 LocalPrefixLength = MAX_UINT8;
3123 CompressStart = ARRAY_SIZE (Address->Addr);
3124 ExpectPrefix = FALSE;
3125
3126 //
3127 // None of String or Address shall be a null pointer.
3128 //
3129 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3130 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3131
3132 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3133 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
3134 if (*Pointer != ':') {
3135 //
3136 // ":" or "/" should be followed by digit characters.
3137 //
3138 return RETURN_UNSUPPORTED;
3139 }
3140
3141 //
3142 // Meet second ":" after previous ":" or "/"
3143 // or meet first ":" in the beginning of String.
3144 //
3145 if (ExpectPrefix) {
3146 //
3147 // ":" shall not be after "/"
3148 //
3149 return RETURN_UNSUPPORTED;
3150 }
3151
3152 if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
3153 //
3154 // "::" can only appear once.
3155 // "::" can only appear when address is not full length.
3156 //
3157 return RETURN_UNSUPPORTED;
3158 } else {
3159 //
3160 // Remember the start of zero compressing.
3161 //
3162 CompressStart = AddressIndex;
3163 Pointer++;
3164
3165 if (CompressStart == 0) {
3166 if (*Pointer != ':') {
3167 //
3168 // Single ":" shall not be in the beginning of String.
3169 //
3170 return RETURN_UNSUPPORTED;
3171 }
3172 Pointer++;
3173 }
3174 }
3175 }
3176
3177 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
3178 if (*Pointer == '/') {
3179 //
3180 // Might be optional "/P" after "::".
3181 //
3182 if (CompressStart != AddressIndex) {
3183 return RETURN_UNSUPPORTED;
3184 }
3185 } else {
3186 break;
3187 }
3188 } else {
3189 if (!ExpectPrefix) {
3190 //
3191 // Get X.
3192 //
3193 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);
3194 if (RETURN_ERROR (Status) || End - Pointer > 4) {
3195 //
3196 // Number of hexadecimal digit characters is no more than 4.
3197 //
3198 return RETURN_UNSUPPORTED;
3199 }
3200 Pointer = End;
3201 //
3202 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3203 //
3204 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
3205 LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
3206 LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
3207 AddressIndex += 2;
3208 } else {
3209 //
3210 // Get P, then exit the loop.
3211 //
3212 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);
3213 if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
3214 //
3215 // Prefix length should not exceed 128.
3216 //
3217 return RETURN_UNSUPPORTED;
3218 }
3219 LocalPrefixLength = (UINT8) Uintn;
3220 Pointer = End;
3221 break;
3222 }
3223 }
3224
3225 //
3226 // Skip ':' or "/"
3227 //
3228 if (*Pointer == '/') {
3229 ExpectPrefix = TRUE;
3230 } else if (*Pointer == ':') {
3231 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3232 //
3233 // Meet additional ":" after all 8 16-bit address
3234 //
3235 break;
3236 }
3237 } else {
3238 //
3239 // Meet other character that is not "/" or ":" after all 8 16-bit address
3240 //
3241 break;
3242 }
3243 Pointer++;
3244 }
3245
3246 if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
3247 (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
3248 ) {
3249 //
3250 // Full length of address shall not have compressing zeros.
3251 // Non-full length of address shall have compressing zeros.
3252 //
3253 return RETURN_UNSUPPORTED;
3254 }
3255 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
3256 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
3257 if (AddressIndex > CompressStart) {
3258 CopyMem (
3259 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
3260 &LocalAddress.Addr[CompressStart],
3261 AddressIndex - CompressStart
3262 );
3263
3264 }
3265
3266 if (PrefixLength != NULL) {
3267 *PrefixLength = LocalPrefixLength;
3268 }
3269 if (EndPointer != NULL) {
3270 *EndPointer = (CHAR8 *) Pointer;
3271 }
3272
3273 return RETURN_SUCCESS;
3274 }
3275
3276 /**
3277 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3278
3279 This function outputs a value of type IPv4_ADDRESS and may output a value
3280 of type UINT8 by interpreting the contents of the ASCII string specified
3281 by String. The format of the input ASCII string String is as follows:
3282
3283 D.D.D.D[/P]
3284
3285 D and P are decimal digit characters in the range [0-9]. The running zero in
3286 the beginning of D and P will be ignored. /P is optional.
3287
3288 When /P is not in the String, the function stops at the first character that is
3289 not a valid decimal digit character after four D's are converted.
3290
3291 When /P is in the String, the function stops at the first character that is not
3292 a valid decimal digit character after P is converted.
3293
3294 If String is NULL, then ASSERT().
3295
3296 If Address is NULL, then ASSERT().
3297
3298 If EndPointer is not NULL and Address is translated from String, a pointer
3299 to the character that stopped the scan is stored at the location pointed to
3300 by EndPointer.
3301
3302 @param String Pointer to a Null-terminated ASCII string.
3303 @param EndPointer Pointer to character that stops scan.
3304 @param Address Pointer to the converted IPv4 address.
3305 @param PrefixLength Pointer to the converted IPv4 address prefix
3306 length. MAX_UINT8 is returned when /P is
3307 not in the String.
3308
3309 @retval RETURN_SUCCESS Address is translated from String.
3310 @retval RETURN_INVALID_PARAMETER If String is NULL.
3311 If Data is NULL.
3312 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3313 If any decimal number converted from D
3314 exceeds 255.
3315 If the decimal number converted from P
3316 exceeds 32.
3317
3318 **/
3319 RETURN_STATUS
3320 EFIAPI
3321 AsciiStrToIpv4Address (
3322 IN CONST CHAR8 *String,
3323 OUT CHAR8 **EndPointer, OPTIONAL
3324 OUT IPv4_ADDRESS *Address,
3325 OUT UINT8 *PrefixLength OPTIONAL
3326 )
3327 {
3328 RETURN_STATUS Status;
3329 UINTN AddressIndex;
3330 UINTN Uintn;
3331 IPv4_ADDRESS LocalAddress;
3332 UINT8 LocalPrefixLength;
3333 CHAR8 *Pointer;
3334
3335 LocalPrefixLength = MAX_UINT8;
3336
3337 //
3338 // None of String or Address shall be a null pointer.
3339 //
3340 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3341 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
3342
3343 for (Pointer = (CHAR8 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
3344 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {
3345 //
3346 // D or P contains invalid characters.
3347 //
3348 break;
3349 }
3350
3351 //
3352 // Get D or P.
3353 //
3354 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *) Pointer, &Pointer, &Uintn);
3355 if (RETURN_ERROR (Status)) {
3356 return RETURN_UNSUPPORTED;
3357 }
3358 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3359 //
3360 // It's P.
3361 //
3362 if (Uintn > 32) {
3363 return RETURN_UNSUPPORTED;
3364 }
3365 LocalPrefixLength = (UINT8) Uintn;
3366 } else {
3367 //
3368 // It's D.
3369 //
3370 if (Uintn > MAX_UINT8) {
3371 return RETURN_UNSUPPORTED;
3372 }
3373 LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
3374 AddressIndex++;
3375 }
3376
3377 //
3378 // Check the '.' or '/', depending on the AddressIndex.
3379 //
3380 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
3381 if (*Pointer == '/') {
3382 //
3383 // '/P' is in the String.
3384 // Skip "/" and get P in next loop.
3385 //
3386 Pointer++;
3387 } else {
3388 //
3389 // '/P' is not in the String.
3390 //
3391 break;
3392 }
3393 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3394 if (*Pointer == '.') {
3395 //
3396 // D should be followed by '.'
3397 //
3398 Pointer++;
3399 } else {
3400 return RETURN_UNSUPPORTED;
3401 }
3402 }
3403 }
3404
3405 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
3406 return RETURN_UNSUPPORTED;
3407 }
3408
3409 CopyMem (Address, &LocalAddress, sizeof (*Address));
3410 if (PrefixLength != NULL) {
3411 *PrefixLength = LocalPrefixLength;
3412 }
3413 if (EndPointer != NULL) {
3414 *EndPointer = Pointer;
3415 }
3416
3417 return RETURN_SUCCESS;
3418 }
3419
3420 /**
3421 Convert a Null-terminated ASCII GUID string to a value of type
3422 EFI_GUID.
3423
3424 This function outputs a GUID value by interpreting the contents of
3425 the ASCII string specified by String. The format of the input
3426 ASCII string String consists of 36 characters, as follows:
3427
3428 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3429
3430 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3431 [A-F], with each pair representing a single byte hexadecimal value.
3432
3433 The mapping between String and the EFI_GUID structure is as follows:
3434 aa Data1[24:31]
3435 bb Data1[16:23]
3436 cc Data1[8:15]
3437 dd Data1[0:7]
3438 ee Data2[8:15]
3439 ff Data2[0:7]
3440 gg Data3[8:15]
3441 hh Data3[0:7]
3442 ii Data4[0:7]
3443 jj Data4[8:15]
3444 kk Data4[16:23]
3445 ll Data4[24:31]
3446 mm Data4[32:39]
3447 nn Data4[40:47]
3448 oo Data4[48:55]
3449 pp Data4[56:63]
3450
3451 If String is NULL, then ASSERT().
3452 If Guid is NULL, then ASSERT().
3453
3454 @param String Pointer to a Null-terminated ASCII string.
3455 @param Guid Pointer to the converted GUID.
3456
3457 @retval RETURN_SUCCESS Guid is translated from String.
3458 @retval RETURN_INVALID_PARAMETER If String is NULL.
3459 If Data is NULL.
3460 @retval RETURN_UNSUPPORTED If String is not as the above format.
3461
3462 **/
3463 RETURN_STATUS
3464 EFIAPI
3465 AsciiStrToGuid (
3466 IN CONST CHAR8 *String,
3467 OUT GUID *Guid
3468 )
3469 {
3470 RETURN_STATUS Status;
3471 GUID LocalGuid;
3472
3473 //
3474 // None of String or Guid shall be a null pointer.
3475 //
3476 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3477 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
3478
3479 //
3480 // Get aabbccdd in big-endian.
3481 //
3482 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
3483 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != '-') {
3484 return RETURN_UNSUPPORTED;
3485 }
3486 //
3487 // Convert big-endian to little-endian.
3488 //
3489 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
3490 String += 2 * sizeof (LocalGuid.Data1) + 1;
3491
3492 //
3493 // Get eeff in big-endian.
3494 //
3495 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
3496 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != '-') {
3497 return RETURN_UNSUPPORTED;
3498 }
3499 //
3500 // Convert big-endian to little-endian.
3501 //
3502 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
3503 String += 2 * sizeof (LocalGuid.Data2) + 1;
3504
3505 //
3506 // Get gghh in big-endian.
3507 //
3508 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
3509 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != '-') {
3510 return RETURN_UNSUPPORTED;
3511 }
3512 //
3513 // Convert big-endian to little-endian.
3514 //
3515 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
3516 String += 2 * sizeof (LocalGuid.Data3) + 1;
3517
3518 //
3519 // Get iijj.
3520 //
3521 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
3522 if (RETURN_ERROR (Status) || String[2 * 2] != '-') {
3523 return RETURN_UNSUPPORTED;
3524 }
3525 String += 2 * 2 + 1;
3526
3527 //
3528 // Get kkllmmnnoopp.
3529 //
3530 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
3531 if (RETURN_ERROR (Status)) {
3532 return RETURN_UNSUPPORTED;
3533 }
3534
3535 CopyGuid (Guid, &LocalGuid);
3536 return RETURN_SUCCESS;
3537 }
3538
3539 /**
3540 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3541
3542 This function outputs a byte array by interpreting the contents of
3543 the ASCII string specified by String in hexadecimal format. The format of
3544 the input ASCII string String is:
3545
3546 [XX]*
3547
3548 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3549 The function decodes every two hexadecimal digit characters as one byte. The
3550 decoding stops after Length of characters and outputs Buffer containing
3551 (Length / 2) bytes.
3552
3553 If String is NULL, then ASSERT().
3554
3555 If Buffer is NULL, then ASSERT().
3556
3557 If Length is not multiple of 2, then ASSERT().
3558
3559 If PcdMaximumAsciiStringLength is not zero and Length is greater than
3560 PcdMaximumAsciiStringLength, then ASSERT().
3561
3562 If MaxBufferSize is less than (Length / 2), then ASSERT().
3563
3564 @param String Pointer to a Null-terminated ASCII string.
3565 @param Length The number of ASCII characters to decode.
3566 @param Buffer Pointer to the converted bytes array.
3567 @param MaxBufferSize The maximum size of Buffer.
3568
3569 @retval RETURN_SUCCESS Buffer is translated from String.
3570 @retval RETURN_INVALID_PARAMETER If String is NULL.
3571 If Data is NULL.
3572 If Length is not multiple of 2.
3573 If PcdMaximumAsciiStringLength is not zero,
3574 and Length is greater than
3575 PcdMaximumAsciiStringLength.
3576 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3577 a character that is not valid hexadecimal
3578 digit characters, or a Null-terminator.
3579 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3580 **/
3581 RETURN_STATUS
3582 EFIAPI
3583 AsciiStrHexToBytes (
3584 IN CONST CHAR8 *String,
3585 IN UINTN Length,
3586 OUT UINT8 *Buffer,
3587 IN UINTN MaxBufferSize
3588 )
3589 {
3590 UINTN Index;
3591
3592 //
3593 // 1. None of String or Buffer shall be a null pointer.
3594 //
3595 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
3596 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
3597
3598 //
3599 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3600 //
3601 if (ASCII_RSIZE_MAX != 0) {
3602 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
3603 }
3604
3605 //
3606 // 3. Length shall not be odd.
3607 //
3608 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
3609
3610 //
3611 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3612 //
3613 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
3614
3615 //
3616 // 5. String shall not contains invalid hexadecimal digits.
3617 //
3618 for (Index = 0; Index < Length; Index++) {
3619 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {
3620 break;
3621 }
3622 }
3623 if (Index != Length) {
3624 return RETURN_UNSUPPORTED;
3625 }
3626
3627 //
3628 // Convert the hex string to bytes.
3629 //
3630 for(Index = 0; Index < Length; Index++) {
3631
3632 //
3633 // For even characters, write the upper nibble for each buffer byte,
3634 // and for even characters, the lower nibble.
3635 //
3636 if ((Index & BIT0) == 0) {
3637 Buffer[Index / 2] = (UINT8) InternalAsciiHexCharToUintn (String[Index]) << 4;
3638 } else {
3639 Buffer[Index / 2] |= (UINT8) InternalAsciiHexCharToUintn (String[Index]);
3640 }
3641 }
3642 return RETURN_SUCCESS;
3643 }
3644