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