1 /** @file
2   Unicode and ASCII string primitives.
3 
4   Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include "BaseLibInternals.h"
10 
11 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
12 
13 /**
14   [ATTENTION] This function will be deprecated for security reason.
15 
16   Copies one Null-terminated Unicode string to another Null-terminated Unicode
17   string and returns the new Unicode string.
18 
19   This function copies the contents of the Unicode string Source to the Unicode
20   string Destination, and returns Destination. If Source and Destination
21   overlap, then the results are undefined.
22 
23   If Destination is NULL, then ASSERT().
24   If Destination is not aligned on a 16-bit boundary, then ASSERT().
25   If Source is NULL, then ASSERT().
26   If Source is not aligned on a 16-bit boundary, then ASSERT().
27   If Source and Destination overlap, then ASSERT().
28   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
29   PcdMaximumUnicodeStringLength Unicode characters, not including the
30   Null-terminator, then ASSERT().
31 
32   @param  Destination A pointer to a Null-terminated Unicode string.
33   @param  Source      A pointer to a Null-terminated Unicode string.
34 
35   @return Destination.
36 
37 **/
38 CHAR16 *
39 EFIAPI
StrCpy(OUT CHAR16 * Destination,IN CONST CHAR16 * Source)40 StrCpy (
41   OUT     CHAR16                    *Destination,
42   IN      CONST CHAR16              *Source
43   )
44 {
45   CHAR16                            *ReturnValue;
46 
47   //
48   // Destination cannot be NULL
49   //
50   ASSERT (Destination != NULL);
51   ASSERT (((UINTN) Destination & BIT0) == 0);
52 
53   //
54   // Destination and source cannot overlap
55   //
56   ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
57   ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
58 
59   ReturnValue = Destination;
60   while (*Source != 0) {
61     *(Destination++) = *(Source++);
62   }
63   *Destination = 0;
64   return ReturnValue;
65 }
66 
67 /**
68   [ATTENTION] This function will be deprecated for security reason.
69 
70   Copies up to a specified length from one Null-terminated Unicode string  to
71   another Null-terminated Unicode string and returns the new Unicode string.
72 
73   This function copies the contents of the Unicode string Source to the Unicode
74   string Destination, and returns Destination. At most, Length Unicode
75   characters are copied from Source to Destination. If Length is 0, then
76   Destination is returned unmodified. If Length is greater that the number of
77   Unicode characters in Source, then Destination is padded with Null Unicode
78   characters. If Source and Destination overlap, then the results are
79   undefined.
80 
81   If Length > 0 and Destination is NULL, then ASSERT().
82   If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
83   If Length > 0 and Source is NULL, then ASSERT().
84   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
85   If Source and Destination overlap, then ASSERT().
86   If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
87   PcdMaximumUnicodeStringLength, then ASSERT().
88   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
89   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
90   then ASSERT().
91 
92   @param  Destination A pointer to a Null-terminated Unicode string.
93   @param  Source      A pointer to a Null-terminated Unicode string.
94   @param  Length      The maximum number of Unicode characters to copy.
95 
96   @return Destination.
97 
98 **/
99 CHAR16 *
100 EFIAPI
StrnCpy(OUT CHAR16 * Destination,IN CONST CHAR16 * Source,IN UINTN Length)101 StrnCpy (
102   OUT     CHAR16                    *Destination,
103   IN      CONST CHAR16              *Source,
104   IN      UINTN                     Length
105   )
106 {
107   CHAR16                            *ReturnValue;
108 
109   if (Length == 0) {
110     return Destination;
111   }
112 
113   //
114   // Destination cannot be NULL if Length is not zero
115   //
116   ASSERT (Destination != NULL);
117   ASSERT (((UINTN) Destination & BIT0) == 0);
118 
119   //
120   // Destination and source cannot overlap
121   //
122   ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
123   ASSERT ((UINTN)(Source - Destination) >= Length);
124 
125   if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
126     ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
127   }
128 
129   ReturnValue = Destination;
130 
131   while ((*Source != L'\0') && (Length > 0)) {
132     *(Destination++) = *(Source++);
133     Length--;
134   }
135 
136   ZeroMem (Destination, Length * sizeof (*Destination));
137   return ReturnValue;
138 }
139 #endif
140 
141 /**
142   Returns the length of a Null-terminated Unicode string.
143 
144   This function returns the number of Unicode characters in the Null-terminated
145   Unicode string specified by String.
146 
147   If String is NULL, then ASSERT().
148   If String is not aligned on a 16-bit boundary, then ASSERT().
149   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
150   PcdMaximumUnicodeStringLength Unicode characters, not including the
151   Null-terminator, then ASSERT().
152 
153   @param  String  A pointer to a Null-terminated Unicode string.
154 
155   @return The length of String.
156 
157 **/
158 UINTN
159 EFIAPI
StrLen(IN CONST CHAR16 * String)160 StrLen (
161   IN      CONST CHAR16              *String
162   )
163 {
164   UINTN                             Length;
165 
166   ASSERT (String != NULL);
167   ASSERT (((UINTN) String & BIT0) == 0);
168 
169   for (Length = 0; *String != L'\0'; String++, Length++) {
170     //
171     // If PcdMaximumUnicodeStringLength is not zero,
172     // length should not more than PcdMaximumUnicodeStringLength
173     //
174     if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
175       ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
176     }
177   }
178   return Length;
179 }
180 
181 /**
182   Returns the size of a Null-terminated Unicode string in bytes, including the
183   Null terminator.
184 
185   This function returns the size, in bytes, of the Null-terminated Unicode string
186   specified by String.
187 
188   If String is NULL, then ASSERT().
189   If String is not aligned on a 16-bit boundary, then ASSERT().
190   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
191   PcdMaximumUnicodeStringLength Unicode characters, not including the
192   Null-terminator, then ASSERT().
193 
194   @param  String  A pointer to a Null-terminated Unicode string.
195 
196   @return The size of String.
197 
198 **/
199 UINTN
200 EFIAPI
StrSize(IN CONST CHAR16 * String)201 StrSize (
202   IN      CONST CHAR16              *String
203   )
204 {
205   return (StrLen (String) + 1) * sizeof (*String);
206 }
207 
208 /**
209   Compares two Null-terminated Unicode strings, and returns the difference
210   between the first mismatched Unicode characters.
211 
212   This function compares the Null-terminated Unicode string FirstString to the
213   Null-terminated Unicode string SecondString. If FirstString is identical to
214   SecondString, then 0 is returned. Otherwise, the value returned is the first
215   mismatched Unicode character in SecondString subtracted from the first
216   mismatched Unicode character in FirstString.
217 
218   If FirstString is NULL, then ASSERT().
219   If FirstString is not aligned on a 16-bit boundary, then ASSERT().
220   If SecondString is NULL, then ASSERT().
221   If SecondString is not aligned on a 16-bit boundary, then ASSERT().
222   If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
223   than PcdMaximumUnicodeStringLength Unicode characters, not including the
224   Null-terminator, then ASSERT().
225   If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
226   than PcdMaximumUnicodeStringLength Unicode characters, not including the
227   Null-terminator, then ASSERT().
228 
229   @param  FirstString   A pointer to a Null-terminated Unicode string.
230   @param  SecondString  A pointer to a Null-terminated Unicode string.
231 
232   @retval 0      FirstString is identical to SecondString.
233   @return others FirstString is not identical to SecondString.
234 
235 **/
236 INTN
237 EFIAPI
StrCmp(IN CONST CHAR16 * FirstString,IN CONST CHAR16 * SecondString)238 StrCmp (
239   IN      CONST CHAR16              *FirstString,
240   IN      CONST CHAR16              *SecondString
241   )
242 {
243   //
244   // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
245   //
246   ASSERT (StrSize (FirstString) != 0);
247   ASSERT (StrSize (SecondString) != 0);
248 
249   while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
250     FirstString++;
251     SecondString++;
252   }
253   return *FirstString - *SecondString;
254 }
255 
256 /**
257   Compares up to a specified length the contents of two Null-terminated Unicode strings,
258   and returns the difference between the first mismatched Unicode characters.
259 
260   This function compares the Null-terminated Unicode string FirstString to the
261   Null-terminated Unicode string SecondString. At most, Length Unicode
262   characters will be compared. If Length is 0, then 0 is returned. If
263   FirstString is identical to SecondString, then 0 is returned. Otherwise, the
264   value returned is the first mismatched Unicode character in SecondString
265   subtracted from the first mismatched Unicode character in FirstString.
266 
267   If Length > 0 and FirstString is NULL, then ASSERT().
268   If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
269   If Length > 0 and SecondString is NULL, then ASSERT().
270   If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
271   If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
272   PcdMaximumUnicodeStringLength, then ASSERT().
273   If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
274   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
275   then ASSERT().
276   If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
277   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
278   then ASSERT().
279 
280   @param  FirstString   A pointer to a Null-terminated Unicode string.
281   @param  SecondString  A pointer to a Null-terminated Unicode string.
282   @param  Length        The maximum number of Unicode characters to compare.
283 
284   @retval 0      FirstString is identical to SecondString.
285   @return others FirstString is not identical to SecondString.
286 
287 **/
288 INTN
289 EFIAPI
StrnCmp(IN CONST CHAR16 * FirstString,IN CONST CHAR16 * SecondString,IN UINTN Length)290 StrnCmp (
291   IN      CONST CHAR16              *FirstString,
292   IN      CONST CHAR16              *SecondString,
293   IN      UINTN                     Length
294   )
295 {
296   if (Length == 0) {
297     return 0;
298   }
299 
300   //
301   // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
302   // Length tests are performed inside StrLen().
303   //
304   ASSERT (StrSize (FirstString) != 0);
305   ASSERT (StrSize (SecondString) != 0);
306 
307   if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
308     ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
309   }
310 
311   while ((*FirstString != L'\0') &&
312          (*SecondString != L'\0') &&
313          (*FirstString == *SecondString) &&
314          (Length > 1)) {
315     FirstString++;
316     SecondString++;
317     Length--;
318   }
319 
320   return *FirstString - *SecondString;
321 }
322 
323 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
324 
325 /**
326   [ATTENTION] This function will be deprecated for security reason.
327 
328   Concatenates one Null-terminated Unicode string to another Null-terminated
329   Unicode string, and returns the concatenated Unicode string.
330 
331   This function concatenates two Null-terminated Unicode strings. The contents
332   of Null-terminated Unicode string Source are concatenated to the end of
333   Null-terminated Unicode string Destination. The Null-terminated concatenated
334   Unicode String is returned. If Source and Destination overlap, then the
335   results are undefined.
336 
337   If Destination is NULL, then ASSERT().
338   If Destination is not aligned on a 16-bit boundary, then ASSERT().
339   If Source is NULL, then ASSERT().
340   If Source is not aligned on a 16-bit boundary, then ASSERT().
341   If Source and Destination overlap, then ASSERT().
342   If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
343   than PcdMaximumUnicodeStringLength Unicode characters, not including the
344   Null-terminator, then ASSERT().
345   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
346   PcdMaximumUnicodeStringLength Unicode characters, not including the
347   Null-terminator, then ASSERT().
348   If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
349   and Source results in a Unicode string with more than
350   PcdMaximumUnicodeStringLength Unicode characters, not including the
351   Null-terminator, then ASSERT().
352 
353   @param  Destination A pointer to a Null-terminated Unicode string.
354   @param  Source      A pointer to a Null-terminated Unicode string.
355 
356   @return Destination.
357 
358 **/
359 CHAR16 *
360 EFIAPI
StrCat(IN OUT CHAR16 * Destination,IN CONST CHAR16 * Source)361 StrCat (
362   IN OUT  CHAR16                    *Destination,
363   IN      CONST CHAR16              *Source
364   )
365 {
366   StrCpy (Destination + StrLen (Destination), Source);
367 
368   //
369   // Size of the resulting string should never be zero.
370   // PcdMaximumUnicodeStringLength is tested inside StrLen().
371   //
372   ASSERT (StrSize (Destination) != 0);
373   return Destination;
374 }
375 
376 /**
377   [ATTENTION] This function will be deprecated for security reason.
378 
379   Concatenates up to a specified length one Null-terminated Unicode to the end
380   of another Null-terminated Unicode string, and returns the concatenated
381   Unicode string.
382 
383   This function concatenates two Null-terminated Unicode strings. The contents
384   of Null-terminated Unicode string Source are concatenated to the end of
385   Null-terminated Unicode string Destination, and Destination is returned. At
386   most, Length Unicode characters are concatenated from Source to the end of
387   Destination, and Destination is always Null-terminated. If Length is 0, then
388   Destination is returned unmodified. If Source and Destination overlap, then
389   the results are undefined.
390 
391   If Destination is NULL, then ASSERT().
392   If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
393   If Length > 0 and Source is NULL, then ASSERT().
394   If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
395   If Source and Destination overlap, then ASSERT().
396   If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
397   PcdMaximumUnicodeStringLength, then ASSERT().
398   If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
399   than PcdMaximumUnicodeStringLength Unicode characters, not including the
400   Null-terminator, then ASSERT().
401   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
402   PcdMaximumUnicodeStringLength Unicode characters, not including the
403   Null-terminator, then ASSERT().
404   If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
405   and Source results in a Unicode string with more than PcdMaximumUnicodeStringLength
406   Unicode characters, not including the Null-terminator, then ASSERT().
407 
408   @param  Destination A pointer to a Null-terminated Unicode string.
409   @param  Source      A pointer to a Null-terminated Unicode string.
410   @param  Length      The maximum number of Unicode characters to concatenate from
411                       Source.
412 
413   @return Destination.
414 
415 **/
416 CHAR16 *
417 EFIAPI
StrnCat(IN OUT CHAR16 * Destination,IN CONST CHAR16 * Source,IN UINTN Length)418 StrnCat (
419   IN OUT  CHAR16                    *Destination,
420   IN      CONST CHAR16              *Source,
421   IN      UINTN                     Length
422   )
423 {
424   UINTN   DestinationLen;
425 
426   DestinationLen = StrLen (Destination);
427   StrnCpy (Destination + DestinationLen, Source, Length);
428   Destination[DestinationLen + Length] = L'\0';
429 
430   //
431   // Size of the resulting string should never be zero.
432   // PcdMaximumUnicodeStringLength is tested inside StrLen().
433   //
434   ASSERT (StrSize (Destination) != 0);
435   return Destination;
436 }
437 #endif
438 
439 /**
440   Returns the first occurrence of a Null-terminated Unicode sub-string
441   in a Null-terminated Unicode string.
442 
443   This function scans the contents of the Null-terminated Unicode string
444   specified by String and returns the first occurrence of SearchString.
445   If SearchString is not found in String, then NULL is returned.  If
446   the length of SearchString is zero, then String is
447   returned.
448 
449   If String is NULL, then ASSERT().
450   If String is not aligned on a 16-bit boundary, then ASSERT().
451   If SearchString is NULL, then ASSERT().
452   If SearchString is not aligned on a 16-bit boundary, then ASSERT().
453 
454   If PcdMaximumUnicodeStringLength is not zero, and SearchString
455   or String contains more than PcdMaximumUnicodeStringLength Unicode
456   characters, not including the Null-terminator, then ASSERT().
457 
458   @param  String          A pointer to a Null-terminated Unicode string.
459   @param  SearchString    A pointer to a Null-terminated Unicode string to search for.
460 
461   @retval NULL            If the SearchString does not appear in String.
462   @return others          If there is a match.
463 
464 **/
465 CHAR16 *
466 EFIAPI
StrStr(IN CONST CHAR16 * String,IN CONST CHAR16 * SearchString)467 StrStr (
468   IN      CONST CHAR16              *String,
469   IN      CONST CHAR16              *SearchString
470   )
471 {
472   CONST CHAR16 *FirstMatch;
473   CONST CHAR16 *SearchStringTmp;
474 
475   //
476   // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
477   // Length tests are performed inside StrLen().
478   //
479   ASSERT (StrSize (String) != 0);
480   ASSERT (StrSize (SearchString) != 0);
481 
482   if (*SearchString == L'\0') {
483     return (CHAR16 *) String;
484   }
485 
486   while (*String != L'\0') {
487     SearchStringTmp = SearchString;
488     FirstMatch = String;
489 
490     while ((*String == *SearchStringTmp)
491             && (*String != L'\0')) {
492       String++;
493       SearchStringTmp++;
494     }
495 
496     if (*SearchStringTmp == L'\0') {
497       return (CHAR16 *) FirstMatch;
498     }
499 
500     if (*String == L'\0') {
501       return NULL;
502     }
503 
504     String = FirstMatch + 1;
505   }
506 
507   return NULL;
508 }
509 
510 /**
511   Check if a Unicode character is a decimal character.
512 
513   This internal function checks if a Unicode character is a
514   decimal character. The valid decimal character is from
515   L'0' to L'9'.
516 
517   @param  Char  The character to check against.
518 
519   @retval TRUE  If the Char is a decmial character.
520   @retval FALSE If the Char is not a decmial character.
521 
522 **/
523 BOOLEAN
524 EFIAPI
InternalIsDecimalDigitCharacter(IN CHAR16 Char)525 InternalIsDecimalDigitCharacter (
526   IN      CHAR16                    Char
527   )
528 {
529   return (BOOLEAN) (Char >= L'0' && Char <= L'9');
530 }
531 
532 /**
533   Convert a Unicode character to upper case only if
534   it maps to a valid small-case ASCII character.
535 
536   This internal function only deal with Unicode character
537   which maps to a valid small-case ASCII character, i.e.
538   L'a' to L'z'. For other Unicode character, the input character
539   is returned directly.
540 
541   @param  Char  The character to convert.
542 
543   @retval LowerCharacter   If the Char is with range L'a' to L'z'.
544   @retval Unchanged        Otherwise.
545 
546 **/
547 CHAR16
548 EFIAPI
CharToUpper(IN CHAR16 Char)549 CharToUpper (
550   IN      CHAR16                    Char
551   )
552 {
553   if (Char >= L'a' && Char <= L'z') {
554     return (CHAR16) (Char - (L'a' - L'A'));
555   }
556 
557   return Char;
558 }
559 
560 /**
561   Convert a Unicode character to numerical value.
562 
563   This internal function only deal with Unicode character
564   which maps to a valid hexadecimal ASII character, i.e.
565   L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
566   Unicode character, the value returned does not make sense.
567 
568   @param  Char  The character to convert.
569 
570   @return The numerical value converted.
571 
572 **/
573 UINTN
574 EFIAPI
InternalHexCharToUintn(IN CHAR16 Char)575 InternalHexCharToUintn (
576   IN      CHAR16                    Char
577   )
578 {
579   if (InternalIsDecimalDigitCharacter (Char)) {
580     return Char - L'0';
581   }
582 
583   return (10 + CharToUpper (Char) - L'A');
584 }
585 
586 /**
587   Check if a Unicode character is a hexadecimal character.
588 
589   This internal function checks if a Unicode character is a
590   decimal character.  The valid hexadecimal character is
591   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
592 
593 
594   @param  Char  The character to check against.
595 
596   @retval TRUE  If the Char is a hexadecmial character.
597   @retval FALSE If the Char is not a hexadecmial character.
598 
599 **/
600 BOOLEAN
601 EFIAPI
InternalIsHexaDecimalDigitCharacter(IN CHAR16 Char)602 InternalIsHexaDecimalDigitCharacter (
603   IN      CHAR16                    Char
604   )
605 {
606 
607   return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
608     (Char >= L'A' && Char <= L'F') ||
609     (Char >= L'a' && Char <= L'f'));
610 }
611 
612 /**
613   Convert a Null-terminated Unicode decimal string to a value of
614   type UINTN.
615 
616   This function returns a value of type UINTN by interpreting the contents
617   of the Unicode string specified by String as a decimal number. The format
618   of the input Unicode string String is:
619 
620                   [spaces] [decimal digits].
621 
622   The valid decimal digit character is in the range [0-9]. The
623   function will ignore the pad space, which includes spaces or
624   tab characters, before [decimal digits]. The running zero in the
625   beginning of [decimal digits] will be ignored. Then, the function
626   stops at the first character that is a not a valid decimal character
627   or a Null-terminator, whichever one comes first.
628 
629   If String is NULL, then ASSERT().
630   If String is not aligned in a 16-bit boundary, then ASSERT().
631   If String has only pad spaces, then 0 is returned.
632   If String has no pad spaces or valid decimal digits,
633   then 0 is returned.
634   If the number represented by String overflows according
635   to the range defined by UINTN, then MAX_UINTN is returned.
636 
637   If PcdMaximumUnicodeStringLength is not zero, and String contains
638   more than PcdMaximumUnicodeStringLength Unicode characters, not including
639   the Null-terminator, then ASSERT().
640 
641   @param  String      A pointer to a Null-terminated Unicode string.
642 
643   @retval Value translated from String.
644 
645 **/
646 UINTN
647 EFIAPI
StrDecimalToUintn(IN CONST CHAR16 * String)648 StrDecimalToUintn (
649   IN      CONST CHAR16              *String
650   )
651 {
652   UINTN     Result;
653 
654   StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);
655   return Result;
656 }
657 
658 
659 /**
660   Convert a Null-terminated Unicode decimal string to a value of
661   type UINT64.
662 
663   This function returns a value of type UINT64 by interpreting the contents
664   of the Unicode string specified by String as a decimal number. The format
665   of the input Unicode string String is:
666 
667                   [spaces] [decimal digits].
668 
669   The valid decimal digit character is in the range [0-9]. The
670   function will ignore the pad space, which includes spaces or
671   tab characters, before [decimal digits]. The running zero in the
672   beginning of [decimal digits] will be ignored. Then, the function
673   stops at the first character that is a not a valid decimal character
674   or a Null-terminator, whichever one comes first.
675 
676   If String is NULL, then ASSERT().
677   If String is not aligned in a 16-bit boundary, then ASSERT().
678   If String has only pad spaces, then 0 is returned.
679   If String has no pad spaces or valid decimal digits,
680   then 0 is returned.
681   If the number represented by String overflows according
682   to the range defined by UINT64, then MAX_UINT64 is returned.
683 
684   If PcdMaximumUnicodeStringLength is not zero, and String contains
685   more than PcdMaximumUnicodeStringLength Unicode characters, not including
686   the Null-terminator, then ASSERT().
687 
688   @param  String          A pointer to a Null-terminated Unicode string.
689 
690   @retval Value translated from String.
691 
692 **/
693 UINT64
694 EFIAPI
StrDecimalToUint64(IN CONST CHAR16 * String)695 StrDecimalToUint64 (
696   IN      CONST CHAR16              *String
697   )
698 {
699   UINT64     Result;
700 
701   StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
702   return Result;
703 }
704 
705 /**
706   Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
707 
708   This function returns a value of type UINTN by interpreting the contents
709   of the Unicode string specified by String as a hexadecimal number.
710   The format of the input Unicode string String is:
711 
712                   [spaces][zeros][x][hexadecimal digits].
713 
714   The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
715   The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
716   If "x" appears in the input string, it must be prefixed with at least one 0.
717   The function will ignore the pad space, which includes spaces or tab characters,
718   before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
719   [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
720   first valid hexadecimal digit. Then, the function stops at the first character that is
721   a not a valid hexadecimal character or NULL, whichever one comes first.
722 
723   If String is NULL, then ASSERT().
724   If String is not aligned in a 16-bit boundary, then ASSERT().
725   If String has only pad spaces, then zero is returned.
726   If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
727   then zero is returned.
728   If the number represented by String overflows according to the range defined by
729   UINTN, then MAX_UINTN is returned.
730 
731   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
732   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
733   then ASSERT().
734 
735   @param  String          A pointer to a Null-terminated Unicode string.
736 
737   @retval Value translated from String.
738 
739 **/
740 UINTN
741 EFIAPI
StrHexToUintn(IN CONST CHAR16 * String)742 StrHexToUintn (
743   IN      CONST CHAR16              *String
744   )
745 {
746   UINTN     Result;
747 
748   StrHexToUintnS (String, (CHAR16 **) NULL, &Result);
749   return Result;
750 }
751 
752 
753 /**
754   Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
755 
756   This function returns a value of type UINT64 by interpreting the contents
757   of the Unicode string specified by String as a hexadecimal number.
758   The format of the input Unicode string String is
759 
760                   [spaces][zeros][x][hexadecimal digits].
761 
762   The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
763   The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
764   If "x" appears in the input string, it must be prefixed with at least one 0.
765   The function will ignore the pad space, which includes spaces or tab characters,
766   before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
767   [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
768   first valid hexadecimal digit. Then, the function stops at the first character that is
769   a not a valid hexadecimal character or NULL, whichever one comes first.
770 
771   If String is NULL, then ASSERT().
772   If String is not aligned in a 16-bit boundary, then ASSERT().
773   If String has only pad spaces, then zero is returned.
774   If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
775   then zero is returned.
776   If the number represented by String overflows according to the range defined by
777   UINT64, then MAX_UINT64 is returned.
778 
779   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
780   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
781   then ASSERT().
782 
783   @param  String          A pointer to a Null-terminated Unicode string.
784 
785   @retval Value translated from String.
786 
787 **/
788 UINT64
789 EFIAPI
StrHexToUint64(IN CONST CHAR16 * String)790 StrHexToUint64 (
791   IN      CONST CHAR16             *String
792   )
793 {
794   UINT64    Result;
795 
796   StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
797   return Result;
798 }
799 
800 /**
801   Check if a ASCII character is a decimal character.
802 
803   This internal function checks if a Unicode character is a
804   decimal character. The valid decimal character is from
805   '0' to '9'.
806 
807   @param  Char  The character to check against.
808 
809   @retval TRUE  If the Char is a decmial character.
810   @retval FALSE If the Char is not a decmial character.
811 
812 **/
813 BOOLEAN
814 EFIAPI
InternalAsciiIsDecimalDigitCharacter(IN CHAR8 Char)815 InternalAsciiIsDecimalDigitCharacter (
816   IN      CHAR8                     Char
817   )
818 {
819   return (BOOLEAN) (Char >= '0' && Char <= '9');
820 }
821 
822 /**
823   Check if a ASCII character is a hexadecimal character.
824 
825   This internal function checks if a ASCII character is a
826   decimal character.  The valid hexadecimal character is
827   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
828 
829 
830   @param  Char  The character to check against.
831 
832   @retval TRUE  If the Char is a hexadecmial character.
833   @retval FALSE If the Char is not a hexadecmial character.
834 
835 **/
836 BOOLEAN
837 EFIAPI
InternalAsciiIsHexaDecimalDigitCharacter(IN CHAR8 Char)838 InternalAsciiIsHexaDecimalDigitCharacter (
839   IN      CHAR8                    Char
840   )
841 {
842 
843   return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||
844     (Char >= 'A' && Char <= 'F') ||
845     (Char >= 'a' && Char <= 'f'));
846 }
847 
848 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
849 
850 /**
851   [ATTENTION] This function is deprecated for security reason.
852 
853   Convert a Null-terminated Unicode string to a Null-terminated
854   ASCII string and returns the ASCII string.
855 
856   This function converts the content of the Unicode string Source
857   to the ASCII string Destination by copying the lower 8 bits of
858   each Unicode character. It returns Destination.
859 
860   The caller is responsible to make sure Destination points to a buffer with size
861   equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
862 
863   If any Unicode characters in Source contain non-zero value in
864   the upper 8 bits, then ASSERT().
865 
866   If Destination is NULL, then ASSERT().
867   If Source is NULL, then ASSERT().
868   If Source is not aligned on a 16-bit boundary, then ASSERT().
869   If Source and Destination overlap, then ASSERT().
870 
871   If PcdMaximumUnicodeStringLength is not zero, and Source contains
872   more than PcdMaximumUnicodeStringLength Unicode characters, not including
873   the Null-terminator, then ASSERT().
874 
875   If PcdMaximumAsciiStringLength is not zero, and Source contains more
876   than PcdMaximumAsciiStringLength Unicode characters, not including the
877   Null-terminator, then ASSERT().
878 
879   @param  Source        A pointer to a Null-terminated Unicode string.
880   @param  Destination   A pointer to a Null-terminated ASCII string.
881 
882   @return Destination.
883 
884 **/
885 CHAR8 *
886 EFIAPI
UnicodeStrToAsciiStr(IN CONST CHAR16 * Source,OUT CHAR8 * Destination)887 UnicodeStrToAsciiStr (
888   IN      CONST CHAR16              *Source,
889   OUT     CHAR8                     *Destination
890   )
891 {
892   CHAR8                               *ReturnValue;
893 
894   ASSERT (Destination != NULL);
895 
896   //
897   // ASSERT if Source is long than PcdMaximumUnicodeStringLength.
898   // Length tests are performed inside StrLen().
899   //
900   ASSERT (StrSize (Source) != 0);
901 
902   //
903   // Source and Destination should not overlap
904   //
905   ASSERT ((UINTN) (Destination - (CHAR8 *) Source) >= StrSize (Source));
906   ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
907 
908 
909   ReturnValue = Destination;
910   while (*Source != '\0') {
911     //
912     // If any Unicode characters in Source contain
913     // non-zero value in the upper 8 bits, then ASSERT().
914     //
915     ASSERT (*Source < 0x100);
916     *(Destination++) = (CHAR8) *(Source++);
917   }
918 
919   *Destination = '\0';
920 
921   //
922   // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
923   // Length tests are performed inside AsciiStrLen().
924   //
925   ASSERT (AsciiStrSize (ReturnValue) != 0);
926 
927   return ReturnValue;
928 }
929 
930 /**
931   [ATTENTION] This function will be deprecated for security reason.
932 
933   Copies one Null-terminated ASCII string to another Null-terminated ASCII
934   string and returns the new ASCII string.
935 
936   This function copies the contents of the ASCII string Source to the ASCII
937   string Destination, and returns Destination. If Source and Destination
938   overlap, then the results are undefined.
939 
940   If Destination is NULL, then ASSERT().
941   If Source is NULL, then ASSERT().
942   If Source and Destination overlap, then ASSERT().
943   If PcdMaximumAsciiStringLength is not zero and Source contains more than
944   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
945   then ASSERT().
946 
947   @param  Destination A pointer to a Null-terminated ASCII string.
948   @param  Source      A pointer to a Null-terminated ASCII string.
949 
950   @return Destination
951 
952 **/
953 CHAR8 *
954 EFIAPI
AsciiStrCpy(OUT CHAR8 * Destination,IN CONST CHAR8 * Source)955 AsciiStrCpy (
956   OUT     CHAR8                     *Destination,
957   IN      CONST CHAR8               *Source
958   )
959 {
960   CHAR8                             *ReturnValue;
961 
962   //
963   // Destination cannot be NULL
964   //
965   ASSERT (Destination != NULL);
966 
967   //
968   // Destination and source cannot overlap
969   //
970   ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
971   ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));
972 
973   ReturnValue = Destination;
974   while (*Source != 0) {
975     *(Destination++) = *(Source++);
976   }
977   *Destination = 0;
978   return ReturnValue;
979 }
980 
981 /**
982   [ATTENTION] This function will be deprecated for security reason.
983 
984   Copies up to a specified length one Null-terminated ASCII string to another
985   Null-terminated ASCII string and returns the new ASCII string.
986 
987   This function copies the contents of the ASCII string Source to the ASCII
988   string Destination, and returns Destination. At most, Length ASCII characters
989   are copied from Source to Destination. If Length is 0, then Destination is
990   returned unmodified. If Length is greater that the number of ASCII characters
991   in Source, then Destination is padded with Null ASCII characters. If Source
992   and Destination overlap, then the results are undefined.
993 
994   If Destination is NULL, then ASSERT().
995   If Source is NULL, then ASSERT().
996   If Source and Destination overlap, then ASSERT().
997   If PcdMaximumAsciiStringLength is not zero, and Length is greater than
998   PcdMaximumAsciiStringLength, then ASSERT().
999   If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1000   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1001   then ASSERT().
1002 
1003   @param  Destination A pointer to a Null-terminated ASCII string.
1004   @param  Source      A pointer to a Null-terminated ASCII string.
1005   @param  Length      The maximum number of ASCII characters to copy.
1006 
1007   @return Destination
1008 
1009 **/
1010 CHAR8 *
1011 EFIAPI
AsciiStrnCpy(OUT CHAR8 * Destination,IN CONST CHAR8 * Source,IN UINTN Length)1012 AsciiStrnCpy (
1013   OUT     CHAR8                     *Destination,
1014   IN      CONST CHAR8               *Source,
1015   IN      UINTN                     Length
1016   )
1017 {
1018   CHAR8                             *ReturnValue;
1019 
1020   if (Length == 0) {
1021     return Destination;
1022   }
1023 
1024   //
1025   // Destination cannot be NULL
1026   //
1027   ASSERT (Destination != NULL);
1028 
1029   //
1030   // Destination and source cannot overlap
1031   //
1032   ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
1033   ASSERT ((UINTN)(Source - Destination) >= Length);
1034 
1035   if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1036     ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
1037   }
1038 
1039   ReturnValue = Destination;
1040 
1041   while (*Source != 0 && Length > 0) {
1042     *(Destination++) = *(Source++);
1043     Length--;
1044   }
1045 
1046   ZeroMem (Destination, Length * sizeof (*Destination));
1047   return ReturnValue;
1048 }
1049 #endif
1050 
1051 /**
1052   Returns the length of a Null-terminated ASCII string.
1053 
1054   This function returns the number of ASCII characters in the Null-terminated
1055   ASCII string specified by String.
1056 
1057   If Length > 0 and Destination is NULL, then ASSERT().
1058   If Length > 0 and Source is NULL, then ASSERT().
1059   If PcdMaximumAsciiStringLength is not zero and String contains more than
1060   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1061   then ASSERT().
1062 
1063   @param  String  A pointer to a Null-terminated ASCII string.
1064 
1065   @return The length of String.
1066 
1067 **/
1068 UINTN
1069 EFIAPI
AsciiStrLen(IN CONST CHAR8 * String)1070 AsciiStrLen (
1071   IN      CONST CHAR8               *String
1072   )
1073 {
1074   UINTN                             Length;
1075 
1076   ASSERT (String != NULL);
1077 
1078   for (Length = 0; *String != '\0'; String++, Length++) {
1079     //
1080     // If PcdMaximumUnicodeStringLength is not zero,
1081     // length should not more than PcdMaximumUnicodeStringLength
1082     //
1083     if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1084       ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
1085     }
1086   }
1087   return Length;
1088 }
1089 
1090 /**
1091   Returns the size of a Null-terminated ASCII string in bytes, including the
1092   Null terminator.
1093 
1094   This function returns the size, in bytes, of the Null-terminated ASCII string
1095   specified by String.
1096 
1097   If String is NULL, then ASSERT().
1098   If PcdMaximumAsciiStringLength is not zero and String contains more than
1099   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1100   then ASSERT().
1101 
1102   @param  String  A pointer to a Null-terminated ASCII string.
1103 
1104   @return The size of String.
1105 
1106 **/
1107 UINTN
1108 EFIAPI
AsciiStrSize(IN CONST CHAR8 * String)1109 AsciiStrSize (
1110   IN      CONST CHAR8               *String
1111   )
1112 {
1113   return (AsciiStrLen (String) + 1) * sizeof (*String);
1114 }
1115 
1116 /**
1117   Compares two Null-terminated ASCII strings, and returns the difference
1118   between the first mismatched ASCII characters.
1119 
1120   This function compares the Null-terminated ASCII string FirstString to the
1121   Null-terminated ASCII string SecondString. If FirstString is identical to
1122   SecondString, then 0 is returned. Otherwise, the value returned is the first
1123   mismatched ASCII character in SecondString subtracted from the first
1124   mismatched ASCII character in FirstString.
1125 
1126   If FirstString is NULL, then ASSERT().
1127   If SecondString is NULL, then ASSERT().
1128   If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1129   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1130   then ASSERT().
1131   If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1132   than PcdMaximumAsciiStringLength ASCII characters, not including the
1133   Null-terminator, then ASSERT().
1134 
1135   @param  FirstString   A pointer to a Null-terminated ASCII string.
1136   @param  SecondString  A pointer to a Null-terminated ASCII string.
1137 
1138   @retval ==0      FirstString is identical to SecondString.
1139   @retval !=0      FirstString is not identical to SecondString.
1140 
1141 **/
1142 INTN
1143 EFIAPI
AsciiStrCmp(IN CONST CHAR8 * FirstString,IN CONST CHAR8 * SecondString)1144 AsciiStrCmp (
1145   IN      CONST CHAR8               *FirstString,
1146   IN      CONST CHAR8               *SecondString
1147   )
1148 {
1149   //
1150   // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1151   //
1152   ASSERT (AsciiStrSize (FirstString));
1153   ASSERT (AsciiStrSize (SecondString));
1154 
1155   while ((*FirstString != '\0') && (*FirstString == *SecondString)) {
1156     FirstString++;
1157     SecondString++;
1158   }
1159 
1160   return *FirstString - *SecondString;
1161 }
1162 
1163 /**
1164   Converts a lowercase Ascii character to upper one.
1165 
1166   If Chr is lowercase Ascii character, then converts it to upper one.
1167 
1168   If Value >= 0xA0, then ASSERT().
1169   If (Value & 0x0F) >= 0x0A, then ASSERT().
1170 
1171   @param  Chr   one Ascii character
1172 
1173   @return The uppercase value of Ascii character
1174 
1175 **/
1176 CHAR8
1177 EFIAPI
AsciiCharToUpper(IN CHAR8 Chr)1178 AsciiCharToUpper (
1179   IN      CHAR8                     Chr
1180   )
1181 {
1182   return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);
1183 }
1184 
1185 /**
1186   Convert a ASCII character to numerical value.
1187 
1188   This internal function only deal with Unicode character
1189   which maps to a valid hexadecimal ASII character, i.e.
1190   '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
1191   ASCII character, the value returned does not make sense.
1192 
1193   @param  Char  The character to convert.
1194 
1195   @return The numerical value converted.
1196 
1197 **/
1198 UINTN
1199 EFIAPI
InternalAsciiHexCharToUintn(IN CHAR8 Char)1200 InternalAsciiHexCharToUintn (
1201   IN      CHAR8                    Char
1202   )
1203 {
1204   if (InternalIsDecimalDigitCharacter (Char)) {
1205     return Char - '0';
1206   }
1207 
1208   return (10 + AsciiCharToUpper (Char) - 'A');
1209 }
1210 
1211 
1212 /**
1213   Performs a case insensitive comparison of two Null-terminated ASCII strings,
1214   and returns the difference between the first mismatched ASCII characters.
1215 
1216   This function performs a case insensitive comparison of the Null-terminated
1217   ASCII string FirstString to the Null-terminated ASCII string SecondString. If
1218   FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1219   value returned is the first mismatched lower case ASCII character in
1220   SecondString subtracted from the first mismatched lower case ASCII character
1221   in FirstString.
1222 
1223   If FirstString is NULL, then ASSERT().
1224   If SecondString is NULL, then ASSERT().
1225   If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1226   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1227   then ASSERT().
1228   If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1229   than PcdMaximumAsciiStringLength ASCII characters, not including the
1230   Null-terminator, then ASSERT().
1231 
1232   @param  FirstString   A pointer to a Null-terminated ASCII string.
1233   @param  SecondString  A pointer to a Null-terminated ASCII string.
1234 
1235   @retval ==0    FirstString is identical to SecondString using case insensitive
1236                  comparisons.
1237   @retval !=0    FirstString is not identical to SecondString using case
1238                  insensitive comparisons.
1239 
1240 **/
1241 INTN
1242 EFIAPI
AsciiStriCmp(IN CONST CHAR8 * FirstString,IN CONST CHAR8 * SecondString)1243 AsciiStriCmp (
1244   IN      CONST CHAR8               *FirstString,
1245   IN      CONST CHAR8               *SecondString
1246   )
1247 {
1248   CHAR8  UpperFirstString;
1249   CHAR8  UpperSecondString;
1250 
1251   //
1252   // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1253   //
1254   ASSERT (AsciiStrSize (FirstString));
1255   ASSERT (AsciiStrSize (SecondString));
1256 
1257   UpperFirstString  = AsciiCharToUpper (*FirstString);
1258   UpperSecondString = AsciiCharToUpper (*SecondString);
1259   while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {
1260     FirstString++;
1261     SecondString++;
1262     UpperFirstString  = AsciiCharToUpper (*FirstString);
1263     UpperSecondString = AsciiCharToUpper (*SecondString);
1264   }
1265 
1266   return UpperFirstString - UpperSecondString;
1267 }
1268 
1269 /**
1270   Compares two Null-terminated ASCII strings with maximum lengths, and returns
1271   the difference between the first mismatched ASCII characters.
1272 
1273   This function compares the Null-terminated ASCII string FirstString to the
1274   Null-terminated ASCII  string SecondString. At most, Length ASCII characters
1275   will be compared. If Length is 0, then 0 is returned. If FirstString is
1276   identical to SecondString, then 0 is returned. Otherwise, the value returned
1277   is the first mismatched ASCII character in SecondString subtracted from the
1278   first mismatched ASCII character in FirstString.
1279 
1280   If Length > 0 and FirstString is NULL, then ASSERT().
1281   If Length > 0 and SecondString is NULL, then ASSERT().
1282   If PcdMaximumAsciiStringLength is not zero, and Length is greater than
1283   PcdMaximumAsciiStringLength, then ASSERT().
1284   If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
1285   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1286   then ASSERT().
1287   If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
1288   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1289   then ASSERT().
1290 
1291   @param  FirstString   A pointer to a Null-terminated ASCII string.
1292   @param  SecondString  A pointer to a Null-terminated ASCII string.
1293   @param  Length        The maximum number of ASCII characters for compare.
1294 
1295   @retval ==0       FirstString is identical to SecondString.
1296   @retval !=0       FirstString is not identical to SecondString.
1297 
1298 **/
1299 INTN
1300 EFIAPI
AsciiStrnCmp(IN CONST CHAR8 * FirstString,IN CONST CHAR8 * SecondString,IN UINTN Length)1301 AsciiStrnCmp (
1302   IN      CONST CHAR8               *FirstString,
1303   IN      CONST CHAR8               *SecondString,
1304   IN      UINTN                     Length
1305   )
1306 {
1307   if (Length == 0) {
1308     return 0;
1309   }
1310 
1311   //
1312   // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1313   //
1314   ASSERT (AsciiStrSize (FirstString));
1315   ASSERT (AsciiStrSize (SecondString));
1316 
1317   if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1318     ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
1319   }
1320 
1321   while ((*FirstString != '\0') &&
1322          (*SecondString != '\0') &&
1323          (*FirstString == *SecondString) &&
1324          (Length > 1)) {
1325     FirstString++;
1326     SecondString++;
1327     Length--;
1328   }
1329   return *FirstString - *SecondString;
1330 }
1331 
1332 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
1333 
1334 /**
1335   [ATTENTION] This function will be deprecated for security reason.
1336 
1337   Concatenates one Null-terminated ASCII string to another Null-terminated
1338   ASCII string, and returns the concatenated ASCII string.
1339 
1340   This function concatenates two Null-terminated ASCII strings. The contents of
1341   Null-terminated ASCII string Source are concatenated to the end of Null-
1342   terminated ASCII string Destination. The Null-terminated concatenated ASCII
1343   String is returned.
1344 
1345   If Destination is NULL, then ASSERT().
1346   If Source is NULL, then ASSERT().
1347   If PcdMaximumAsciiStringLength is not zero and Destination contains more than
1348   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1349   then ASSERT().
1350   If PcdMaximumAsciiStringLength is not zero and Source contains more than
1351   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1352   then ASSERT().
1353   If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
1354   Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1355   ASCII characters, then ASSERT().
1356 
1357   @param  Destination A pointer to a Null-terminated ASCII string.
1358   @param  Source      A pointer to a Null-terminated ASCII string.
1359 
1360   @return Destination
1361 
1362 **/
1363 CHAR8 *
1364 EFIAPI
AsciiStrCat(IN OUT CHAR8 * Destination,IN CONST CHAR8 * Source)1365 AsciiStrCat (
1366   IN OUT CHAR8    *Destination,
1367   IN CONST CHAR8  *Source
1368   )
1369 {
1370   AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);
1371 
1372   //
1373   // Size of the resulting string should never be zero.
1374   // PcdMaximumUnicodeStringLength is tested inside StrLen().
1375   //
1376   ASSERT (AsciiStrSize (Destination) != 0);
1377   return Destination;
1378 }
1379 
1380 /**
1381   [ATTENTION] This function will be deprecated for security reason.
1382 
1383   Concatenates up to a specified length one Null-terminated ASCII string to
1384   the end of another Null-terminated ASCII string, and returns the
1385   concatenated ASCII string.
1386 
1387   This function concatenates two Null-terminated ASCII strings. The contents
1388   of Null-terminated ASCII string Source are concatenated to the end of Null-
1389   terminated ASCII string Destination, and Destination is returned. At most,
1390   Length ASCII characters are concatenated from Source to the end of
1391   Destination, and Destination is always Null-terminated. If Length is 0, then
1392   Destination is returned unmodified. If Source and Destination overlap, then
1393   the results are undefined.
1394 
1395   If Length > 0 and Destination is NULL, then ASSERT().
1396   If Length > 0 and Source is NULL, then ASSERT().
1397   If Source and Destination overlap, then ASSERT().
1398   If PcdMaximumAsciiStringLength is not zero, and Length is greater than
1399   PcdMaximumAsciiStringLength, then ASSERT().
1400   If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
1401   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1402   then ASSERT().
1403   If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1404   PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
1405   then ASSERT().
1406   If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
1407   Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1408   ASCII characters, not including the Null-terminator, then ASSERT().
1409 
1410   @param  Destination A pointer to a Null-terminated ASCII string.
1411   @param  Source      A pointer to a Null-terminated ASCII string.
1412   @param  Length      The maximum number of ASCII characters to concatenate from
1413                       Source.
1414 
1415   @return Destination
1416 
1417 **/
1418 CHAR8 *
1419 EFIAPI
AsciiStrnCat(IN OUT CHAR8 * Destination,IN CONST CHAR8 * Source,IN UINTN Length)1420 AsciiStrnCat (
1421   IN OUT  CHAR8                     *Destination,
1422   IN      CONST CHAR8               *Source,
1423   IN      UINTN                     Length
1424   )
1425 {
1426   UINTN   DestinationLen;
1427 
1428   DestinationLen = AsciiStrLen (Destination);
1429   AsciiStrnCpy (Destination + DestinationLen, Source, Length);
1430   Destination[DestinationLen + Length] = '\0';
1431 
1432   //
1433   // Size of the resulting string should never be zero.
1434   // PcdMaximumUnicodeStringLength is tested inside StrLen().
1435   //
1436   ASSERT (AsciiStrSize (Destination) != 0);
1437   return Destination;
1438 }
1439 #endif
1440 
1441 /**
1442   Returns the first occurrence of a Null-terminated ASCII sub-string
1443   in a Null-terminated ASCII string.
1444 
1445   This function scans the contents of the ASCII string specified by String
1446   and returns the first occurrence of SearchString. If SearchString is not
1447   found in String, then NULL is returned. If the length of SearchString is zero,
1448   then String is returned.
1449 
1450   If String is NULL, then ASSERT().
1451   If SearchString is NULL, then ASSERT().
1452 
1453   If PcdMaximumAsciiStringLength is not zero, and SearchString or
1454   String contains more than PcdMaximumAsciiStringLength Unicode characters
1455   not including the Null-terminator, then ASSERT().
1456 
1457   @param  String          A pointer to a Null-terminated ASCII string.
1458   @param  SearchString    A pointer to a Null-terminated ASCII string to search for.
1459 
1460   @retval NULL            If the SearchString does not appear in String.
1461   @retval others          If there is a match return the first occurrence of SearchingString.
1462                           If the length of SearchString is zero,return String.
1463 
1464 **/
1465 CHAR8 *
1466 EFIAPI
AsciiStrStr(IN CONST CHAR8 * String,IN CONST CHAR8 * SearchString)1467 AsciiStrStr (
1468   IN      CONST CHAR8               *String,
1469   IN      CONST CHAR8               *SearchString
1470   )
1471 {
1472   CONST CHAR8 *FirstMatch;
1473   CONST CHAR8 *SearchStringTmp;
1474 
1475   //
1476   // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1477   //
1478   ASSERT (AsciiStrSize (String) != 0);
1479   ASSERT (AsciiStrSize (SearchString) != 0);
1480 
1481   if (*SearchString == '\0') {
1482     return (CHAR8 *) String;
1483   }
1484 
1485   while (*String != '\0') {
1486     SearchStringTmp = SearchString;
1487     FirstMatch = String;
1488 
1489     while ((*String == *SearchStringTmp)
1490             && (*String != '\0')) {
1491       String++;
1492       SearchStringTmp++;
1493     }
1494 
1495     if (*SearchStringTmp == '\0') {
1496       return (CHAR8 *) FirstMatch;
1497     }
1498 
1499     if (*String == '\0') {
1500       return NULL;
1501     }
1502 
1503     String = FirstMatch + 1;
1504   }
1505 
1506   return NULL;
1507 }
1508 
1509 /**
1510   Convert a Null-terminated ASCII decimal string to a value of type
1511   UINTN.
1512 
1513   This function returns a value of type UINTN by interpreting the contents
1514   of the ASCII string String as a decimal number. The format of the input
1515   ASCII string String is:
1516 
1517                     [spaces] [decimal digits].
1518 
1519   The valid decimal digit character is in the range [0-9]. The function will
1520   ignore the pad space, which includes spaces or tab characters, before the digits.
1521   The running zero in the beginning of [decimal digits] will be ignored. Then, the
1522   function stops at the first character that is a not a valid decimal character or
1523   Null-terminator, whichever on comes first.
1524 
1525   If String has only pad spaces, then 0 is returned.
1526   If String has no pad spaces or valid decimal digits, then 0 is returned.
1527   If the number represented by String overflows according to the range defined by
1528   UINTN, then MAX_UINTN is returned.
1529   If String is NULL, then ASSERT().
1530   If PcdMaximumAsciiStringLength is not zero, and String contains more than
1531   PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1532   then ASSERT().
1533 
1534   @param  String          A pointer to a Null-terminated ASCII string.
1535 
1536   @retval Value translated from String.
1537 
1538 **/
1539 UINTN
1540 EFIAPI
AsciiStrDecimalToUintn(IN CONST CHAR8 * String)1541 AsciiStrDecimalToUintn (
1542   IN      CONST CHAR8               *String
1543   )
1544 {
1545   UINTN     Result;
1546 
1547   AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result);
1548   return Result;
1549 }
1550 
1551 
1552 /**
1553   Convert a Null-terminated ASCII decimal string to a value of type
1554   UINT64.
1555 
1556   This function returns a value of type UINT64 by interpreting the contents
1557   of the ASCII string String as a decimal number. The format of the input
1558   ASCII string String is:
1559 
1560                     [spaces] [decimal digits].
1561 
1562   The valid decimal digit character is in the range [0-9]. The function will
1563   ignore the pad space, which includes spaces or tab characters, before the digits.
1564   The running zero in the beginning of [decimal digits] will be ignored. Then, the
1565   function stops at the first character that is a not a valid decimal character or
1566   Null-terminator, whichever on comes first.
1567 
1568   If String has only pad spaces, then 0 is returned.
1569   If String has no pad spaces or valid decimal digits, then 0 is returned.
1570   If the number represented by String overflows according to the range defined by
1571   UINT64, then MAX_UINT64 is returned.
1572   If String is NULL, then ASSERT().
1573   If PcdMaximumAsciiStringLength is not zero, and String contains more than
1574   PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1575   then ASSERT().
1576 
1577   @param  String          A pointer to a Null-terminated ASCII string.
1578 
1579   @retval Value translated from String.
1580 
1581 **/
1582 UINT64
1583 EFIAPI
AsciiStrDecimalToUint64(IN CONST CHAR8 * String)1584 AsciiStrDecimalToUint64 (
1585   IN      CONST CHAR8               *String
1586   )
1587 {
1588   UINT64     Result;
1589 
1590   AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result);
1591   return Result;
1592 }
1593 
1594 /**
1595   Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
1596 
1597   This function returns a value of type UINTN by interpreting the contents of
1598   the ASCII string String as a hexadecimal number. The format of the input ASCII
1599   string String is:
1600 
1601                   [spaces][zeros][x][hexadecimal digits].
1602 
1603   The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1604   The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1605   appears in the input string, it must be prefixed with at least one 0. The function
1606   will ignore the pad space, which includes spaces or tab characters, before [zeros],
1607   [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1608   will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1609   digit. Then, the function stops at the first character that is a not a valid
1610   hexadecimal character or Null-terminator, whichever on comes first.
1611 
1612   If String has only pad spaces, then 0 is returned.
1613   If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1614   0 is returned.
1615 
1616   If the number represented by String overflows according to the range defined by UINTN,
1617   then MAX_UINTN is returned.
1618   If String is NULL, then ASSERT().
1619   If PcdMaximumAsciiStringLength is not zero,
1620   and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1621   the Null-terminator, then ASSERT().
1622 
1623   @param  String          A pointer to a Null-terminated ASCII string.
1624 
1625   @retval Value translated from String.
1626 
1627 **/
1628 UINTN
1629 EFIAPI
AsciiStrHexToUintn(IN CONST CHAR8 * String)1630 AsciiStrHexToUintn (
1631   IN      CONST CHAR8               *String
1632   )
1633 {
1634   UINTN     Result;
1635 
1636   AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result);
1637   return Result;
1638 }
1639 
1640 
1641 /**
1642   Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
1643 
1644   This function returns a value of type UINT64 by interpreting the contents of
1645   the ASCII string String as a hexadecimal number. The format of the input ASCII
1646   string String is:
1647 
1648                   [spaces][zeros][x][hexadecimal digits].
1649 
1650   The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1651   The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1652   appears in the input string, it must be prefixed with at least one 0. The function
1653   will ignore the pad space, which includes spaces or tab characters, before [zeros],
1654   [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1655   will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1656   digit. Then, the function stops at the first character that is a not a valid
1657   hexadecimal character or Null-terminator, whichever on comes first.
1658 
1659   If String has only pad spaces, then 0 is returned.
1660   If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1661   0 is returned.
1662 
1663   If the number represented by String overflows according to the range defined by UINT64,
1664   then MAX_UINT64 is returned.
1665   If String is NULL, then ASSERT().
1666   If PcdMaximumAsciiStringLength is not zero,
1667   and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1668   the Null-terminator, then ASSERT().
1669 
1670   @param  String          A pointer to a Null-terminated ASCII string.
1671 
1672   @retval Value translated from String.
1673 
1674 **/
1675 UINT64
1676 EFIAPI
AsciiStrHexToUint64(IN CONST CHAR8 * String)1677 AsciiStrHexToUint64 (
1678   IN      CONST CHAR8                *String
1679   )
1680 {
1681   UINT64    Result;
1682 
1683   AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result);
1684   return Result;
1685 }
1686 
1687 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
1688 
1689 /**
1690   [ATTENTION] This function is deprecated for security reason.
1691 
1692   Convert one Null-terminated ASCII string to a Null-terminated
1693   Unicode string and returns the Unicode string.
1694 
1695   This function converts the contents of the ASCII string Source to the Unicode
1696   string Destination, and returns Destination.  The function terminates the
1697   Unicode string Destination by appending a Null-terminator character at the end.
1698   The caller is responsible to make sure Destination points to a buffer with size
1699   equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
1700 
1701   If Destination is NULL, then ASSERT().
1702   If Destination is not aligned on a 16-bit boundary, then ASSERT().
1703   If Source is NULL, then ASSERT().
1704   If Source and Destination overlap, then ASSERT().
1705   If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1706   PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1707   then ASSERT().
1708   If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
1709   PcdMaximumUnicodeStringLength ASCII characters not including the
1710   Null-terminator, then ASSERT().
1711 
1712   @param  Source        A pointer to a Null-terminated ASCII string.
1713   @param  Destination   A pointer to a Null-terminated Unicode string.
1714 
1715   @return Destination.
1716 
1717 **/
1718 CHAR16 *
1719 EFIAPI
AsciiStrToUnicodeStr(IN CONST CHAR8 * Source,OUT CHAR16 * Destination)1720 AsciiStrToUnicodeStr (
1721   IN      CONST CHAR8               *Source,
1722   OUT     CHAR16                    *Destination
1723   )
1724 {
1725   CHAR16                            *ReturnValue;
1726 
1727   ASSERT (Destination != NULL);
1728 
1729   //
1730   // ASSERT Source is less long than PcdMaximumAsciiStringLength
1731   //
1732   ASSERT (AsciiStrSize (Source) != 0);
1733 
1734   //
1735   // Source and Destination should not overlap
1736   //
1737   ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));
1738   ASSERT ((UINTN) (Source - (CHAR8 *) Destination) >= (AsciiStrSize (Source) * sizeof (CHAR16)));
1739 
1740 
1741   ReturnValue = Destination;
1742   while (*Source != '\0') {
1743     *(Destination++) = (CHAR16)(UINT8) *(Source++);
1744   }
1745   //
1746   // End the Destination with a NULL.
1747   //
1748   *Destination = '\0';
1749 
1750   //
1751   // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength
1752   //
1753   ASSERT (StrSize (ReturnValue) != 0);
1754 
1755   return ReturnValue;
1756 }
1757 
1758 #endif
1759 
1760 //
1761 // The basis for Base64 encoding is RFC 4686 https://tools.ietf.org/html/rfc4648
1762 //
1763 // RFC 4686 has a number of MAY and SHOULD cases.  This implementation chooses
1764 // the more restrictive versions for security concerns (see RFC 4686 section 3.3).
1765 //
1766 // A invalid character, if encountered during the decode operation, causes the data
1767 // to be rejected. In addition, the '=' padding character is only allowed at the end
1768 // of the Base64 encoded string.
1769 //
1770 #define BAD_V  99
1771 
1772 STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1773                                 "abcdefghijklmnopqrstuvwxyz"
1774                                 "0123456789+/";
1775 
1776 STATIC UINT8 DecodingTable[] = {
1777   //
1778   // Valid characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
1779   // Also, set '=' as a zero for decoding
1780   // 0  ,            1,           2,           3,            4,           5,            6,           7,           8,            9,           a,            b,            c,           d,            e,            f
1781   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //   0
1782   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  10
1783   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,     62,  BAD_V,  BAD_V,  BAD_V,     63,   //  20
1784      52,     53,     54,     55,     56,     57,     58,     59,     60,     61,  BAD_V,  BAD_V,  BAD_V,      0,  BAD_V,  BAD_V,   //  30
1785   BAD_V,      0,      1,      2,      3,      4,      5,      6,      7,      8,      9,     10,     11,     12,     13,     14,   //  40
1786      15,     16,     17,     18,     19,     20,     21,     22,     23,     24,     25,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  50
1787   BAD_V,     26,     27,     28,     29,     30,     31,     32,     33,     34,     35,     36,     37,     38,     39,     40,   //  60
1788      41,     42,     43,     44,     45,     46,     47,     48,     49,     50,     51,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  70
1789   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  80
1790   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  90
1791   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  a0
1792   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  b0
1793   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  c0
1794   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  d0
1795   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  d0
1796   BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V    //  f0
1797 };
1798 
1799 /**
1800   Convert binary data to a Base64 encoded ascii string based on RFC4648.
1801 
1802   Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.
1803   The Ascii string is produced by converting the data string specified by Source and SourceLength.
1804 
1805   @param Source            Input UINT8 data
1806   @param SourceLength      Number of UINT8 bytes of data
1807   @param Destination       Pointer to output string buffer
1808   @param DestinationSize   Size of ascii buffer. Set to 0 to get the size needed.
1809                            Caller is responsible for passing in buffer of DestinationSize
1810 
1811   @retval RETURN_SUCCESS             When ascii buffer is filled in.
1812   @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.
1813   @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).
1814   @retval RETURN_BUFFER_TOO_SMALL    If SourceLength is 0 and DestinationSize is <1.
1815   @retval RETURN_BUFFER_TOO_SMALL    If Destination is NULL or DestinationSize is smaller than required buffersize.
1816 
1817 **/
1818 RETURN_STATUS
1819 EFIAPI
Base64Encode(IN CONST UINT8 * Source,IN UINTN SourceLength,OUT CHAR8 * Destination OPTIONAL,IN OUT UINTN * DestinationSize)1820 Base64Encode (
1821   IN  CONST UINT8  *Source,
1822   IN        UINTN   SourceLength,
1823   OUT       CHAR8  *Destination   OPTIONAL,
1824   IN OUT    UINTN  *DestinationSize
1825   )
1826 {
1827 
1828   UINTN          RequiredSize;
1829   UINTN          Left;
1830 
1831   //
1832   // Check pointers, and SourceLength is valid
1833   //
1834   if ((Source == NULL) || (DestinationSize == NULL)) {
1835     return RETURN_INVALID_PARAMETER;
1836   }
1837 
1838   //
1839   // Allow for RFC 4648 test vector 1
1840   //
1841   if (SourceLength == 0) {
1842     if (*DestinationSize < 1) {
1843       *DestinationSize = 1;
1844       return RETURN_BUFFER_TOO_SMALL;
1845     }
1846     *DestinationSize = 1;
1847     *Destination = '\0';
1848     return RETURN_SUCCESS;
1849   }
1850 
1851   //
1852   // Check if SourceLength or  DestinationSize is valid
1853   //
1854   if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){
1855     return RETURN_INVALID_PARAMETER;
1856   }
1857 
1858   //
1859   // 4 ascii per 3 bytes + NULL
1860   //
1861   RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;
1862   if ((Destination == NULL) || *DestinationSize < RequiredSize) {
1863     *DestinationSize = RequiredSize;
1864     return RETURN_BUFFER_TOO_SMALL;
1865   }
1866 
1867   Left = SourceLength;
1868 
1869   //
1870   // Encode 24 bits (three bytes) into 4 ascii characters
1871   //
1872   while (Left >= 3) {
1873 
1874     *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2 ];
1875     *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
1876     *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];
1877     *Destination++ = EncodingTable[( Source[2] & 0x3f)];
1878     Left -= 3;
1879     Source += 3;
1880   }
1881 
1882   //
1883   // Handle the remainder, and add padding '=' characters as necessary.
1884   //
1885   switch (Left) {
1886     case 0:
1887 
1888       //
1889       // No bytes Left, done.
1890       //
1891       break;
1892     case 1:
1893 
1894       //
1895       // One more data byte, two pad characters
1896       //
1897       *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];
1898       *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];
1899       *Destination++ = '=';
1900       *Destination++ = '=';
1901       break;
1902     case 2:
1903 
1904       //
1905       // Two more data bytes, and one pad character
1906       //
1907       *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];
1908       *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
1909       *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];
1910       *Destination++ = '=';
1911       break;
1912     }
1913   //
1914   // Add terminating NULL
1915   //
1916   *Destination = '\0';
1917   return RETURN_SUCCESS;
1918 }
1919 
1920 /**
1921   Convert Base64 ascii string to binary data based on RFC4648.
1922 
1923   Produce Null-terminated binary data in the output buffer specified by Destination and DestinationSize.
1924   The binary data is produced by converting the Base64 ascii string specified by Source and SourceLength.
1925 
1926   @param Source            Input ASCII characters
1927   @param SourceLength      Number of ASCII characters
1928   @param Destination       Pointer to output buffer
1929   @param DestinationSize   Caller is responsible for passing in buffer of at least DestinationSize.
1930                            Set 0 to get the size needed. Set to bytes stored on return.
1931 
1932   @retval RETURN_SUCCESS             When binary buffer is filled in.
1933   @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.
1934   @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS -(UINTN)Destination ).
1935   @retval RETURN_INVALID_PARAMETER   If there is any invalid character in input stream.
1936   @retval RETURN_BUFFER_TOO_SMALL    If buffer length is smaller than required buffer size.
1937  **/
1938 RETURN_STATUS
1939 EFIAPI
Base64Decode(IN CONST CHAR8 * Source,IN UINTN SourceLength,OUT UINT8 * Destination OPTIONAL,IN OUT UINTN * DestinationSize)1940 Base64Decode (
1941   IN  CONST CHAR8  *Source,
1942   IN        UINTN   SourceLength,
1943   OUT       UINT8  *Destination   OPTIONAL,
1944   IN OUT    UINTN  *DestinationSize
1945   )
1946 {
1947 
1948   UINT32   Value;
1949   CHAR8    Chr;
1950   INTN     BufferSize;
1951   UINTN    SourceIndex;
1952   UINTN    DestinationIndex;
1953   UINTN    Index;
1954   UINTN    ActualSourceLength;
1955 
1956   //
1957   // Check pointers are not NULL
1958   //
1959   if ((Source == NULL) || (DestinationSize == NULL)) {
1960     return RETURN_INVALID_PARAMETER;
1961   }
1962 
1963   //
1964   // Check if SourceLength or  DestinationSize is valid
1965   //
1966   if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){
1967     return RETURN_INVALID_PARAMETER;
1968   }
1969 
1970   ActualSourceLength = 0;
1971   BufferSize = 0;
1972 
1973   //
1974   // Determine the actual number of valid characters in the string.
1975   // All invalid characters except selected white space characters,
1976   // will cause the Base64 string to be rejected. White space to allow
1977   // properly formatted XML will be ignored.
1978   //
1979   // See section 3.3 of RFC 4648.
1980   //
1981   for (SourceIndex = 0; SourceIndex < SourceLength; SourceIndex++) {
1982 
1983     //
1984     // '=' is part of the quantum
1985     //
1986     if (Source[SourceIndex] == '=') {
1987       ActualSourceLength++;
1988       BufferSize--;
1989 
1990       //
1991       // Only two '=' characters can be valid.
1992       //
1993       if (BufferSize < -2) {
1994         return RETURN_INVALID_PARAMETER;
1995       }
1996     }
1997     else {
1998       Chr = Source[SourceIndex];
1999       if (BAD_V != DecodingTable[(UINT8) Chr]) {
2000 
2001         //
2002         // The '=' characters are only valid at the end, so any
2003         // valid character after an '=', will be flagged as an error.
2004         //
2005         if (BufferSize < 0) {
2006           return RETURN_INVALID_PARAMETER;
2007         }
2008           ActualSourceLength++;
2009       }
2010         else {
2011 
2012         //
2013         // The reset of the decoder will ignore all invalid characters allowed here.
2014         // Ignoring selected white space is useful.  In this case, the decoder will
2015         // ignore ' ', '\t', '\n', and '\r'.
2016         //
2017         if ((Chr != ' ') &&(Chr != '\t') &&(Chr != '\n') &&(Chr != '\r')) {
2018           return RETURN_INVALID_PARAMETER;
2019         }
2020       }
2021     }
2022   }
2023 
2024   //
2025   // The Base64 character string must be a multiple of 4 character quantums.
2026   //
2027   if (ActualSourceLength % 4 != 0) {
2028     return RETURN_INVALID_PARAMETER;
2029   }
2030 
2031   BufferSize += ActualSourceLength / 4 * 3;
2032     if (BufferSize < 0) {
2033       return RETURN_INVALID_PARAMETER;
2034   }
2035 
2036   //
2037   // BufferSize is >= 0
2038   //
2039   if ((Destination == NULL) || (*DestinationSize < (UINTN) BufferSize)) {
2040     *DestinationSize = BufferSize;
2041     return RETURN_BUFFER_TOO_SMALL;
2042   }
2043 
2044   //
2045   // If no decodable characters, return a size of zero. RFC 4686 test vector 1.
2046   //
2047   if (ActualSourceLength == 0) {
2048     *DestinationSize = 0;
2049     return RETURN_SUCCESS;
2050   }
2051 
2052   //
2053   // Input data is verified to be a multiple of 4 valid charcters.  Process four
2054   // characters at a time. Uncounted (ie. invalid)  characters will be ignored.
2055   //
2056   for (SourceIndex = 0, DestinationIndex = 0; (SourceIndex < SourceLength) && (DestinationIndex < *DestinationSize); ) {
2057     Value = 0;
2058 
2059     //
2060     // Get 24 bits of data from 4 input characters, each character representing 6 bits
2061     //
2062     for (Index = 0; Index < 4; Index++) {
2063       do {
2064       Chr = DecodingTable[(UINT8) Source[SourceIndex++]];
2065       } while (Chr == BAD_V);
2066       Value <<= 6;
2067       Value |= (UINT32)Chr;
2068     }
2069 
2070     //
2071     // Store 3 bytes of binary data (24 bits)
2072     //
2073     *Destination++ = (UINT8) (Value >> 16);
2074     DestinationIndex++;
2075 
2076     //
2077     // Due to the '=' special cases for the two bytes at the end,
2078     // we have to check the length and not store the padding data
2079     //
2080     if (DestinationIndex++ < *DestinationSize) {
2081       *Destination++ = (UINT8) (Value >>  8);
2082     }
2083     if (DestinationIndex++ < *DestinationSize) {
2084       *Destination++ = (UINT8) Value;
2085     }
2086   }
2087 
2088   return RETURN_SUCCESS;
2089 }
2090 
2091 /**
2092   Converts an 8-bit value to an 8-bit BCD value.
2093 
2094   Converts the 8-bit value specified by Value to BCD. The BCD value is
2095   returned.
2096 
2097   If Value >= 100, then ASSERT().
2098 
2099   @param  Value The 8-bit value to convert to BCD. Range 0..99.
2100 
2101   @return The BCD value.
2102 
2103 **/
2104 UINT8
2105 EFIAPI
DecimalToBcd8(IN UINT8 Value)2106 DecimalToBcd8 (
2107   IN      UINT8                     Value
2108   )
2109 {
2110   ASSERT (Value < 100);
2111   return (UINT8) (((Value / 10) << 4) | (Value % 10));
2112 }
2113 
2114 /**
2115   Converts an 8-bit BCD value to an 8-bit value.
2116 
2117   Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
2118   value is returned.
2119 
2120   If Value >= 0xA0, then ASSERT().
2121   If (Value & 0x0F) >= 0x0A, then ASSERT().
2122 
2123   @param  Value The 8-bit BCD value to convert to an 8-bit value.
2124 
2125   @return The 8-bit value is returned.
2126 
2127 **/
2128 UINT8
2129 EFIAPI
BcdToDecimal8(IN UINT8 Value)2130 BcdToDecimal8 (
2131   IN      UINT8                     Value
2132   )
2133 {
2134   ASSERT (Value < 0xa0);
2135   ASSERT ((Value & 0xf) < 0xa);
2136   return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));
2137 }
2138