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