MdePkg/BaseLib: Add safe string functions [U|A]StrnTo[A|U]StrS
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
1 /** @file
2 Safe String functions.
3
4 Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BaseLibInternals.h"
16
17 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
18
19 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
20
21 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
22 do { \
23 ASSERT (Expression); \
24 if (!(Expression)) { \
25 return Status; \
26 } \
27 } while (FALSE)
28
29 /**
30 Returns if 2 memory blocks are overlapped.
31
32 @param Base1 Base address of 1st memory block.
33 @param Size1 Size of 1st memory block.
34 @param Base2 Base address of 2nd memory block.
35 @param Size2 Size of 2nd memory block.
36
37 @retval TRUE 2 memory blocks are overlapped.
38 @retval FALSE 2 memory blocks are not overlapped.
39 **/
40 BOOLEAN
41 InternalSafeStringIsOverlap (
42 IN VOID *Base1,
43 IN UINTN Size1,
44 IN VOID *Base2,
45 IN UINTN Size2
46 )
47 {
48 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
49 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
50 return TRUE;
51 }
52 return FALSE;
53 }
54
55 /**
56 Returns if 2 Unicode strings are not overlapped.
57
58 @param Str1 Start address of 1st Unicode string.
59 @param Size1 The number of char in 1st Unicode string,
60 including terminating null char.
61 @param Str2 Start address of 2nd Unicode string.
62 @param Size2 The number of char in 2nd Unicode string,
63 including terminating null char.
64
65 @retval TRUE 2 Unicode strings are NOT overlapped.
66 @retval FALSE 2 Unicode strings are overlapped.
67 **/
68 BOOLEAN
69 InternalSafeStringNoStrOverlap (
70 IN CHAR16 *Str1,
71 IN UINTN Size1,
72 IN CHAR16 *Str2,
73 IN UINTN Size2
74 )
75 {
76 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
77 }
78
79 /**
80 Returns if 2 Ascii strings are not overlapped.
81
82 @param Str1 Start address of 1st Ascii string.
83 @param Size1 The number of char in 1st Ascii string,
84 including terminating null char.
85 @param Str2 Start address of 2nd Ascii string.
86 @param Size2 The number of char in 2nd Ascii string,
87 including terminating null char.
88
89 @retval TRUE 2 Ascii strings are NOT overlapped.
90 @retval FALSE 2 Ascii strings are overlapped.
91 **/
92 BOOLEAN
93 InternalSafeStringNoAsciiStrOverlap (
94 IN CHAR8 *Str1,
95 IN UINTN Size1,
96 IN CHAR8 *Str2,
97 IN UINTN Size2
98 )
99 {
100 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);
101 }
102
103 /**
104 Returns the length of a Null-terminated Unicode string.
105
106 This function is similar as strlen_s defined in C11.
107
108 If String is not aligned on a 16-bit boundary, then ASSERT().
109
110 @param String A pointer to a Null-terminated Unicode string.
111 @param MaxSize The maximum number of Destination Unicode
112 char, including terminating null char.
113
114 @retval 0 If String is NULL.
115 @retval MaxSize If there is no null character in the first MaxSize characters of String.
116 @return The number of characters that percede the terminating null character.
117
118 **/
119 UINTN
120 EFIAPI
121 StrnLenS (
122 IN CONST CHAR16 *String,
123 IN UINTN MaxSize
124 )
125 {
126 UINTN Length;
127
128 ASSERT (((UINTN) String & BIT0) == 0);
129
130 //
131 // If String is a null pointer, then the StrnLenS function returns zero.
132 //
133 if (String == NULL) {
134 return 0;
135 }
136
137 //
138 // Otherwise, the StrnLenS function returns the number of characters that precede the
139 // terminating null character. If there is no null character in the first MaxSize characters of
140 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
141 // be accessed by StrnLenS.
142 //
143 Length = 0;
144 while (String[Length] != 0) {
145 if (Length >= MaxSize - 1) {
146 return MaxSize;
147 }
148 Length++;
149 }
150 return Length;
151 }
152
153 /**
154 Returns the size of a Null-terminated Unicode string in bytes, including the
155 Null terminator.
156
157 This function returns the size of the Null-terminated Unicode string
158 specified by String in bytes, including the Null terminator.
159
160 If String is not aligned on a 16-bit boundary, then ASSERT().
161
162 @param String A pointer to a Null-terminated Unicode string.
163 @param MaxSize The maximum number of Destination Unicode
164 char, including the Null terminator.
165
166 @retval 0 If String is NULL.
167 @retval (sizeof (CHAR16) * (MaxSize + 1))
168 If there is no Null terminator in the first MaxSize characters of
169 String.
170 @return The size of the Null-terminated Unicode string in bytes, including
171 the Null terminator.
172
173 **/
174 UINTN
175 EFIAPI
176 StrnSizeS (
177 IN CONST CHAR16 *String,
178 IN UINTN MaxSize
179 )
180 {
181 //
182 // If String is a null pointer, then the StrnSizeS function returns zero.
183 //
184 if (String == NULL) {
185 return 0;
186 }
187
188 //
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
190 // Unicode string in bytes, including the Null terminator. If there is no
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
193 // the StrnLenS function.
194 //
195 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);
196 }
197
198 /**
199 Copies the string pointed to by Source (including the terminating null char)
200 to the array pointed to by Destination.
201
202 This function is similar as strcpy_s defined in C11.
203
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().
205 If Source is not aligned on a 16-bit boundary, then ASSERT().
206 If an error would be returned, then the function will also ASSERT().
207
208 If an error is returned, then the Destination is unmodified.
209
210 @param Destination A pointer to a Null-terminated Unicode string.
211 @param DestMax The maximum number of Destination Unicode
212 char, including terminating null char.
213 @param Source A pointer to a Null-terminated Unicode string.
214
215 @retval RETURN_SUCCESS String is copied.
216 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
217 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
218 If Source is NULL.
219 If PcdMaximumUnicodeStringLength is not zero,
220 and DestMax is greater than
221 PcdMaximumUnicodeStringLength.
222 If DestMax is 0.
223 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
224 **/
225 RETURN_STATUS
226 EFIAPI
227 StrCpyS (
228 OUT CHAR16 *Destination,
229 IN UINTN DestMax,
230 IN CONST CHAR16 *Source
231 )
232 {
233 UINTN SourceLen;
234
235 ASSERT (((UINTN) Destination & BIT0) == 0);
236 ASSERT (((UINTN) Source & BIT0) == 0);
237
238 //
239 // 1. Neither Destination nor Source shall be a null pointer.
240 //
241 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
242 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
243
244 //
245 // 2. DestMax shall not be greater than RSIZE_MAX.
246 //
247 if (RSIZE_MAX != 0) {
248 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
249 }
250
251 //
252 // 3. DestMax shall not equal zero.
253 //
254 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
255
256 //
257 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
258 //
259 SourceLen = StrnLenS (Source, DestMax);
260 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
261
262 //
263 // 5. Copying shall not take place between objects that overlap.
264 //
265 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
266
267 //
268 // The StrCpyS function copies the string pointed to by Source (including the terminating
269 // null character) into the array pointed to by Destination.
270 //
271 while (*Source != 0) {
272 *(Destination++) = *(Source++);
273 }
274 *Destination = 0;
275
276 return RETURN_SUCCESS;
277 }
278
279 /**
280 Copies not more than Length successive char from the string pointed to by
281 Source to the array pointed to by Destination. If no null char is copied from
282 Source, then Destination[Length] is always set to null.
283
284 This function is similar as strncpy_s defined in C11.
285
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
288 If an error would be returned, then the function will also ASSERT().
289
290 If an error is returned, then the Destination is unmodified.
291
292 @param Destination A pointer to a Null-terminated Unicode string.
293 @param DestMax The maximum number of Destination Unicode
294 char, including terminating null char.
295 @param Source A pointer to a Null-terminated Unicode string.
296 @param Length The maximum number of Unicode characters to copy.
297
298 @retval RETURN_SUCCESS String is copied.
299 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
300 MIN(StrLen(Source), Length).
301 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
302 If Source is NULL.
303 If PcdMaximumUnicodeStringLength is not zero,
304 and DestMax is greater than
305 PcdMaximumUnicodeStringLength.
306 If DestMax is 0.
307 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
308 **/
309 RETURN_STATUS
310 EFIAPI
311 StrnCpyS (
312 OUT CHAR16 *Destination,
313 IN UINTN DestMax,
314 IN CONST CHAR16 *Source,
315 IN UINTN Length
316 )
317 {
318 UINTN SourceLen;
319
320 ASSERT (((UINTN) Destination & BIT0) == 0);
321 ASSERT (((UINTN) Source & BIT0) == 0);
322
323 //
324 // 1. Neither Destination nor Source shall be a null pointer.
325 //
326 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
327 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
328
329 //
330 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
331 //
332 if (RSIZE_MAX != 0) {
333 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
334 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
335 }
336
337 //
338 // 3. DestMax shall not equal zero.
339 //
340 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
341
342 //
343 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
344 //
345 SourceLen = StrnLenS (Source, DestMax);
346 if (Length >= DestMax) {
347 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
348 }
349
350 //
351 // 5. Copying shall not take place between objects that overlap.
352 //
353 if (SourceLen > Length) {
354 SourceLen = Length;
355 }
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
357
358 //
359 // The StrnCpyS function copies not more than Length successive characters (characters that
360 // follow a null character are not copied) from the array pointed to by Source to the array
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
362 // character.
363 //
364 while ((*Source != 0) && (SourceLen > 0)) {
365 *(Destination++) = *(Source++);
366 SourceLen--;
367 }
368 *Destination = 0;
369
370 return RETURN_SUCCESS;
371 }
372
373 /**
374 Appends a copy of the string pointed to by Source (including the terminating
375 null char) to the end of the string pointed to by Destination.
376
377 This function is similar as strcat_s defined in C11.
378
379 If Destination is not aligned on a 16-bit boundary, then ASSERT().
380 If Source is not aligned on a 16-bit boundary, then ASSERT().
381 If an error would be returned, then the function will also ASSERT().
382
383 If an error is returned, then the Destination is unmodified.
384
385 @param Destination A pointer to a Null-terminated Unicode string.
386 @param DestMax The maximum number of Destination Unicode
387 char, including terminating null char.
388 @param Source A pointer to a Null-terminated Unicode string.
389
390 @retval RETURN_SUCCESS String is appended.
391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
392 StrLen(Destination).
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
394 greater than StrLen(Source).
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
396 If Source is NULL.
397 If PcdMaximumUnicodeStringLength is not zero,
398 and DestMax is greater than
399 PcdMaximumUnicodeStringLength.
400 If DestMax is 0.
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
402 **/
403 RETURN_STATUS
404 EFIAPI
405 StrCatS (
406 IN OUT CHAR16 *Destination,
407 IN UINTN DestMax,
408 IN CONST CHAR16 *Source
409 )
410 {
411 UINTN DestLen;
412 UINTN CopyLen;
413 UINTN SourceLen;
414
415 ASSERT (((UINTN) Destination & BIT0) == 0);
416 ASSERT (((UINTN) Source & BIT0) == 0);
417
418 //
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
420 //
421 DestLen = StrnLenS (Destination, DestMax);
422 CopyLen = DestMax - DestLen;
423
424 //
425 // 1. Neither Destination nor Source shall be a null pointer.
426 //
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
428 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
429
430 //
431 // 2. DestMax shall not be greater than RSIZE_MAX.
432 //
433 if (RSIZE_MAX != 0) {
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
435 }
436
437 //
438 // 3. DestMax shall not equal zero.
439 //
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
441
442 //
443 // 4. CopyLen shall not equal zero.
444 //
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
446
447 //
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
449 //
450 SourceLen = StrnLenS (Source, CopyLen);
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
452
453 //
454 // 6. Copying shall not take place between objects that overlap.
455 //
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
457
458 //
459 // The StrCatS function appends a copy of the string pointed to by Source (including the
460 // terminating null character) to the end of the string pointed to by Destination. The initial character
461 // from Source overwrites the null character at the end of Destination.
462 //
463 Destination = Destination + DestLen;
464 while (*Source != 0) {
465 *(Destination++) = *(Source++);
466 }
467 *Destination = 0;
468
469 return RETURN_SUCCESS;
470 }
471
472 /**
473 Appends not more than Length successive char from the string pointed to by
474 Source to the end of the string pointed to by Destination. If no null char is
475 copied from Source, then Destination[StrLen(Destination) + Length] is always
476 set to null.
477
478 This function is similar as strncat_s defined in C11.
479
480 If Destination is not aligned on a 16-bit boundary, then ASSERT().
481 If Source is not aligned on a 16-bit boundary, then ASSERT().
482 If an error would be returned, then the function will also ASSERT().
483
484 If an error is returned, then the Destination is unmodified.
485
486 @param Destination A pointer to a Null-terminated Unicode string.
487 @param DestMax The maximum number of Destination Unicode
488 char, including terminating null char.
489 @param Source A pointer to a Null-terminated Unicode string.
490 @param Length The maximum number of Unicode characters to copy.
491
492 @retval RETURN_SUCCESS String is appended.
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
494 StrLen(Destination).
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
496 greater than MIN(StrLen(Source), Length).
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
498 If Source is NULL.
499 If PcdMaximumUnicodeStringLength is not zero,
500 and DestMax is greater than
501 PcdMaximumUnicodeStringLength.
502 If DestMax is 0.
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
504 **/
505 RETURN_STATUS
506 EFIAPI
507 StrnCatS (
508 IN OUT CHAR16 *Destination,
509 IN UINTN DestMax,
510 IN CONST CHAR16 *Source,
511 IN UINTN Length
512 )
513 {
514 UINTN DestLen;
515 UINTN CopyLen;
516 UINTN SourceLen;
517
518 ASSERT (((UINTN) Destination & BIT0) == 0);
519 ASSERT (((UINTN) Source & BIT0) == 0);
520
521 //
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
523 //
524 DestLen = StrnLenS (Destination, DestMax);
525 CopyLen = DestMax - DestLen;
526
527 //
528 // 1. Neither Destination nor Source shall be a null pointer.
529 //
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
531 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
532
533 //
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
535 //
536 if (RSIZE_MAX != 0) {
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
538 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
539 }
540
541 //
542 // 3. DestMax shall not equal zero.
543 //
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
545
546 //
547 // 4. CopyLen shall not equal zero.
548 //
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
550
551 //
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
553 //
554 SourceLen = StrnLenS (Source, CopyLen);
555 if (Length >= CopyLen) {
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
557 }
558
559 //
560 // 6. Copying shall not take place between objects that overlap.
561 //
562 if (SourceLen > Length) {
563 SourceLen = Length;
564 }
565 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
566
567 //
568 // The StrnCatS function appends not more than Length successive characters (characters
569 // that follow a null character are not copied) from the array pointed to by Source to the end of
570 // the string pointed to by Destination. The initial character from Source overwrites the null character at
571 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
572 // a null character.
573 //
574 Destination = Destination + DestLen;
575 while ((*Source != 0) && (SourceLen > 0)) {
576 *(Destination++) = *(Source++);
577 SourceLen--;
578 }
579 *Destination = 0;
580
581 return RETURN_SUCCESS;
582 }
583
584 /**
585 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
586
587 This function outputs a value of type UINTN by interpreting the contents of
588 the Unicode string specified by String as a decimal number. The format of the
589 input Unicode string String is:
590
591 [spaces] [decimal digits].
592
593 The valid decimal digit character is in the range [0-9]. The function will
594 ignore the pad space, which includes spaces or tab characters, before
595 [decimal digits]. The running zero in the beginning of [decimal digits] will
596 be ignored. Then, the function stops at the first character that is a not a
597 valid decimal character or a Null-terminator, whichever one comes first.
598
599 If String is NULL, then ASSERT().
600 If Data is NULL, then ASSERT().
601 If String is not aligned in a 16-bit boundary, then ASSERT().
602 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
603 PcdMaximumUnicodeStringLength Unicode characters, not including the
604 Null-terminator, then ASSERT().
605
606 If String has no valid decimal digits in the above format, then 0 is stored
607 at the location pointed to by Data.
608 If the number represented by String exceeds the range defined by UINTN, then
609 MAX_UINTN is stored at the location pointed to by Data.
610
611 If EndPointer is not NULL, a pointer to the character that stopped the scan
612 is stored at the location pointed to by EndPointer. If String has no valid
613 decimal digits right after the optional pad spaces, the value of String is
614 stored at the location pointed to by EndPointer.
615
616 @param String Pointer to a Null-terminated Unicode string.
617 @param EndPointer Pointer to character that stops scan.
618 @param Data Pointer to the converted value.
619
620 @retval RETURN_SUCCESS Value is translated from String.
621 @retval RETURN_INVALID_PARAMETER If String is NULL.
622 If Data is NULL.
623 If PcdMaximumUnicodeStringLength is not
624 zero, and String contains more than
625 PcdMaximumUnicodeStringLength Unicode
626 characters, not including the
627 Null-terminator.
628 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
629 the range defined by UINTN.
630
631 **/
632 RETURN_STATUS
633 EFIAPI
634 StrDecimalToUintnS (
635 IN CONST CHAR16 *String,
636 OUT CHAR16 **EndPointer, OPTIONAL
637 OUT UINTN *Data
638 )
639 {
640 ASSERT (((UINTN) String & BIT0) == 0);
641
642 //
643 // 1. Neither String nor Data shall be a null pointer.
644 //
645 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
646 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
647
648 //
649 // 2. The length of String shall not be greater than RSIZE_MAX.
650 //
651 if (RSIZE_MAX != 0) {
652 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
653 }
654
655 if (EndPointer != NULL) {
656 *EndPointer = (CHAR16 *) String;
657 }
658
659 //
660 // Ignore the pad spaces (space or tab)
661 //
662 while ((*String == L' ') || (*String == L'\t')) {
663 String++;
664 }
665
666 //
667 // Ignore leading Zeros after the spaces
668 //
669 while (*String == L'0') {
670 String++;
671 }
672
673 *Data = 0;
674
675 while (InternalIsDecimalDigitCharacter (*String)) {
676 //
677 // If the number represented by String overflows according to the range
678 // defined by UINTN, then MAX_UINTN is stored in *Data and
679 // RETURN_UNSUPPORTED is returned.
680 //
681 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {
682 *Data = MAX_UINTN;
683 if (EndPointer != NULL) {
684 *EndPointer = (CHAR16 *) String;
685 }
686 return RETURN_UNSUPPORTED;
687 }
688
689 *Data = *Data * 10 + (*String - L'0');
690 String++;
691 }
692
693 if (EndPointer != NULL) {
694 *EndPointer = (CHAR16 *) String;
695 }
696 return RETURN_SUCCESS;
697 }
698
699 /**
700 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
701
702 This function outputs a value of type UINT64 by interpreting the contents of
703 the Unicode string specified by String as a decimal number. The format of the
704 input Unicode string String is:
705
706 [spaces] [decimal digits].
707
708 The valid decimal digit character is in the range [0-9]. The function will
709 ignore the pad space, which includes spaces or tab characters, before
710 [decimal digits]. The running zero in the beginning of [decimal digits] will
711 be ignored. Then, the function stops at the first character that is a not a
712 valid decimal character or a Null-terminator, whichever one comes first.
713
714 If String is NULL, then ASSERT().
715 If Data is NULL, then ASSERT().
716 If String is not aligned in a 16-bit boundary, then ASSERT().
717 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
718 PcdMaximumUnicodeStringLength Unicode characters, not including the
719 Null-terminator, then ASSERT().
720
721 If String has no valid decimal digits in the above format, then 0 is stored
722 at the location pointed to by Data.
723 If the number represented by String exceeds the range defined by UINT64, then
724 MAX_UINT64 is stored at the location pointed to by Data.
725
726 If EndPointer is not NULL, a pointer to the character that stopped the scan
727 is stored at the location pointed to by EndPointer. If String has no valid
728 decimal digits right after the optional pad spaces, the value of String is
729 stored at the location pointed to by EndPointer.
730
731 @param String Pointer to a Null-terminated Unicode string.
732 @param EndPointer Pointer to character that stops scan.
733 @param Data Pointer to the converted value.
734
735 @retval RETURN_SUCCESS Value is translated from String.
736 @retval RETURN_INVALID_PARAMETER If String is NULL.
737 If Data is NULL.
738 If PcdMaximumUnicodeStringLength is not
739 zero, and String contains more than
740 PcdMaximumUnicodeStringLength Unicode
741 characters, not including the
742 Null-terminator.
743 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
744 the range defined by UINT64.
745
746 **/
747 RETURN_STATUS
748 EFIAPI
749 StrDecimalToUint64S (
750 IN CONST CHAR16 *String,
751 OUT CHAR16 **EndPointer, OPTIONAL
752 OUT UINT64 *Data
753 )
754 {
755 ASSERT (((UINTN) String & BIT0) == 0);
756
757 //
758 // 1. Neither String nor Data shall be a null pointer.
759 //
760 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
761 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
762
763 //
764 // 2. The length of String shall not be greater than RSIZE_MAX.
765 //
766 if (RSIZE_MAX != 0) {
767 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
768 }
769
770 if (EndPointer != NULL) {
771 *EndPointer = (CHAR16 *) String;
772 }
773
774 //
775 // Ignore the pad spaces (space or tab)
776 //
777 while ((*String == L' ') || (*String == L'\t')) {
778 String++;
779 }
780
781 //
782 // Ignore leading Zeros after the spaces
783 //
784 while (*String == L'0') {
785 String++;
786 }
787
788 *Data = 0;
789
790 while (InternalIsDecimalDigitCharacter (*String)) {
791 //
792 // If the number represented by String overflows according to the range
793 // defined by UINT64, then MAX_UINT64 is stored in *Data and
794 // RETURN_UNSUPPORTED is returned.
795 //
796 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {
797 *Data = MAX_UINT64;
798 if (EndPointer != NULL) {
799 *EndPointer = (CHAR16 *) String;
800 }
801 return RETURN_UNSUPPORTED;
802 }
803
804 *Data = MultU64x32 (*Data, 10) + (*String - L'0');
805 String++;
806 }
807
808 if (EndPointer != NULL) {
809 *EndPointer = (CHAR16 *) String;
810 }
811 return RETURN_SUCCESS;
812 }
813
814 /**
815 Convert a Null-terminated Unicode hexadecimal string to a value of type
816 UINTN.
817
818 This function outputs a value of type UINTN by interpreting the contents of
819 the Unicode string specified by String as a hexadecimal number. The format of
820 the input Unicode string String is:
821
822 [spaces][zeros][x][hexadecimal digits].
823
824 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
825 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
826 If "x" appears in the input string, it must be prefixed with at least one 0.
827 The function will ignore the pad space, which includes spaces or tab
828 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
829 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
830 after [x] or the first valid hexadecimal digit. Then, the function stops at
831 the first character that is a not a valid hexadecimal character or NULL,
832 whichever one comes first.
833
834 If String is NULL, then ASSERT().
835 If Data is NULL, then ASSERT().
836 If String is not aligned in a 16-bit boundary, then ASSERT().
837 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
838 PcdMaximumUnicodeStringLength Unicode characters, not including the
839 Null-terminator, then ASSERT().
840
841 If String has no valid hexadecimal digits in the above format, then 0 is
842 stored at the location pointed to by Data.
843 If the number represented by String exceeds the range defined by UINTN, then
844 MAX_UINTN is stored at the location pointed to by Data.
845
846 If EndPointer is not NULL, a pointer to the character that stopped the scan
847 is stored at the location pointed to by EndPointer. If String has no valid
848 hexadecimal digits right after the optional pad spaces, the value of String
849 is stored at the location pointed to by EndPointer.
850
851 @param String Pointer to a Null-terminated Unicode string.
852 @param EndPointer Pointer to character that stops scan.
853 @param Data Pointer to the converted value.
854
855 @retval RETURN_SUCCESS Value is translated from String.
856 @retval RETURN_INVALID_PARAMETER If String is NULL.
857 If Data is NULL.
858 If PcdMaximumUnicodeStringLength is not
859 zero, and String contains more than
860 PcdMaximumUnicodeStringLength Unicode
861 characters, not including the
862 Null-terminator.
863 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
864 the range defined by UINTN.
865
866 **/
867 RETURN_STATUS
868 EFIAPI
869 StrHexToUintnS (
870 IN CONST CHAR16 *String,
871 OUT CHAR16 **EndPointer, OPTIONAL
872 OUT UINTN *Data
873 )
874 {
875 ASSERT (((UINTN) String & BIT0) == 0);
876
877 //
878 // 1. Neither String nor Data shall be a null pointer.
879 //
880 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
881 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
882
883 //
884 // 2. The length of String shall not be greater than RSIZE_MAX.
885 //
886 if (RSIZE_MAX != 0) {
887 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
888 }
889
890 if (EndPointer != NULL) {
891 *EndPointer = (CHAR16 *) String;
892 }
893
894 //
895 // Ignore the pad spaces (space or tab)
896 //
897 while ((*String == L' ') || (*String == L'\t')) {
898 String++;
899 }
900
901 //
902 // Ignore leading Zeros after the spaces
903 //
904 while (*String == L'0') {
905 String++;
906 }
907
908 if (InternalCharToUpper (*String) == L'X') {
909 if (*(String - 1) != L'0') {
910 *Data = 0;
911 return RETURN_SUCCESS;
912 }
913 //
914 // Skip the 'X'
915 //
916 String++;
917 }
918
919 *Data = 0;
920
921 while (InternalIsHexaDecimalDigitCharacter (*String)) {
922 //
923 // If the number represented by String overflows according to the range
924 // defined by UINTN, then MAX_UINTN is stored in *Data and
925 // RETURN_UNSUPPORTED is returned.
926 //
927 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {
928 *Data = MAX_UINTN;
929 if (EndPointer != NULL) {
930 *EndPointer = (CHAR16 *) String;
931 }
932 return RETURN_UNSUPPORTED;
933 }
934
935 *Data = (*Data << 4) + InternalHexCharToUintn (*String);
936 String++;
937 }
938
939 if (EndPointer != NULL) {
940 *EndPointer = (CHAR16 *) String;
941 }
942 return RETURN_SUCCESS;
943 }
944
945 /**
946 Convert a Null-terminated Unicode hexadecimal string to a value of type
947 UINT64.
948
949 This function outputs a value of type UINT64 by interpreting the contents of
950 the Unicode string specified by String as a hexadecimal number. The format of
951 the input Unicode string String is:
952
953 [spaces][zeros][x][hexadecimal digits].
954
955 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
956 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
957 If "x" appears in the input string, it must be prefixed with at least one 0.
958 The function will ignore the pad space, which includes spaces or tab
959 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
960 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
961 after [x] or the first valid hexadecimal digit. Then, the function stops at
962 the first character that is a not a valid hexadecimal character or NULL,
963 whichever one comes first.
964
965 If String is NULL, then ASSERT().
966 If Data is NULL, then ASSERT().
967 If String is not aligned in a 16-bit boundary, then ASSERT().
968 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
969 PcdMaximumUnicodeStringLength Unicode characters, not including the
970 Null-terminator, then ASSERT().
971
972 If String has no valid hexadecimal digits in the above format, then 0 is
973 stored at the location pointed to by Data.
974 If the number represented by String exceeds the range defined by UINT64, then
975 MAX_UINT64 is stored at the location pointed to by Data.
976
977 If EndPointer is not NULL, a pointer to the character that stopped the scan
978 is stored at the location pointed to by EndPointer. If String has no valid
979 hexadecimal digits right after the optional pad spaces, the value of String
980 is stored at the location pointed to by EndPointer.
981
982 @param String Pointer to a Null-terminated Unicode string.
983 @param EndPointer Pointer to character that stops scan.
984 @param Data Pointer to the converted value.
985
986 @retval RETURN_SUCCESS Value is translated from String.
987 @retval RETURN_INVALID_PARAMETER If String is NULL.
988 If Data is NULL.
989 If PcdMaximumUnicodeStringLength is not
990 zero, and String contains more than
991 PcdMaximumUnicodeStringLength Unicode
992 characters, not including the
993 Null-terminator.
994 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
995 the range defined by UINT64.
996
997 **/
998 RETURN_STATUS
999 EFIAPI
1000 StrHexToUint64S (
1001 IN CONST CHAR16 *String,
1002 OUT CHAR16 **EndPointer, OPTIONAL
1003 OUT UINT64 *Data
1004 )
1005 {
1006 ASSERT (((UINTN) String & BIT0) == 0);
1007
1008 //
1009 // 1. Neither String nor Data shall be a null pointer.
1010 //
1011 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1012 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1013
1014 //
1015 // 2. The length of String shall not be greater than RSIZE_MAX.
1016 //
1017 if (RSIZE_MAX != 0) {
1018 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1019 }
1020
1021 if (EndPointer != NULL) {
1022 *EndPointer = (CHAR16 *) String;
1023 }
1024
1025 //
1026 // Ignore the pad spaces (space or tab)
1027 //
1028 while ((*String == L' ') || (*String == L'\t')) {
1029 String++;
1030 }
1031
1032 //
1033 // Ignore leading Zeros after the spaces
1034 //
1035 while (*String == L'0') {
1036 String++;
1037 }
1038
1039 if (InternalCharToUpper (*String) == L'X') {
1040 if (*(String - 1) != L'0') {
1041 *Data = 0;
1042 return RETURN_SUCCESS;
1043 }
1044 //
1045 // Skip the 'X'
1046 //
1047 String++;
1048 }
1049
1050 *Data = 0;
1051
1052 while (InternalIsHexaDecimalDigitCharacter (*String)) {
1053 //
1054 // If the number represented by String overflows according to the range
1055 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1056 // RETURN_UNSUPPORTED is returned.
1057 //
1058 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {
1059 *Data = MAX_UINT64;
1060 if (EndPointer != NULL) {
1061 *EndPointer = (CHAR16 *) String;
1062 }
1063 return RETURN_UNSUPPORTED;
1064 }
1065
1066 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);
1067 String++;
1068 }
1069
1070 if (EndPointer != NULL) {
1071 *EndPointer = (CHAR16 *) String;
1072 }
1073 return RETURN_SUCCESS;
1074 }
1075
1076 /**
1077 Returns the length of a Null-terminated Ascii string.
1078
1079 This function is similar as strlen_s defined in C11.
1080
1081 @param String A pointer to a Null-terminated Ascii string.
1082 @param MaxSize The maximum number of Destination Ascii
1083 char, including terminating null char.
1084
1085 @retval 0 If String is NULL.
1086 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1087 @return The number of characters that percede the terminating null character.
1088
1089 **/
1090 UINTN
1091 EFIAPI
1092 AsciiStrnLenS (
1093 IN CONST CHAR8 *String,
1094 IN UINTN MaxSize
1095 )
1096 {
1097 UINTN Length;
1098
1099 //
1100 // If String is a null pointer, then the AsciiStrnLenS function returns zero.
1101 //
1102 if (String == NULL) {
1103 return 0;
1104 }
1105
1106 //
1107 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1108 // terminating null character. If there is no null character in the first MaxSize characters of
1109 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1110 // be accessed by AsciiStrnLenS.
1111 //
1112 Length = 0;
1113 while (String[Length] != 0) {
1114 if (Length >= MaxSize - 1) {
1115 return MaxSize;
1116 }
1117 Length++;
1118 }
1119 return Length;
1120 }
1121
1122 /**
1123 Returns the size of a Null-terminated Ascii string in bytes, including the
1124 Null terminator.
1125
1126 This function returns the size of the Null-terminated Ascii string specified
1127 by String in bytes, including the Null terminator.
1128
1129 @param String A pointer to a Null-terminated Ascii string.
1130 @param MaxSize The maximum number of Destination Ascii
1131 char, including the Null terminator.
1132
1133 @retval 0 If String is NULL.
1134 @retval (sizeof (CHAR8) * (MaxSize + 1))
1135 If there is no Null terminator in the first MaxSize characters of
1136 String.
1137 @return The size of the Null-terminated Ascii string in bytes, including the
1138 Null terminator.
1139
1140 **/
1141 UINTN
1142 EFIAPI
1143 AsciiStrnSizeS (
1144 IN CONST CHAR8 *String,
1145 IN UINTN MaxSize
1146 )
1147 {
1148 //
1149 // If String is a null pointer, then the AsciiStrnSizeS function returns
1150 // zero.
1151 //
1152 if (String == NULL) {
1153 return 0;
1154 }
1155
1156 //
1157 // Otherwise, the AsciiStrnSizeS function returns the size of the
1158 // Null-terminated Ascii string in bytes, including the Null terminator. If
1159 // there is no Null terminator in the first MaxSize characters of String,
1160 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1161 // consistent map with the AsciiStrnLenS function.
1162 //
1163 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
1164 }
1165
1166 /**
1167 Copies the string pointed to by Source (including the terminating null char)
1168 to the array pointed to by Destination.
1169
1170 This function is similar as strcpy_s defined in C11.
1171
1172 If an error would be returned, then the function will also ASSERT().
1173
1174 If an error is returned, then the Destination is unmodified.
1175
1176 @param Destination A pointer to a Null-terminated Ascii string.
1177 @param DestMax The maximum number of Destination Ascii
1178 char, including terminating null char.
1179 @param Source A pointer to a Null-terminated Ascii string.
1180
1181 @retval RETURN_SUCCESS String is copied.
1182 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1183 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1184 If Source is NULL.
1185 If PcdMaximumAsciiStringLength is not zero,
1186 and DestMax is greater than
1187 PcdMaximumAsciiStringLength.
1188 If DestMax is 0.
1189 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1190 **/
1191 RETURN_STATUS
1192 EFIAPI
1193 AsciiStrCpyS (
1194 OUT CHAR8 *Destination,
1195 IN UINTN DestMax,
1196 IN CONST CHAR8 *Source
1197 )
1198 {
1199 UINTN SourceLen;
1200
1201 //
1202 // 1. Neither Destination nor Source shall be a null pointer.
1203 //
1204 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1205 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1206
1207 //
1208 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1209 //
1210 if (ASCII_RSIZE_MAX != 0) {
1211 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1212 }
1213
1214 //
1215 // 3. DestMax shall not equal zero.
1216 //
1217 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1218
1219 //
1220 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1221 //
1222 SourceLen = AsciiStrnLenS (Source, DestMax);
1223 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1224
1225 //
1226 // 5. Copying shall not take place between objects that overlap.
1227 //
1228 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1229
1230 //
1231 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1232 // null character) into the array pointed to by Destination.
1233 //
1234 while (*Source != 0) {
1235 *(Destination++) = *(Source++);
1236 }
1237 *Destination = 0;
1238
1239 return RETURN_SUCCESS;
1240 }
1241
1242 /**
1243 Copies not more than Length successive char from the string pointed to by
1244 Source to the array pointed to by Destination. If no null char is copied from
1245 Source, then Destination[Length] is always set to null.
1246
1247 This function is similar as strncpy_s defined in C11.
1248
1249 If an error would be returned, then the function will also ASSERT().
1250
1251 If an error is returned, then the Destination is unmodified.
1252
1253 @param Destination A pointer to a Null-terminated Ascii string.
1254 @param DestMax The maximum number of Destination Ascii
1255 char, including terminating null char.
1256 @param Source A pointer to a Null-terminated Ascii string.
1257 @param Length The maximum number of Ascii characters to copy.
1258
1259 @retval RETURN_SUCCESS String is copied.
1260 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1261 MIN(StrLen(Source), Length).
1262 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1263 If Source is NULL.
1264 If PcdMaximumAsciiStringLength is not zero,
1265 and DestMax is greater than
1266 PcdMaximumAsciiStringLength.
1267 If DestMax is 0.
1268 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1269 **/
1270 RETURN_STATUS
1271 EFIAPI
1272 AsciiStrnCpyS (
1273 OUT CHAR8 *Destination,
1274 IN UINTN DestMax,
1275 IN CONST CHAR8 *Source,
1276 IN UINTN Length
1277 )
1278 {
1279 UINTN SourceLen;
1280
1281 //
1282 // 1. Neither Destination nor Source shall be a null pointer.
1283 //
1284 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1285 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1286
1287 //
1288 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1289 //
1290 if (ASCII_RSIZE_MAX != 0) {
1291 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1292 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1293 }
1294
1295 //
1296 // 3. DestMax shall not equal zero.
1297 //
1298 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1299
1300 //
1301 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1302 //
1303 SourceLen = AsciiStrnLenS (Source, DestMax);
1304 if (Length >= DestMax) {
1305 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1306 }
1307
1308 //
1309 // 5. Copying shall not take place between objects that overlap.
1310 //
1311 if (SourceLen > Length) {
1312 SourceLen = Length;
1313 }
1314 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1315
1316 //
1317 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1318 // follow a null character are not copied) from the array pointed to by Source to the array
1319 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1320 // character.
1321 //
1322 while ((*Source != 0) && (SourceLen > 0)) {
1323 *(Destination++) = *(Source++);
1324 SourceLen--;
1325 }
1326 *Destination = 0;
1327
1328 return RETURN_SUCCESS;
1329 }
1330
1331 /**
1332 Appends a copy of the string pointed to by Source (including the terminating
1333 null char) to the end of the string pointed to by Destination.
1334
1335 This function is similar as strcat_s defined in C11.
1336
1337 If an error would be returned, then the function will also ASSERT().
1338
1339 If an error is returned, then the Destination is unmodified.
1340
1341 @param Destination A pointer to a Null-terminated Ascii string.
1342 @param DestMax The maximum number of Destination Ascii
1343 char, including terminating null char.
1344 @param Source A pointer to a Null-terminated Ascii string.
1345
1346 @retval RETURN_SUCCESS String is appended.
1347 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1348 StrLen(Destination).
1349 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1350 greater than StrLen(Source).
1351 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1352 If Source is NULL.
1353 If PcdMaximumAsciiStringLength is not zero,
1354 and DestMax is greater than
1355 PcdMaximumAsciiStringLength.
1356 If DestMax is 0.
1357 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1358 **/
1359 RETURN_STATUS
1360 EFIAPI
1361 AsciiStrCatS (
1362 IN OUT CHAR8 *Destination,
1363 IN UINTN DestMax,
1364 IN CONST CHAR8 *Source
1365 )
1366 {
1367 UINTN DestLen;
1368 UINTN CopyLen;
1369 UINTN SourceLen;
1370
1371 //
1372 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1373 //
1374 DestLen = AsciiStrnLenS (Destination, DestMax);
1375 CopyLen = DestMax - DestLen;
1376
1377 //
1378 // 1. Neither Destination nor Source shall be a null pointer.
1379 //
1380 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1381 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1382
1383 //
1384 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1385 //
1386 if (ASCII_RSIZE_MAX != 0) {
1387 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1388 }
1389
1390 //
1391 // 3. DestMax shall not equal zero.
1392 //
1393 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1394
1395 //
1396 // 4. CopyLen shall not equal zero.
1397 //
1398 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
1399
1400 //
1401 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1402 //
1403 SourceLen = AsciiStrnLenS (Source, CopyLen);
1404 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
1405
1406 //
1407 // 6. Copying shall not take place between objects that overlap.
1408 //
1409 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1410
1411 //
1412 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
1413 // terminating null character) to the end of the string pointed to by Destination. The initial character
1414 // from Source overwrites the null character at the end of Destination.
1415 //
1416 Destination = Destination + DestLen;
1417 while (*Source != 0) {
1418 *(Destination++) = *(Source++);
1419 }
1420 *Destination = 0;
1421
1422 return RETURN_SUCCESS;
1423 }
1424
1425 /**
1426 Appends not more than Length successive char from the string pointed to by
1427 Source to the end of the string pointed to by Destination. If no null char is
1428 copied from Source, then Destination[StrLen(Destination) + Length] is always
1429 set to null.
1430
1431 This function is similar as strncat_s defined in C11.
1432
1433 If an error would be returned, then the function will also ASSERT().
1434
1435 If an error is returned, then the Destination is unmodified.
1436
1437 @param Destination A pointer to a Null-terminated Ascii string.
1438 @param DestMax The maximum number of Destination Ascii
1439 char, including terminating null char.
1440 @param Source A pointer to a Null-terminated Ascii string.
1441 @param Length The maximum number of Ascii characters to copy.
1442
1443 @retval RETURN_SUCCESS String is appended.
1444 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1445 StrLen(Destination).
1446 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1447 greater than MIN(StrLen(Source), Length).
1448 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1449 If Source is NULL.
1450 If PcdMaximumAsciiStringLength is not zero,
1451 and DestMax is greater than
1452 PcdMaximumAsciiStringLength.
1453 If DestMax is 0.
1454 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1455 **/
1456 RETURN_STATUS
1457 EFIAPI
1458 AsciiStrnCatS (
1459 IN OUT CHAR8 *Destination,
1460 IN UINTN DestMax,
1461 IN CONST CHAR8 *Source,
1462 IN UINTN Length
1463 )
1464 {
1465 UINTN DestLen;
1466 UINTN CopyLen;
1467 UINTN SourceLen;
1468
1469 //
1470 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
1471 //
1472 DestLen = AsciiStrnLenS (Destination, DestMax);
1473 CopyLen = DestMax - DestLen;
1474
1475 //
1476 // 1. Neither Destination nor Source shall be a null pointer.
1477 //
1478 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1479 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1480
1481 //
1482 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
1483 //
1484 if (ASCII_RSIZE_MAX != 0) {
1485 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1486 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1487 }
1488
1489 //
1490 // 3. DestMax shall not equal zero.
1491 //
1492 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1493
1494 //
1495 // 4. CopyLen shall not equal zero.
1496 //
1497 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
1498
1499 //
1500 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1501 //
1502 SourceLen = AsciiStrnLenS (Source, CopyLen);
1503 if (Length >= CopyLen) {
1504 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
1505 }
1506
1507 //
1508 // 6. Copying shall not take place between objects that overlap.
1509 //
1510 if (SourceLen > Length) {
1511 SourceLen = Length;
1512 }
1513 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1514
1515 //
1516 // The AsciiStrnCatS function appends not more than Length successive characters (characters
1517 // that follow a null character are not copied) from the array pointed to by Source to the end of
1518 // the string pointed to by Destination. The initial character from Source overwrites the null character at
1519 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
1520 // a null character.
1521 //
1522 Destination = Destination + DestLen;
1523 while ((*Source != 0) && (SourceLen > 0)) {
1524 *(Destination++) = *(Source++);
1525 SourceLen--;
1526 }
1527 *Destination = 0;
1528
1529 return RETURN_SUCCESS;
1530 }
1531
1532 /**
1533 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
1534
1535 This function outputs a value of type UINTN by interpreting the contents of
1536 the Ascii string specified by String as a decimal number. The format of the
1537 input Ascii string String is:
1538
1539 [spaces] [decimal digits].
1540
1541 The valid decimal digit character is in the range [0-9]. The function will
1542 ignore the pad space, which includes spaces or tab characters, before
1543 [decimal digits]. The running zero in the beginning of [decimal digits] will
1544 be ignored. Then, the function stops at the first character that is a not a
1545 valid decimal character or a Null-terminator, whichever one comes first.
1546
1547 If String is NULL, then ASSERT().
1548 If Data is NULL, then ASSERT().
1549 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1550 PcdMaximumAsciiStringLength Ascii characters, not including the
1551 Null-terminator, then ASSERT().
1552
1553 If String has no valid decimal digits in the above format, then 0 is stored
1554 at the location pointed to by Data.
1555 If the number represented by String exceeds the range defined by UINTN, then
1556 MAX_UINTN is stored at the location pointed to by Data.
1557
1558 If EndPointer is not NULL, a pointer to the character that stopped the scan
1559 is stored at the location pointed to by EndPointer. If String has no valid
1560 decimal digits right after the optional pad spaces, the value of String is
1561 stored at the location pointed to by EndPointer.
1562
1563 @param String Pointer to a Null-terminated Ascii string.
1564 @param EndPointer Pointer to character that stops scan.
1565 @param Data Pointer to the converted value.
1566
1567 @retval RETURN_SUCCESS Value is translated from String.
1568 @retval RETURN_INVALID_PARAMETER If String is NULL.
1569 If Data is NULL.
1570 If PcdMaximumAsciiStringLength is not zero,
1571 and String contains more than
1572 PcdMaximumAsciiStringLength Ascii
1573 characters, not including the
1574 Null-terminator.
1575 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1576 the range defined by UINTN.
1577
1578 **/
1579 RETURN_STATUS
1580 EFIAPI
1581 AsciiStrDecimalToUintnS (
1582 IN CONST CHAR8 *String,
1583 OUT CHAR8 **EndPointer, OPTIONAL
1584 OUT UINTN *Data
1585 )
1586 {
1587 //
1588 // 1. Neither String nor Data shall be a null pointer.
1589 //
1590 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1591 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1592
1593 //
1594 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
1595 //
1596 if (ASCII_RSIZE_MAX != 0) {
1597 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1598 }
1599
1600 if (EndPointer != NULL) {
1601 *EndPointer = (CHAR8 *) String;
1602 }
1603
1604 //
1605 // Ignore the pad spaces (space or tab)
1606 //
1607 while ((*String == ' ') || (*String == '\t')) {
1608 String++;
1609 }
1610
1611 //
1612 // Ignore leading Zeros after the spaces
1613 //
1614 while (*String == '0') {
1615 String++;
1616 }
1617
1618 *Data = 0;
1619
1620 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1621 //
1622 // If the number represented by String overflows according to the range
1623 // defined by UINTN, then MAX_UINTN is stored in *Data and
1624 // RETURN_UNSUPPORTED is returned.
1625 //
1626 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {
1627 *Data = MAX_UINTN;
1628 if (EndPointer != NULL) {
1629 *EndPointer = (CHAR8 *) String;
1630 }
1631 return RETURN_UNSUPPORTED;
1632 }
1633
1634 *Data = *Data * 10 + (*String - '0');
1635 String++;
1636 }
1637
1638 if (EndPointer != NULL) {
1639 *EndPointer = (CHAR8 *) String;
1640 }
1641 return RETURN_SUCCESS;
1642 }
1643
1644 /**
1645 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
1646
1647 This function outputs a value of type UINT64 by interpreting the contents of
1648 the Ascii string specified by String as a decimal number. The format of the
1649 input Ascii string String is:
1650
1651 [spaces] [decimal digits].
1652
1653 The valid decimal digit character is in the range [0-9]. The function will
1654 ignore the pad space, which includes spaces or tab characters, before
1655 [decimal digits]. The running zero in the beginning of [decimal digits] will
1656 be ignored. Then, the function stops at the first character that is a not a
1657 valid decimal character or a Null-terminator, whichever one comes first.
1658
1659 If String is NULL, then ASSERT().
1660 If Data is NULL, then ASSERT().
1661 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1662 PcdMaximumAsciiStringLength Ascii characters, not including the
1663 Null-terminator, then ASSERT().
1664
1665 If String has no valid decimal digits in the above format, then 0 is stored
1666 at the location pointed to by Data.
1667 If the number represented by String exceeds the range defined by UINT64, then
1668 MAX_UINT64 is stored at the location pointed to by Data.
1669
1670 If EndPointer is not NULL, a pointer to the character that stopped the scan
1671 is stored at the location pointed to by EndPointer. If String has no valid
1672 decimal digits right after the optional pad spaces, the value of String is
1673 stored at the location pointed to by EndPointer.
1674
1675 @param String Pointer to a Null-terminated Ascii string.
1676 @param EndPointer Pointer to character that stops scan.
1677 @param Data Pointer to the converted value.
1678
1679 @retval RETURN_SUCCESS Value is translated from String.
1680 @retval RETURN_INVALID_PARAMETER If String is NULL.
1681 If Data is NULL.
1682 If PcdMaximumAsciiStringLength is not zero,
1683 and String contains more than
1684 PcdMaximumAsciiStringLength Ascii
1685 characters, not including the
1686 Null-terminator.
1687 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1688 the range defined by UINT64.
1689
1690 **/
1691 RETURN_STATUS
1692 EFIAPI
1693 AsciiStrDecimalToUint64S (
1694 IN CONST CHAR8 *String,
1695 OUT CHAR8 **EndPointer, OPTIONAL
1696 OUT UINT64 *Data
1697 )
1698 {
1699 //
1700 // 1. Neither String nor Data shall be a null pointer.
1701 //
1702 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1703 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1704
1705 //
1706 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
1707 //
1708 if (ASCII_RSIZE_MAX != 0) {
1709 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1710 }
1711
1712 if (EndPointer != NULL) {
1713 *EndPointer = (CHAR8 *) String;
1714 }
1715
1716 //
1717 // Ignore the pad spaces (space or tab)
1718 //
1719 while ((*String == ' ') || (*String == '\t')) {
1720 String++;
1721 }
1722
1723 //
1724 // Ignore leading Zeros after the spaces
1725 //
1726 while (*String == '0') {
1727 String++;
1728 }
1729
1730 *Data = 0;
1731
1732 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1733 //
1734 // If the number represented by String overflows according to the range
1735 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1736 // RETURN_UNSUPPORTED is returned.
1737 //
1738 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {
1739 *Data = MAX_UINT64;
1740 if (EndPointer != NULL) {
1741 *EndPointer = (CHAR8 *) String;
1742 }
1743 return RETURN_UNSUPPORTED;
1744 }
1745
1746 *Data = MultU64x32 (*Data, 10) + (*String - '0');
1747 String++;
1748 }
1749
1750 if (EndPointer != NULL) {
1751 *EndPointer = (CHAR8 *) String;
1752 }
1753 return RETURN_SUCCESS;
1754 }
1755
1756 /**
1757 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
1758
1759 This function outputs a value of type UINTN by interpreting the contents of
1760 the Ascii string specified by String as a hexadecimal number. The format of
1761 the input Ascii string String is:
1762
1763 [spaces][zeros][x][hexadecimal digits].
1764
1765 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1766 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
1767 "x" appears in the input string, it must be prefixed with at least one 0. The
1768 function will ignore the pad space, which includes spaces or tab characters,
1769 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
1770 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
1771 the first valid hexadecimal digit. Then, the function stops at the first
1772 character that is a not a valid hexadecimal character or Null-terminator,
1773 whichever on comes first.
1774
1775 If String is NULL, then ASSERT().
1776 If Data is NULL, then ASSERT().
1777 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1778 PcdMaximumAsciiStringLength Ascii characters, not including the
1779 Null-terminator, then ASSERT().
1780
1781 If String has no valid hexadecimal digits in the above format, then 0 is
1782 stored at the location pointed to by Data.
1783 If the number represented by String exceeds the range defined by UINTN, then
1784 MAX_UINTN is stored at the location pointed to by Data.
1785
1786 If EndPointer is not NULL, a pointer to the character that stopped the scan
1787 is stored at the location pointed to by EndPointer. If String has no valid
1788 hexadecimal digits right after the optional pad spaces, the value of String
1789 is stored at the location pointed to by EndPointer.
1790
1791 @param String Pointer to a Null-terminated Ascii string.
1792 @param EndPointer Pointer to character that stops scan.
1793 @param Data Pointer to the converted value.
1794
1795 @retval RETURN_SUCCESS Value is translated from String.
1796 @retval RETURN_INVALID_PARAMETER If String is NULL.
1797 If Data is NULL.
1798 If PcdMaximumAsciiStringLength is not zero,
1799 and String contains more than
1800 PcdMaximumAsciiStringLength Ascii
1801 characters, not including the
1802 Null-terminator.
1803 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1804 the range defined by UINTN.
1805
1806 **/
1807 RETURN_STATUS
1808 EFIAPI
1809 AsciiStrHexToUintnS (
1810 IN CONST CHAR8 *String,
1811 OUT CHAR8 **EndPointer, OPTIONAL
1812 OUT UINTN *Data
1813 )
1814 {
1815 //
1816 // 1. Neither String nor Data shall be a null pointer.
1817 //
1818 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1819 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1820
1821 //
1822 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
1823 //
1824 if (ASCII_RSIZE_MAX != 0) {
1825 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1826 }
1827
1828 if (EndPointer != NULL) {
1829 *EndPointer = (CHAR8 *) String;
1830 }
1831
1832 //
1833 // Ignore the pad spaces (space or tab)
1834 //
1835 while ((*String == ' ') || (*String == '\t')) {
1836 String++;
1837 }
1838
1839 //
1840 // Ignore leading Zeros after the spaces
1841 //
1842 while (*String == '0') {
1843 String++;
1844 }
1845
1846 if (InternalBaseLibAsciiToUpper (*String) == 'X') {
1847 if (*(String - 1) != '0') {
1848 *Data = 0;
1849 return RETURN_SUCCESS;
1850 }
1851 //
1852 // Skip the 'X'
1853 //
1854 String++;
1855 }
1856
1857 *Data = 0;
1858
1859 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1860 //
1861 // If the number represented by String overflows according to the range
1862 // defined by UINTN, then MAX_UINTN is stored in *Data and
1863 // RETURN_UNSUPPORTED is returned.
1864 //
1865 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {
1866 *Data = MAX_UINTN;
1867 if (EndPointer != NULL) {
1868 *EndPointer = (CHAR8 *) String;
1869 }
1870 return RETURN_UNSUPPORTED;
1871 }
1872
1873 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);
1874 String++;
1875 }
1876
1877 if (EndPointer != NULL) {
1878 *EndPointer = (CHAR8 *) String;
1879 }
1880 return RETURN_SUCCESS;
1881 }
1882
1883 /**
1884 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
1885
1886 This function outputs a value of type UINT64 by interpreting the contents of
1887 the Ascii string specified by String as a hexadecimal number. The format of
1888 the input Ascii string String is:
1889
1890 [spaces][zeros][x][hexadecimal digits].
1891
1892 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1893 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
1894 "x" appears in the input string, it must be prefixed with at least one 0. The
1895 function will ignore the pad space, which includes spaces or tab characters,
1896 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
1897 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
1898 the first valid hexadecimal digit. Then, the function stops at the first
1899 character that is a not a valid hexadecimal character or Null-terminator,
1900 whichever on comes first.
1901
1902 If String is NULL, then ASSERT().
1903 If Data is NULL, then ASSERT().
1904 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1905 PcdMaximumAsciiStringLength Ascii characters, not including the
1906 Null-terminator, then ASSERT().
1907
1908 If String has no valid hexadecimal digits in the above format, then 0 is
1909 stored at the location pointed to by Data.
1910 If the number represented by String exceeds the range defined by UINT64, then
1911 MAX_UINT64 is stored at the location pointed to by Data.
1912
1913 If EndPointer is not NULL, a pointer to the character that stopped the scan
1914 is stored at the location pointed to by EndPointer. If String has no valid
1915 hexadecimal digits right after the optional pad spaces, the value of String
1916 is stored at the location pointed to by EndPointer.
1917
1918 @param String Pointer to a Null-terminated Ascii string.
1919 @param EndPointer Pointer to character that stops scan.
1920 @param Data Pointer to the converted value.
1921
1922 @retval RETURN_SUCCESS Value is translated from String.
1923 @retval RETURN_INVALID_PARAMETER If String is NULL.
1924 If Data is NULL.
1925 If PcdMaximumAsciiStringLength is not zero,
1926 and String contains more than
1927 PcdMaximumAsciiStringLength Ascii
1928 characters, not including the
1929 Null-terminator.
1930 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1931 the range defined by UINT64.
1932
1933 **/
1934 RETURN_STATUS
1935 EFIAPI
1936 AsciiStrHexToUint64S (
1937 IN CONST CHAR8 *String,
1938 OUT CHAR8 **EndPointer, OPTIONAL
1939 OUT UINT64 *Data
1940 )
1941 {
1942 //
1943 // 1. Neither String nor Data shall be a null pointer.
1944 //
1945 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
1946 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
1947
1948 //
1949 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
1950 //
1951 if (ASCII_RSIZE_MAX != 0) {
1952 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1953 }
1954
1955 if (EndPointer != NULL) {
1956 *EndPointer = (CHAR8 *) String;
1957 }
1958
1959 //
1960 // Ignore the pad spaces (space or tab)
1961 //
1962 while ((*String == ' ') || (*String == '\t')) {
1963 String++;
1964 }
1965
1966 //
1967 // Ignore leading Zeros after the spaces
1968 //
1969 while (*String == '0') {
1970 String++;
1971 }
1972
1973 if (InternalBaseLibAsciiToUpper (*String) == 'X') {
1974 if (*(String - 1) != '0') {
1975 *Data = 0;
1976 return RETURN_SUCCESS;
1977 }
1978 //
1979 // Skip the 'X'
1980 //
1981 String++;
1982 }
1983
1984 *Data = 0;
1985
1986 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1987 //
1988 // If the number represented by String overflows according to the range
1989 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1990 // RETURN_UNSUPPORTED is returned.
1991 //
1992 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {
1993 *Data = MAX_UINT64;
1994 if (EndPointer != NULL) {
1995 *EndPointer = (CHAR8 *) String;
1996 }
1997 return RETURN_UNSUPPORTED;
1998 }
1999
2000 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);
2001 String++;
2002 }
2003
2004 if (EndPointer != NULL) {
2005 *EndPointer = (CHAR8 *) String;
2006 }
2007 return RETURN_SUCCESS;
2008 }
2009
2010 /**
2011 Convert a Null-terminated Unicode string to a Null-terminated
2012 ASCII string.
2013
2014 This function is similar to AsciiStrCpyS.
2015
2016 This function converts the content of the Unicode string Source
2017 to the ASCII string Destination by copying the lower 8 bits of
2018 each Unicode character. The function terminates the ASCII string
2019 Destination by appending a Null-terminator character at the end.
2020
2021 The caller is responsible to make sure Destination points to a buffer with size
2022 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2023
2024 If any Unicode characters in Source contain non-zero value in
2025 the upper 8 bits, then ASSERT().
2026
2027 If Source is not aligned on a 16-bit boundary, then ASSERT().
2028 If an error would be returned, then the function will also ASSERT().
2029
2030 If an error is returned, then the Destination is unmodified.
2031
2032 @param Source The pointer to a Null-terminated Unicode string.
2033 @param Destination The pointer to a Null-terminated ASCII string.
2034 @param DestMax The maximum number of Destination Ascii
2035 char, including terminating null char.
2036
2037 @retval RETURN_SUCCESS String is converted.
2038 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2039 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2040 If Source is NULL.
2041 If PcdMaximumAsciiStringLength is not zero,
2042 and DestMax is greater than
2043 PcdMaximumAsciiStringLength.
2044 If PcdMaximumUnicodeStringLength is not zero,
2045 and DestMax is greater than
2046 PcdMaximumUnicodeStringLength.
2047 If DestMax is 0.
2048 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2049
2050 **/
2051 RETURN_STATUS
2052 EFIAPI
2053 UnicodeStrToAsciiStrS (
2054 IN CONST CHAR16 *Source,
2055 OUT CHAR8 *Destination,
2056 IN UINTN DestMax
2057 )
2058 {
2059 UINTN SourceLen;
2060
2061 ASSERT (((UINTN) Source & BIT0) == 0);
2062
2063 //
2064 // 1. Neither Destination nor Source shall be a null pointer.
2065 //
2066 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2067 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2068
2069 //
2070 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2071 //
2072 if (ASCII_RSIZE_MAX != 0) {
2073 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2074 }
2075 if (RSIZE_MAX != 0) {
2076 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2077 }
2078
2079 //
2080 // 3. DestMax shall not equal zero.
2081 //
2082 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2083
2084 //
2085 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2086 //
2087 SourceLen = StrnLenS (Source, DestMax);
2088 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2089
2090 //
2091 // 5. Copying shall not take place between objects that overlap.
2092 //
2093 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
2094
2095 //
2096 // convert string
2097 //
2098 while (*Source != '\0') {
2099 //
2100 // If any Unicode characters in Source contain
2101 // non-zero value in the upper 8 bits, then ASSERT().
2102 //
2103 ASSERT (*Source < 0x100);
2104 *(Destination++) = (CHAR8) *(Source++);
2105 }
2106 *Destination = '\0';
2107
2108 return RETURN_SUCCESS;
2109 }
2110
2111 /**
2112 Convert not more than Length successive characters from a Null-terminated
2113 Unicode string to a Null-terminated Ascii string. If no null char is copied
2114 from Source, then Destination[Length] is always set to null.
2115
2116 This function converts not more than Length successive characters from the
2117 Unicode string Source to the Ascii string Destination by copying the lower 8
2118 bits of each Unicode character. The function terminates the Ascii string
2119 Destination by appending a Null-terminator character at the end.
2120
2121 The caller is responsible to make sure Destination points to a buffer with
2122 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2123 in bytes.
2124
2125 If any Unicode characters in Source contain non-zero value in the upper 8
2126 bits, then ASSERT().
2127 If Source is not aligned on a 16-bit boundary, then ASSERT().
2128 If an error would be returned, then the function will also ASSERT().
2129
2130 If an error is returned, then Destination and DestinationLength are
2131 unmodified.
2132
2133 @param Source The pointer to a Null-terminated Unicode string.
2134 @param Length The maximum number of Unicode characters to
2135 convert.
2136 @param Destination The pointer to a Null-terminated Ascii string.
2137 @param DestMax The maximum number of Destination Ascii char,
2138 including terminating null char.
2139 @param DestinationLength The number of Unicode characters converted.
2140
2141 @retval RETURN_SUCCESS String is converted.
2142 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2143 If Source is NULL.
2144 If DestinationLength is NULL.
2145 If PcdMaximumAsciiStringLength is not zero,
2146 and Length or DestMax is greater than
2147 PcdMaximumAsciiStringLength.
2148 If PcdMaximumUnicodeStringLength is not
2149 zero, and Length or DestMax is greater than
2150 PcdMaximumUnicodeStringLength.
2151 If DestMax is 0.
2152 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2153 MIN(StrLen(Source), Length).
2154 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2155
2156 **/
2157 RETURN_STATUS
2158 EFIAPI
2159 UnicodeStrnToAsciiStrS (
2160 IN CONST CHAR16 *Source,
2161 IN UINTN Length,
2162 OUT CHAR8 *Destination,
2163 IN UINTN DestMax,
2164 OUT UINTN *DestinationLength
2165 )
2166 {
2167 UINTN SourceLen;
2168
2169 ASSERT (((UINTN) Source & BIT0) == 0);
2170
2171 //
2172 // 1. None of Destination, Source or DestinationLength shall be a null
2173 // pointer.
2174 //
2175 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2176 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2177 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2178
2179 //
2180 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2181 // RSIZE_MAX.
2182 //
2183 if (ASCII_RSIZE_MAX != 0) {
2184 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2185 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2186 }
2187 if (RSIZE_MAX != 0) {
2188 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2189 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2190 }
2191
2192 //
2193 // 3. DestMax shall not equal zero.
2194 //
2195 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2196
2197 //
2198 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2199 // StrnLenS(Source, DestMax).
2200 //
2201 SourceLen = StrnLenS (Source, DestMax);
2202 if (Length >= DestMax) {
2203 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2204 }
2205
2206 //
2207 // 5. Copying shall not take place between objects that overlap.
2208 //
2209 if (SourceLen > Length) {
2210 SourceLen = Length;
2211 }
2212 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
2213
2214 *DestinationLength = 0;
2215
2216 //
2217 // Convert string
2218 //
2219 while ((*Source != 0) && (SourceLen > 0)) {
2220 //
2221 // If any Unicode characters in Source contain non-zero value in the upper
2222 // 8 bits, then ASSERT().
2223 //
2224 ASSERT (*Source < 0x100);
2225 *(Destination++) = (CHAR8) *(Source++);
2226 SourceLen--;
2227 (*DestinationLength)++;
2228 }
2229 *Destination = 0;
2230
2231 return RETURN_SUCCESS;
2232 }
2233
2234 /**
2235 Convert one Null-terminated ASCII string to a Null-terminated
2236 Unicode string.
2237
2238 This function is similar to StrCpyS.
2239
2240 This function converts the contents of the ASCII string Source to the Unicode
2241 string Destination. The function terminates the Unicode string Destination by
2242 appending a Null-terminator character at the end.
2243
2244 The caller is responsible to make sure Destination points to a buffer with size
2245 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2246
2247 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2248 If an error would be returned, then the function will also ASSERT().
2249
2250 If an error is returned, then the Destination is unmodified.
2251
2252 @param Source The pointer to a Null-terminated ASCII string.
2253 @param Destination The pointer to a Null-terminated Unicode string.
2254 @param DestMax The maximum number of Destination Unicode
2255 char, including terminating null char.
2256
2257 @retval RETURN_SUCCESS String is converted.
2258 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2259 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2260 If Source is NULL.
2261 If PcdMaximumUnicodeStringLength is not zero,
2262 and DestMax is greater than
2263 PcdMaximumUnicodeStringLength.
2264 If PcdMaximumAsciiStringLength is not zero,
2265 and DestMax is greater than
2266 PcdMaximumAsciiStringLength.
2267 If DestMax is 0.
2268 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2269
2270 **/
2271 RETURN_STATUS
2272 EFIAPI
2273 AsciiStrToUnicodeStrS (
2274 IN CONST CHAR8 *Source,
2275 OUT CHAR16 *Destination,
2276 IN UINTN DestMax
2277 )
2278 {
2279 UINTN SourceLen;
2280
2281 ASSERT (((UINTN) Destination & BIT0) == 0);
2282
2283 //
2284 // 1. Neither Destination nor Source shall be a null pointer.
2285 //
2286 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2287 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2288
2289 //
2290 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2291 //
2292 if (RSIZE_MAX != 0) {
2293 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2294 }
2295 if (ASCII_RSIZE_MAX != 0) {
2296 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2297 }
2298
2299 //
2300 // 3. DestMax shall not equal zero.
2301 //
2302 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2303
2304 //
2305 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2306 //
2307 SourceLen = AsciiStrnLenS (Source, DestMax);
2308 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2309
2310 //
2311 // 5. Copying shall not take place between objects that overlap.
2312 //
2313 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2314
2315 //
2316 // Convert string
2317 //
2318 while (*Source != '\0') {
2319 *(Destination++) = (CHAR16)*(Source++);
2320 }
2321 *Destination = '\0';
2322
2323 return RETURN_SUCCESS;
2324 }
2325
2326 /**
2327 Convert not more than Length successive characters from a Null-terminated
2328 Ascii string to a Null-terminated Unicode string. If no null char is copied
2329 from Source, then Destination[Length] is always set to null.
2330
2331 This function converts not more than Length successive characters from the
2332 Ascii string Source to the Unicode string Destination. The function
2333 terminates the Unicode string Destination by appending a Null-terminator
2334 character at the end.
2335
2336 The caller is responsible to make sure Destination points to a buffer with
2337 size not smaller than
2338 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2339
2340 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2341 If an error would be returned, then the function will also ASSERT().
2342
2343 If an error is returned, then Destination and DestinationLength are
2344 unmodified.
2345
2346 @param Source The pointer to a Null-terminated Ascii string.
2347 @param Length The maximum number of Ascii characters to convert.
2348 @param Destination The pointer to a Null-terminated Unicode string.
2349 @param DestMax The maximum number of Destination Unicode char,
2350 including terminating null char.
2351 @param DestinationLength The number of Ascii characters converted.
2352
2353 @retval RETURN_SUCCESS String is converted.
2354 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2355 If Source is NULL.
2356 If DestinationLength is NULL.
2357 If PcdMaximumUnicodeStringLength is not
2358 zero, and Length or DestMax is greater than
2359 PcdMaximumUnicodeStringLength.
2360 If PcdMaximumAsciiStringLength is not zero,
2361 and Length or DestMax is greater than
2362 PcdMaximumAsciiStringLength.
2363 If DestMax is 0.
2364 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2365 MIN(AsciiStrLen(Source), Length).
2366 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2367
2368 **/
2369 RETURN_STATUS
2370 EFIAPI
2371 AsciiStrnToUnicodeStrS (
2372 IN CONST CHAR8 *Source,
2373 IN UINTN Length,
2374 OUT CHAR16 *Destination,
2375 IN UINTN DestMax,
2376 OUT UINTN *DestinationLength
2377 )
2378 {
2379 UINTN SourceLen;
2380
2381 ASSERT (((UINTN) Destination & BIT0) == 0);
2382
2383 //
2384 // 1. None of Destination, Source or DestinationLength shall be a null
2385 // pointer.
2386 //
2387 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
2388 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
2389 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);
2390
2391 //
2392 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2393 // RSIZE_MAX.
2394 //
2395 if (RSIZE_MAX != 0) {
2396 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2397 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
2398 }
2399 if (ASCII_RSIZE_MAX != 0) {
2400 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2401 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
2402 }
2403
2404 //
2405 // 3. DestMax shall not equal zero.
2406 //
2407 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
2408
2409 //
2410 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2411 // AsciiStrnLenS(Source, DestMax).
2412 //
2413 SourceLen = AsciiStrnLenS (Source, DestMax);
2414 if (Length >= DestMax) {
2415 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
2416 }
2417
2418 //
2419 // 5. Copying shall not take place between objects that overlap.
2420 //
2421 if (SourceLen > Length) {
2422 SourceLen = Length;
2423 }
2424 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
2425
2426 *DestinationLength = 0;
2427
2428 //
2429 // Convert string
2430 //
2431 while ((*Source != 0) && (SourceLen > 0)) {
2432 *(Destination++) = (CHAR16)*(Source++);
2433 SourceLen--;
2434 (*DestinationLength)++;
2435 }
2436 *Destination = 0;
2437
2438 return RETURN_SUCCESS;
2439 }