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