]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/SafeString.c
MdePkg/BaseLib: Add safe string functions [Ascii]StrnSizeS
[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 <Base.h>
16 #include <Library/DebugLib.h>
17 #include <Library/PcdLib.h>
18 #include <Library/BaseLib.h>
19
20 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
21
22 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
23
24 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
25 do { \
26 ASSERT (Expression); \
27 if (!(Expression)) { \
28 return Status; \
29 } \
30 } while (FALSE)
31
32 /**
33 Returns if 2 memory blocks are overlapped.
34
35 @param Base1 Base address of 1st memory block.
36 @param Size1 Size of 1st memory block.
37 @param Base2 Base address of 2nd memory block.
38 @param Size2 Size of 2nd memory block.
39
40 @retval TRUE 2 memory blocks are overlapped.
41 @retval FALSE 2 memory blocks are not overlapped.
42 **/
43 BOOLEAN
44 InternalSafeStringIsOverlap (
45 IN VOID *Base1,
46 IN UINTN Size1,
47 IN VOID *Base2,
48 IN UINTN Size2
49 )
50 {
51 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
52 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
53 return TRUE;
54 }
55 return FALSE;
56 }
57
58 /**
59 Returns if 2 Unicode strings are not overlapped.
60
61 @param Str1 Start address of 1st Unicode string.
62 @param Size1 The number of char in 1st Unicode string,
63 including terminating null char.
64 @param Str2 Start address of 2nd Unicode string.
65 @param Size2 The number of char in 2nd Unicode string,
66 including terminating null char.
67
68 @retval TRUE 2 Unicode strings are NOT overlapped.
69 @retval FALSE 2 Unicode strings are overlapped.
70 **/
71 BOOLEAN
72 InternalSafeStringNoStrOverlap (
73 IN CHAR16 *Str1,
74 IN UINTN Size1,
75 IN CHAR16 *Str2,
76 IN UINTN Size2
77 )
78 {
79 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
80 }
81
82 /**
83 Returns if 2 Ascii strings are not overlapped.
84
85 @param Str1 Start address of 1st Ascii string.
86 @param Size1 The number of char in 1st Ascii string,
87 including terminating null char.
88 @param Str2 Start address of 2nd Ascii string.
89 @param Size2 The number of char in 2nd Ascii string,
90 including terminating null char.
91
92 @retval TRUE 2 Ascii strings are NOT overlapped.
93 @retval FALSE 2 Ascii strings are overlapped.
94 **/
95 BOOLEAN
96 InternalSafeStringNoAsciiStrOverlap (
97 IN CHAR8 *Str1,
98 IN UINTN Size1,
99 IN CHAR8 *Str2,
100 IN UINTN Size2
101 )
102 {
103 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);
104 }
105
106 /**
107 Returns the length of a Null-terminated Unicode string.
108
109 This function is similar as strlen_s defined in C11.
110
111 If String is not aligned on a 16-bit boundary, then ASSERT().
112
113 @param String A pointer to a Null-terminated Unicode string.
114 @param MaxSize The maximum number of Destination Unicode
115 char, including terminating null char.
116
117 @retval 0 If String is NULL.
118 @retval MaxSize If there is no null character in the first MaxSize characters of String.
119 @return The number of characters that percede the terminating null character.
120
121 **/
122 UINTN
123 EFIAPI
124 StrnLenS (
125 IN CONST CHAR16 *String,
126 IN UINTN MaxSize
127 )
128 {
129 UINTN Length;
130
131 ASSERT (((UINTN) String & BIT0) == 0);
132
133 //
134 // If String is a null pointer, then the StrnLenS function returns zero.
135 //
136 if (String == NULL) {
137 return 0;
138 }
139
140 //
141 // Otherwise, the StrnLenS function returns the number of characters that precede the
142 // terminating null character. If there is no null character in the first MaxSize characters of
143 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
144 // be accessed by StrnLenS.
145 //
146 Length = 0;
147 while (String[Length] != 0) {
148 if (Length >= MaxSize - 1) {
149 return MaxSize;
150 }
151 Length++;
152 }
153 return Length;
154 }
155
156 /**
157 Returns the size of a Null-terminated Unicode string in bytes, including the
158 Null terminator.
159
160 This function returns the size of the Null-terminated Unicode string
161 specified by String in bytes, including the Null terminator.
162
163 If String is not aligned on a 16-bit boundary, then ASSERT().
164
165 @param String A pointer to a Null-terminated Unicode string.
166 @param MaxSize The maximum number of Destination Unicode
167 char, including the Null terminator.
168
169 @retval 0 If String is NULL.
170 @retval (sizeof (CHAR16) * (MaxSize + 1))
171 If there is no Null terminator in the first MaxSize characters of
172 String.
173 @return The size of the Null-terminated Unicode string in bytes, including
174 the Null terminator.
175
176 **/
177 UINTN
178 EFIAPI
179 StrnSizeS (
180 IN CONST CHAR16 *String,
181 IN UINTN MaxSize
182 )
183 {
184 //
185 // If String is a null pointer, then the StrnSizeS function returns zero.
186 //
187 if (String == NULL) {
188 return 0;
189 }
190
191 //
192 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
193 // Unicode string in bytes, including the Null terminator. If there is no
194 // Null terminator in the first MaxSize characters of String, then StrnSizeS
195 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
196 // the StrnLenS function.
197 //
198 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);
199 }
200
201 /**
202 Copies the string pointed to by Source (including the terminating null char)
203 to the array pointed to by Destination.
204
205 This function is similar as strcpy_s defined in C11.
206
207 If Destination is not aligned on a 16-bit boundary, then ASSERT().
208 If Source is not aligned on a 16-bit boundary, then ASSERT().
209 If an error would be returned, then the function will also ASSERT().
210
211 If an error is returned, then the Destination is unmodified.
212
213 @param Destination A pointer to a Null-terminated Unicode string.
214 @param DestMax The maximum number of Destination Unicode
215 char, including terminating null char.
216 @param Source A pointer to a Null-terminated Unicode string.
217
218 @retval RETURN_SUCCESS String is copied.
219 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
220 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
221 If Source is NULL.
222 If PcdMaximumUnicodeStringLength is not zero,
223 and DestMax is greater than
224 PcdMaximumUnicodeStringLength.
225 If DestMax is 0.
226 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
227 **/
228 RETURN_STATUS
229 EFIAPI
230 StrCpyS (
231 OUT CHAR16 *Destination,
232 IN UINTN DestMax,
233 IN CONST CHAR16 *Source
234 )
235 {
236 UINTN SourceLen;
237
238 ASSERT (((UINTN) Destination & BIT0) == 0);
239 ASSERT (((UINTN) Source & BIT0) == 0);
240
241 //
242 // 1. Neither Destination nor Source shall be a null pointer.
243 //
244 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
245 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
246
247 //
248 // 2. DestMax shall not be greater than RSIZE_MAX.
249 //
250 if (RSIZE_MAX != 0) {
251 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
252 }
253
254 //
255 // 3. DestMax shall not equal zero.
256 //
257 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
258
259 //
260 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
261 //
262 SourceLen = StrnLenS (Source, DestMax);
263 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
264
265 //
266 // 5. Copying shall not take place between objects that overlap.
267 //
268 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
269
270 //
271 // The StrCpyS function copies the string pointed to by Source (including the terminating
272 // null character) into the array pointed to by Destination.
273 //
274 while (*Source != 0) {
275 *(Destination++) = *(Source++);
276 }
277 *Destination = 0;
278
279 return RETURN_SUCCESS;
280 }
281
282 /**
283 Copies not more than Length successive char from the string pointed to by
284 Source to the array pointed to by Destination. If no null char is copied from
285 Source, then Destination[Length] is always set to null.
286
287 This function is similar as strncpy_s defined in C11.
288
289 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
290 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
291 If an error would be returned, then the function will also ASSERT().
292
293 If an error is returned, then the Destination is unmodified.
294
295 @param Destination A pointer to a Null-terminated Unicode string.
296 @param DestMax The maximum number of Destination Unicode
297 char, including terminating null char.
298 @param Source A pointer to a Null-terminated Unicode string.
299 @param Length The maximum number of Unicode characters to copy.
300
301 @retval RETURN_SUCCESS String is copied.
302 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
303 MIN(StrLen(Source), Length).
304 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
305 If Source is NULL.
306 If PcdMaximumUnicodeStringLength is not zero,
307 and DestMax is greater than
308 PcdMaximumUnicodeStringLength.
309 If DestMax is 0.
310 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
311 **/
312 RETURN_STATUS
313 EFIAPI
314 StrnCpyS (
315 OUT CHAR16 *Destination,
316 IN UINTN DestMax,
317 IN CONST CHAR16 *Source,
318 IN UINTN Length
319 )
320 {
321 UINTN SourceLen;
322
323 ASSERT (((UINTN) Destination & BIT0) == 0);
324 ASSERT (((UINTN) Source & BIT0) == 0);
325
326 //
327 // 1. Neither Destination nor Source shall be a null pointer.
328 //
329 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
330 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
331
332 //
333 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
334 //
335 if (RSIZE_MAX != 0) {
336 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
337 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
338 }
339
340 //
341 // 3. DestMax shall not equal zero.
342 //
343 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
344
345 //
346 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
347 //
348 SourceLen = StrnLenS (Source, DestMax);
349 if (Length >= DestMax) {
350 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
351 }
352
353 //
354 // 5. Copying shall not take place between objects that overlap.
355 //
356 if (SourceLen > Length) {
357 SourceLen = Length;
358 }
359 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
360
361 //
362 // The StrnCpyS function copies not more than Length successive characters (characters that
363 // follow a null character are not copied) from the array pointed to by Source to the array
364 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
365 // character.
366 //
367 while ((*Source != 0) && (SourceLen > 0)) {
368 *(Destination++) = *(Source++);
369 SourceLen--;
370 }
371 *Destination = 0;
372
373 return RETURN_SUCCESS;
374 }
375
376 /**
377 Appends a copy of the string pointed to by Source (including the terminating
378 null char) to the end of the string pointed to by Destination.
379
380 This function is similar as strcat_s defined in C11.
381
382 If Destination is not aligned on a 16-bit boundary, then ASSERT().
383 If Source is not aligned on a 16-bit boundary, then ASSERT().
384 If an error would be returned, then the function will also ASSERT().
385
386 If an error is returned, then the Destination is unmodified.
387
388 @param Destination A pointer to a Null-terminated Unicode string.
389 @param DestMax The maximum number of Destination Unicode
390 char, including terminating null char.
391 @param Source A pointer to a Null-terminated Unicode string.
392
393 @retval RETURN_SUCCESS String is appended.
394 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
395 StrLen(Destination).
396 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
397 greater than StrLen(Source).
398 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
399 If Source is NULL.
400 If PcdMaximumUnicodeStringLength is not zero,
401 and DestMax is greater than
402 PcdMaximumUnicodeStringLength.
403 If DestMax is 0.
404 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
405 **/
406 RETURN_STATUS
407 EFIAPI
408 StrCatS (
409 IN OUT CHAR16 *Destination,
410 IN UINTN DestMax,
411 IN CONST CHAR16 *Source
412 )
413 {
414 UINTN DestLen;
415 UINTN CopyLen;
416 UINTN SourceLen;
417
418 ASSERT (((UINTN) Destination & BIT0) == 0);
419 ASSERT (((UINTN) Source & BIT0) == 0);
420
421 //
422 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
423 //
424 DestLen = StrnLenS (Destination, DestMax);
425 CopyLen = DestMax - DestLen;
426
427 //
428 // 1. Neither Destination nor Source shall be a null pointer.
429 //
430 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
431 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
432
433 //
434 // 2. DestMax shall not be greater than RSIZE_MAX.
435 //
436 if (RSIZE_MAX != 0) {
437 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
438 }
439
440 //
441 // 3. DestMax shall not equal zero.
442 //
443 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
444
445 //
446 // 4. CopyLen shall not equal zero.
447 //
448 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
449
450 //
451 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
452 //
453 SourceLen = StrnLenS (Source, CopyLen);
454 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
455
456 //
457 // 6. Copying shall not take place between objects that overlap.
458 //
459 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
460
461 //
462 // The StrCatS function appends a copy of the string pointed to by Source (including the
463 // terminating null character) to the end of the string pointed to by Destination. The initial character
464 // from Source overwrites the null character at the end of Destination.
465 //
466 Destination = Destination + DestLen;
467 while (*Source != 0) {
468 *(Destination++) = *(Source++);
469 }
470 *Destination = 0;
471
472 return RETURN_SUCCESS;
473 }
474
475 /**
476 Appends not more than Length successive char from the string pointed to by
477 Source to the end of the string pointed to by Destination. If no null char is
478 copied from Source, then Destination[StrLen(Destination) + Length] is always
479 set to null.
480
481 This function is similar as strncat_s defined in C11.
482
483 If Destination is not aligned on a 16-bit boundary, then ASSERT().
484 If Source is not aligned on a 16-bit boundary, then ASSERT().
485 If an error would be returned, then the function will also ASSERT().
486
487 If an error is returned, then the Destination is unmodified.
488
489 @param Destination A pointer to a Null-terminated Unicode string.
490 @param DestMax The maximum number of Destination Unicode
491 char, including terminating null char.
492 @param Source A pointer to a Null-terminated Unicode string.
493 @param Length The maximum number of Unicode characters to copy.
494
495 @retval RETURN_SUCCESS String is appended.
496 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
497 StrLen(Destination).
498 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
499 greater than MIN(StrLen(Source), Length).
500 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
501 If Source is NULL.
502 If PcdMaximumUnicodeStringLength is not zero,
503 and DestMax is greater than
504 PcdMaximumUnicodeStringLength.
505 If DestMax is 0.
506 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
507 **/
508 RETURN_STATUS
509 EFIAPI
510 StrnCatS (
511 IN OUT CHAR16 *Destination,
512 IN UINTN DestMax,
513 IN CONST CHAR16 *Source,
514 IN UINTN Length
515 )
516 {
517 UINTN DestLen;
518 UINTN CopyLen;
519 UINTN SourceLen;
520
521 ASSERT (((UINTN) Destination & BIT0) == 0);
522 ASSERT (((UINTN) Source & BIT0) == 0);
523
524 //
525 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
526 //
527 DestLen = StrnLenS (Destination, DestMax);
528 CopyLen = DestMax - DestLen;
529
530 //
531 // 1. Neither Destination nor Source shall be a null pointer.
532 //
533 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
534 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
535
536 //
537 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
538 //
539 if (RSIZE_MAX != 0) {
540 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
541 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
542 }
543
544 //
545 // 3. DestMax shall not equal zero.
546 //
547 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
548
549 //
550 // 4. CopyLen shall not equal zero.
551 //
552 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
553
554 //
555 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
556 //
557 SourceLen = StrnLenS (Source, CopyLen);
558 if (Length >= CopyLen) {
559 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
560 }
561
562 //
563 // 6. Copying shall not take place between objects that overlap.
564 //
565 if (SourceLen > Length) {
566 SourceLen = Length;
567 }
568 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
569
570 //
571 // The StrnCatS function appends not more than Length successive characters (characters
572 // that follow a null character are not copied) from the array pointed to by Source to the end of
573 // the string pointed to by Destination. The initial character from Source overwrites the null character at
574 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
575 // a null character.
576 //
577 Destination = Destination + DestLen;
578 while ((*Source != 0) && (SourceLen > 0)) {
579 *(Destination++) = *(Source++);
580 SourceLen--;
581 }
582 *Destination = 0;
583
584 return RETURN_SUCCESS;
585 }
586
587 /**
588 Returns the length of a Null-terminated Ascii string.
589
590 This function is similar as strlen_s defined in C11.
591
592 @param String A pointer to a Null-terminated Ascii string.
593 @param MaxSize The maximum number of Destination Ascii
594 char, including terminating null char.
595
596 @retval 0 If String is NULL.
597 @retval MaxSize If there is no null character in the first MaxSize characters of String.
598 @return The number of characters that percede the terminating null character.
599
600 **/
601 UINTN
602 EFIAPI
603 AsciiStrnLenS (
604 IN CONST CHAR8 *String,
605 IN UINTN MaxSize
606 )
607 {
608 UINTN Length;
609
610 //
611 // If String is a null pointer, then the AsciiStrnLenS function returns zero.
612 //
613 if (String == NULL) {
614 return 0;
615 }
616
617 //
618 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
619 // terminating null character. If there is no null character in the first MaxSize characters of
620 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
621 // be accessed by AsciiStrnLenS.
622 //
623 Length = 0;
624 while (String[Length] != 0) {
625 if (Length >= MaxSize - 1) {
626 return MaxSize;
627 }
628 Length++;
629 }
630 return Length;
631 }
632
633 /**
634 Returns the size of a Null-terminated Ascii string in bytes, including the
635 Null terminator.
636
637 This function returns the size of the Null-terminated Ascii string specified
638 by String in bytes, including the Null terminator.
639
640 @param String A pointer to a Null-terminated Ascii string.
641 @param MaxSize The maximum number of Destination Ascii
642 char, including the Null terminator.
643
644 @retval 0 If String is NULL.
645 @retval (sizeof (CHAR8) * (MaxSize + 1))
646 If there is no Null terminator in the first MaxSize characters of
647 String.
648 @return The size of the Null-terminated Ascii string in bytes, including the
649 Null terminator.
650
651 **/
652 UINTN
653 EFIAPI
654 AsciiStrnSizeS (
655 IN CONST CHAR8 *String,
656 IN UINTN MaxSize
657 )
658 {
659 //
660 // If String is a null pointer, then the AsciiStrnSizeS function returns
661 // zero.
662 //
663 if (String == NULL) {
664 return 0;
665 }
666
667 //
668 // Otherwise, the AsciiStrnSizeS function returns the size of the
669 // Null-terminated Ascii string in bytes, including the Null terminator. If
670 // there is no Null terminator in the first MaxSize characters of String,
671 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
672 // consistent map with the AsciiStrnLenS function.
673 //
674 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);
675 }
676
677 /**
678 Copies the string pointed to by Source (including the terminating null char)
679 to the array pointed to by Destination.
680
681 This function is similar as strcpy_s defined in C11.
682
683 If an error would be returned, then the function will also ASSERT().
684
685 If an error is returned, then the Destination is unmodified.
686
687 @param Destination A pointer to a Null-terminated Ascii string.
688 @param DestMax The maximum number of Destination Ascii
689 char, including terminating null char.
690 @param Source A pointer to a Null-terminated Ascii string.
691
692 @retval RETURN_SUCCESS String is copied.
693 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
694 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
695 If Source is NULL.
696 If PcdMaximumAsciiStringLength is not zero,
697 and DestMax is greater than
698 PcdMaximumAsciiStringLength.
699 If DestMax is 0.
700 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
701 **/
702 RETURN_STATUS
703 EFIAPI
704 AsciiStrCpyS (
705 OUT CHAR8 *Destination,
706 IN UINTN DestMax,
707 IN CONST CHAR8 *Source
708 )
709 {
710 UINTN SourceLen;
711
712 //
713 // 1. Neither Destination nor Source shall be a null pointer.
714 //
715 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
716 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
717
718 //
719 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
720 //
721 if (ASCII_RSIZE_MAX != 0) {
722 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
723 }
724
725 //
726 // 3. DestMax shall not equal zero.
727 //
728 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
729
730 //
731 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
732 //
733 SourceLen = AsciiStrnLenS (Source, DestMax);
734 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
735
736 //
737 // 5. Copying shall not take place between objects that overlap.
738 //
739 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
740
741 //
742 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
743 // null character) into the array pointed to by Destination.
744 //
745 while (*Source != 0) {
746 *(Destination++) = *(Source++);
747 }
748 *Destination = 0;
749
750 return RETURN_SUCCESS;
751 }
752
753 /**
754 Copies not more than Length successive char from the string pointed to by
755 Source to the array pointed to by Destination. If no null char is copied from
756 Source, then Destination[Length] is always set to null.
757
758 This function is similar as strncpy_s defined in C11.
759
760 If an error would be returned, then the function will also ASSERT().
761
762 If an error is returned, then the Destination is unmodified.
763
764 @param Destination A pointer to a Null-terminated Ascii string.
765 @param DestMax The maximum number of Destination Ascii
766 char, including terminating null char.
767 @param Source A pointer to a Null-terminated Ascii string.
768 @param Length The maximum number of Ascii characters to copy.
769
770 @retval RETURN_SUCCESS String is copied.
771 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
772 MIN(StrLen(Source), Length).
773 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
774 If Source is NULL.
775 If PcdMaximumAsciiStringLength is not zero,
776 and DestMax is greater than
777 PcdMaximumAsciiStringLength.
778 If DestMax is 0.
779 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
780 **/
781 RETURN_STATUS
782 EFIAPI
783 AsciiStrnCpyS (
784 OUT CHAR8 *Destination,
785 IN UINTN DestMax,
786 IN CONST CHAR8 *Source,
787 IN UINTN Length
788 )
789 {
790 UINTN SourceLen;
791
792 //
793 // 1. Neither Destination nor Source shall be a null pointer.
794 //
795 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
796 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
797
798 //
799 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
800 //
801 if (ASCII_RSIZE_MAX != 0) {
802 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
803 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
804 }
805
806 //
807 // 3. DestMax shall not equal zero.
808 //
809 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
810
811 //
812 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
813 //
814 SourceLen = AsciiStrnLenS (Source, DestMax);
815 if (Length >= DestMax) {
816 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
817 }
818
819 //
820 // 5. Copying shall not take place between objects that overlap.
821 //
822 if (SourceLen > Length) {
823 SourceLen = Length;
824 }
825 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
826
827 //
828 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
829 // follow a null character are not copied) from the array pointed to by Source to the array
830 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
831 // character.
832 //
833 while ((*Source != 0) && (SourceLen > 0)) {
834 *(Destination++) = *(Source++);
835 SourceLen--;
836 }
837 *Destination = 0;
838
839 return RETURN_SUCCESS;
840 }
841
842 /**
843 Appends a copy of the string pointed to by Source (including the terminating
844 null char) to the end of the string pointed to by Destination.
845
846 This function is similar as strcat_s defined in C11.
847
848 If an error would be returned, then the function will also ASSERT().
849
850 If an error is returned, then the Destination is unmodified.
851
852 @param Destination A pointer to a Null-terminated Ascii string.
853 @param DestMax The maximum number of Destination Ascii
854 char, including terminating null char.
855 @param Source A pointer to a Null-terminated Ascii string.
856
857 @retval RETURN_SUCCESS String is appended.
858 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
859 StrLen(Destination).
860 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
861 greater than StrLen(Source).
862 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
863 If Source is NULL.
864 If PcdMaximumAsciiStringLength is not zero,
865 and DestMax is greater than
866 PcdMaximumAsciiStringLength.
867 If DestMax is 0.
868 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
869 **/
870 RETURN_STATUS
871 EFIAPI
872 AsciiStrCatS (
873 IN OUT CHAR8 *Destination,
874 IN UINTN DestMax,
875 IN CONST CHAR8 *Source
876 )
877 {
878 UINTN DestLen;
879 UINTN CopyLen;
880 UINTN SourceLen;
881
882 //
883 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
884 //
885 DestLen = AsciiStrnLenS (Destination, DestMax);
886 CopyLen = DestMax - DestLen;
887
888 //
889 // 1. Neither Destination nor Source shall be a null pointer.
890 //
891 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
892 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
893
894 //
895 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
896 //
897 if (ASCII_RSIZE_MAX != 0) {
898 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
899 }
900
901 //
902 // 3. DestMax shall not equal zero.
903 //
904 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
905
906 //
907 // 4. CopyLen shall not equal zero.
908 //
909 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
910
911 //
912 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
913 //
914 SourceLen = AsciiStrnLenS (Source, CopyLen);
915 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
916
917 //
918 // 6. Copying shall not take place between objects that overlap.
919 //
920 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
921
922 //
923 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
924 // terminating null character) to the end of the string pointed to by Destination. The initial character
925 // from Source overwrites the null character at the end of Destination.
926 //
927 Destination = Destination + DestLen;
928 while (*Source != 0) {
929 *(Destination++) = *(Source++);
930 }
931 *Destination = 0;
932
933 return RETURN_SUCCESS;
934 }
935
936 /**
937 Appends not more than Length successive char from the string pointed to by
938 Source to the end of the string pointed to by Destination. If no null char is
939 copied from Source, then Destination[StrLen(Destination) + Length] is always
940 set to null.
941
942 This function is similar as strncat_s defined in C11.
943
944 If an error would be returned, then the function will also ASSERT().
945
946 If an error is returned, then the Destination is unmodified.
947
948 @param Destination A pointer to a Null-terminated Ascii string.
949 @param DestMax The maximum number of Destination Ascii
950 char, including terminating null char.
951 @param Source A pointer to a Null-terminated Ascii string.
952 @param Length The maximum number of Ascii characters to copy.
953
954 @retval RETURN_SUCCESS String is appended.
955 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
956 StrLen(Destination).
957 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
958 greater than MIN(StrLen(Source), Length).
959 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
960 If Source is NULL.
961 If PcdMaximumAsciiStringLength is not zero,
962 and DestMax is greater than
963 PcdMaximumAsciiStringLength.
964 If DestMax is 0.
965 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
966 **/
967 RETURN_STATUS
968 EFIAPI
969 AsciiStrnCatS (
970 IN OUT CHAR8 *Destination,
971 IN UINTN DestMax,
972 IN CONST CHAR8 *Source,
973 IN UINTN Length
974 )
975 {
976 UINTN DestLen;
977 UINTN CopyLen;
978 UINTN SourceLen;
979
980 //
981 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
982 //
983 DestLen = AsciiStrnLenS (Destination, DestMax);
984 CopyLen = DestMax - DestLen;
985
986 //
987 // 1. Neither Destination nor Source shall be a null pointer.
988 //
989 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
990 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
991
992 //
993 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
994 //
995 if (ASCII_RSIZE_MAX != 0) {
996 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
997 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
998 }
999
1000 //
1001 // 3. DestMax shall not equal zero.
1002 //
1003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1004
1005 //
1006 // 4. CopyLen shall not equal zero.
1007 //
1008 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
1009
1010 //
1011 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1012 //
1013 SourceLen = AsciiStrnLenS (Source, CopyLen);
1014 if (Length >= CopyLen) {
1015 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
1016 }
1017
1018 //
1019 // 6. Copying shall not take place between objects that overlap.
1020 //
1021 if (SourceLen > Length) {
1022 SourceLen = Length;
1023 }
1024 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1025
1026 //
1027 // The AsciiStrnCatS function appends not more than Length successive characters (characters
1028 // that follow a null character are not copied) from the array pointed to by Source to the end of
1029 // the string pointed to by Destination. The initial character from Source overwrites the null character at
1030 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
1031 // a null character.
1032 //
1033 Destination = Destination + DestLen;
1034 while ((*Source != 0) && (SourceLen > 0)) {
1035 *(Destination++) = *(Source++);
1036 SourceLen--;
1037 }
1038 *Destination = 0;
1039
1040 return RETURN_SUCCESS;
1041 }
1042
1043 /**
1044 Convert a Null-terminated Unicode string to a Null-terminated
1045 ASCII string.
1046
1047 This function is similar to AsciiStrCpyS.
1048
1049 This function converts the content of the Unicode string Source
1050 to the ASCII string Destination by copying the lower 8 bits of
1051 each Unicode character. The function terminates the ASCII string
1052 Destination by appending a Null-terminator character at the end.
1053
1054 The caller is responsible to make sure Destination points to a buffer with size
1055 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
1056
1057 If any Unicode characters in Source contain non-zero value in
1058 the upper 8 bits, then ASSERT().
1059
1060 If Source is not aligned on a 16-bit boundary, then ASSERT().
1061 If an error would be returned, then the function will also ASSERT().
1062
1063 If an error is returned, then the Destination is unmodified.
1064
1065 @param Source The pointer to a Null-terminated Unicode string.
1066 @param Destination The pointer to a Null-terminated ASCII string.
1067 @param DestMax The maximum number of Destination Ascii
1068 char, including terminating null char.
1069
1070 @retval RETURN_SUCCESS String is converted.
1071 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1072 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1073 If Source is NULL.
1074 If PcdMaximumAsciiStringLength is not zero,
1075 and DestMax is greater than
1076 PcdMaximumAsciiStringLength.
1077 If PcdMaximumUnicodeStringLength is not zero,
1078 and DestMax is greater than
1079 PcdMaximumUnicodeStringLength.
1080 If DestMax is 0.
1081 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1082
1083 **/
1084 RETURN_STATUS
1085 EFIAPI
1086 UnicodeStrToAsciiStrS (
1087 IN CONST CHAR16 *Source,
1088 OUT CHAR8 *Destination,
1089 IN UINTN DestMax
1090 )
1091 {
1092 UINTN SourceLen;
1093
1094 ASSERT (((UINTN) Source & BIT0) == 0);
1095
1096 //
1097 // 1. Neither Destination nor Source shall be a null pointer.
1098 //
1099 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1100 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1101
1102 //
1103 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
1104 //
1105 if (ASCII_RSIZE_MAX != 0) {
1106 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1107 }
1108 if (RSIZE_MAX != 0) {
1109 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1110 }
1111
1112 //
1113 // 3. DestMax shall not equal zero.
1114 //
1115 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1116
1117 //
1118 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
1119 //
1120 SourceLen = StrnLenS (Source, DestMax);
1121 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1122
1123 //
1124 // 5. Copying shall not take place between objects that overlap.
1125 //
1126 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
1127
1128 //
1129 // convert string
1130 //
1131 while (*Source != '\0') {
1132 //
1133 // If any Unicode characters in Source contain
1134 // non-zero value in the upper 8 bits, then ASSERT().
1135 //
1136 ASSERT (*Source < 0x100);
1137 *(Destination++) = (CHAR8) *(Source++);
1138 }
1139 *Destination = '\0';
1140
1141 return RETURN_SUCCESS;
1142 }
1143
1144
1145 /**
1146 Convert one Null-terminated ASCII string to a Null-terminated
1147 Unicode string.
1148
1149 This function is similar to StrCpyS.
1150
1151 This function converts the contents of the ASCII string Source to the Unicode
1152 string Destination. The function terminates the Unicode string Destination by
1153 appending a Null-terminator character at the end.
1154
1155 The caller is responsible to make sure Destination points to a buffer with size
1156 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
1157
1158 If Destination is not aligned on a 16-bit boundary, then ASSERT().
1159 If an error would be returned, then the function will also ASSERT().
1160
1161 If an error is returned, then the Destination is unmodified.
1162
1163 @param Source The pointer to a Null-terminated ASCII string.
1164 @param Destination The pointer to a Null-terminated Unicode string.
1165 @param DestMax The maximum number of Destination Unicode
1166 char, including terminating null char.
1167
1168 @retval RETURN_SUCCESS String is converted.
1169 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1170 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1171 If Source is NULL.
1172 If PcdMaximumUnicodeStringLength is not zero,
1173 and DestMax is greater than
1174 PcdMaximumUnicodeStringLength.
1175 If PcdMaximumAsciiStringLength is not zero,
1176 and DestMax is greater than
1177 PcdMaximumAsciiStringLength.
1178 If DestMax is 0.
1179 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1180
1181 **/
1182 RETURN_STATUS
1183 EFIAPI
1184 AsciiStrToUnicodeStrS (
1185 IN CONST CHAR8 *Source,
1186 OUT CHAR16 *Destination,
1187 IN UINTN DestMax
1188 )
1189 {
1190 UINTN SourceLen;
1191
1192 ASSERT (((UINTN) Destination & BIT0) == 0);
1193
1194 //
1195 // 1. Neither Destination nor Source shall be a null pointer.
1196 //
1197 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
1198 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
1199
1200 //
1201 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
1202 //
1203 if (RSIZE_MAX != 0) {
1204 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
1205 }
1206 if (ASCII_RSIZE_MAX != 0) {
1207 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
1208 }
1209
1210 //
1211 // 3. DestMax shall not equal zero.
1212 //
1213 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
1214
1215 //
1216 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1217 //
1218 SourceLen = AsciiStrnLenS (Source, DestMax);
1219 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
1220
1221 //
1222 // 5. Copying shall not take place between objects that overlap.
1223 //
1224 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
1225
1226 //
1227 // Convert string
1228 //
1229 while (*Source != '\0') {
1230 *(Destination++) = (CHAR16)*(Source++);
1231 }
1232 *Destination = '\0';
1233
1234 return RETURN_SUCCESS;
1235 }