blob: 7d7765bc01ce6a751bd5647cfeacb59b6125cfb4 [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @file
2 Safe String functions.
3
4 Copyright (c) 2014, 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**/
43BOOLEAN
44InternalSafeStringIsOverlap (
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**/
71BOOLEAN
72InternalSafeStringNoStrOverlap (
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**/
95BOOLEAN
96InternalSafeStringNoAsciiStrOverlap (
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 If String is not aligned on a 16-bit boundary, then ASSERT().
110
111 @param String A pointer to a Null-terminated Unicode string.
112 @param MaxSize The maximum number of Destination Unicode
113 char, including terminating null char.
114
115 @retval 0 If String is NULL.
116 @retval MaxSize If there is no null character in the first MaxSize characters of String.
117 @return The number of characters that percede the terminating null character.
118
119**/
120UINTN
121EFIAPI
122StrnLenS (
123 IN CONST CHAR16 *String,
124 IN UINTN MaxSize
125 )
126{
127 UINTN Length;
128
129 ASSERT (((UINTN) String & BIT0) == 0);
130
131 //
132 // If String is a null pointer, then the StrnLenS function returns zero.
133 //
134 if (String == NULL) {
135 return 0;
136 }
137
138 //
139 // Otherwise, the StrnLenS function returns the number of characters that precede the
140 // terminating null character. If there is no null character in the first MaxSize characters of
141 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
142 // be accessed by StrnLenS.
143 //
144 for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {
145 ;
146 }
147 return Length;
148}
149
150/**
151 Copies the string pointed to by Source (including the terminating null char)
152 to the array pointed to by Destination.
153
154 If Destination is not aligned on a 16-bit boundary, then ASSERT().
155 If Source is not aligned on a 16-bit boundary, then ASSERT().
156
157 @param Destination A pointer to a Null-terminated Unicode string.
158 @param DestMax The maximum number of Destination Unicode
159 char, including terminating null char.
160 @param Source A pointer to a Null-terminated Unicode string.
161
162 @retval RETURN_SUCCESS String is copied.
163 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
164 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
165 If Source is NULL.
166 If PcdMaximumUnicodeStringLength is not zero,
167 and DestMax is greater than
168 PcdMaximumUnicodeStringLength.
169 If DestMax is 0.
170 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
171**/
172RETURN_STATUS
173EFIAPI
174StrCpyS (
175 OUT CHAR16 *Destination,
176 IN UINTN DestMax,
177 IN CONST CHAR16 *Source
178 )
179{
180 UINTN SourceLen;
181
182 ASSERT (((UINTN) Destination & BIT0) == 0);
183 ASSERT (((UINTN) Source & BIT0) == 0);
184
185 //
186 // 1. Neither Destination nor Source shall be a null pointer.
187 //
188 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
189 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
190
191 //
192 // 2. DestMax shall not be greater than RSIZE_MAX.
193 //
194 if (RSIZE_MAX != 0) {
195 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
196 }
197
198 //
199 // 3. DestMax shall not equal zero.
200 //
201 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
202
203 //
204 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
205 //
206 SourceLen = StrnLenS (Source, DestMax);
207 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
208
209 //
210 // 5. Copying shall not take place between objects that overlap.
211 //
212 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
213
214 //
215 // The StrCpyS function copies the string pointed to by Source (including the terminating
216 // null character) into the array pointed to by Destination.
217 //
218 while (*Source != 0) {
219 *(Destination++) = *(Source++);
220 }
221 *Destination = 0;
222
223 return RETURN_SUCCESS;
224}
225
226/**
227 Copies not more than Length successive char from the string pointed to by
228 Source to the array pointed to by Destination. If no null char is copied from
229 Source, then Destination[Length] is always set to null.
230
231 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
232 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
233
234 @param Destination A pointer to a Null-terminated Unicode string.
235 @param DestMax The maximum number of Destination Unicode
236 char, including terminating null char.
237 @param Source A pointer to a Null-terminated Unicode string.
238 @param Length The maximum number of Unicode characters to copy.
239
240 @retval RETURN_SUCCESS String is copied.
241 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
242 MIN(StrLen(Source), Length).
243 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
244 If Source is NULL.
245 If PcdMaximumUnicodeStringLength is not zero,
246 and DestMax is greater than
247 PcdMaximumUnicodeStringLength.
248 If DestMax is 0.
249 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
250**/
251RETURN_STATUS
252EFIAPI
253StrnCpyS (
254 OUT CHAR16 *Destination,
255 IN UINTN DestMax,
256 IN CONST CHAR16 *Source,
257 IN UINTN Length
258 )
259{
260 UINTN SourceLen;
261
262 ASSERT (((UINTN) Destination & BIT0) == 0);
263 ASSERT (((UINTN) Source & BIT0) == 0);
264
265 //
266 // 1. Neither Destination nor Source shall be a null pointer.
267 //
268 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
269 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
270
271 //
272 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
273 //
274 if (RSIZE_MAX != 0) {
275 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
276 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
277 }
278
279 //
280 // 3. DestMax shall not equal zero.
281 //
282 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
283
284 //
285 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
286 //
287 SourceLen = StrnLenS (Source, DestMax);
288 if (Length >= DestMax) {
289 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
290 }
291
292 //
293 // 5. Copying shall not take place between objects that overlap.
294 //
295 if (SourceLen > Length) {
296 SourceLen = Length;
297 }
298 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
299
300 //
301 // The StrnCpyS function copies not more than Length successive characters (characters that
302 // follow a null character are not copied) from the array pointed to by Source to the array
303 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
304 // character.
305 //
306 while ((*Source != 0) && (SourceLen > 0)) {
307 *(Destination++) = *(Source++);
308 SourceLen--;
309 }
310 *Destination = 0;
311
312 return RETURN_SUCCESS;
313}
314
315/**
316 Appends a copy of the string pointed to by Source (including the terminating
317 null char) to the end of the string pointed to by Destination.
318
319 If Destination is not aligned on a 16-bit boundary, then ASSERT().
320 If Source is not aligned on a 16-bit boundary, then ASSERT().
321
322 @param Destination A pointer to a Null-terminated Unicode string.
323 @param DestMax The maximum number of Destination Unicode
324 char, including terminating null char.
325 @param Source A pointer to a Null-terminated Unicode string.
326
327 @retval RETURN_SUCCESS String is appended.
328 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
329 StrLen(Destination).
330 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
331 greater than StrLen(Source).
332 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
333 If Source is NULL.
334 If PcdMaximumUnicodeStringLength is not zero,
335 and DestMax is greater than
336 PcdMaximumUnicodeStringLength.
337 If DestMax is 0.
338 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
339**/
340RETURN_STATUS
341EFIAPI
342StrCatS (
343 IN OUT CHAR16 *Destination,
344 IN UINTN DestMax,
345 IN CONST CHAR16 *Source
346 )
347{
348 UINTN DestLen;
349 UINTN CopyLen;
350 UINTN SourceLen;
351
352 ASSERT (((UINTN) Destination & BIT0) == 0);
353 ASSERT (((UINTN) Source & BIT0) == 0);
354
355 //
356 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
357 //
358 DestLen = StrnLenS (Destination, DestMax);
359 CopyLen = DestMax - DestLen;
360
361 //
362 // 1. Neither Destination nor Source shall be a null pointer.
363 //
364 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
365 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
366
367 //
368 // 2. DestMax shall not be greater than RSIZE_MAX.
369 //
370 if (RSIZE_MAX != 0) {
371 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
372 }
373
374 //
375 // 3. DestMax shall not equal zero.
376 //
377 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
378
379 //
380 // 4. CopyLen shall not equal zero.
381 //
382 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
383
384 //
385 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
386 //
387 SourceLen = StrnLenS (Source, CopyLen);
388 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
389
390 //
391 // 6. Copying shall not take place between objects that overlap.
392 //
393 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
394
395 //
396 // The StrCatS function appends a copy of the string pointed to by Source (including the
397 // terminating null character) to the end of the string pointed to by Destination. The initial character
398 // from Source overwrites the null character at the end of Destination.
399 //
400 Destination = Destination + DestLen;
401 while (*Source != 0) {
402 *(Destination++) = *(Source++);
403 }
404 *Destination = 0;
405
406 return RETURN_SUCCESS;
407}
408
409/**
410 Appends not more than Length successive char from the string pointed to by
411 Source to the end of the string pointed to by Destination. If no null char is
412 copied from Source, then Destination[StrLen(Destination) + Length] is always
413 set to null.
414
415 If Destination is not aligned on a 16-bit boundary, then ASSERT().
416 If and Source is not aligned on a 16-bit boundary, then ASSERT().
417
418 @param Destination A pointer to a Null-terminated Unicode string.
419 @param DestMax The maximum number of Destination Unicode
420 char, including terminating null char.
421 @param Source A pointer to a Null-terminated Unicode string.
422 @param Length The maximum number of Unicode characters to copy.
423
424 @retval RETURN_SUCCESS String is appended.
425 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
426 StrLen(Destination).
427 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
428 greater than MIN(StrLen(Source), Length).
429 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
430 If Source is NULL.
431 If PcdMaximumUnicodeStringLength is not zero,
432 and DestMax is greater than
433 PcdMaximumUnicodeStringLength.
434 If DestMax is 0.
435 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
436**/
437RETURN_STATUS
438EFIAPI
439StrnCatS (
440 IN OUT CHAR16 *Destination,
441 IN UINTN DestMax,
442 IN CONST CHAR16 *Source,
443 IN UINTN Length
444 )
445{
446 UINTN DestLen;
447 UINTN CopyLen;
448 UINTN SourceLen;
449
450 ASSERT (((UINTN) Destination & BIT0) == 0);
451 ASSERT (((UINTN) Source & BIT0) == 0);
452
453 //
454 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
455 //
456 DestLen = StrnLenS (Destination, DestMax);
457 CopyLen = DestMax - DestLen;
458
459 //
460 // 1. Neither Destination nor Source shall be a null pointer.
461 //
462 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
463 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
464
465 //
466 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
467 //
468 if (RSIZE_MAX != 0) {
469 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
470 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
471 }
472
473 //
474 // 3. DestMax shall not equal zero.
475 //
476 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
477
478 //
479 // 4. CopyLen shall not equal zero.
480 //
481 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
482
483 //
484 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
485 //
486 SourceLen = StrnLenS (Source, CopyLen);
487 if (Length >= CopyLen) {
488 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
489 }
490
491 //
492 // 6. Copying shall not take place between objects that overlap.
493 //
494 if (SourceLen > Length) {
495 SourceLen = Length;
496 }
497 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
498
499 //
500 // The StrnCatS function appends not more than Length successive characters (characters
501 // that follow a null character are not copied) from the array pointed to by Source to the end of
502 // the string pointed to by Destination. The initial character from Source overwrites the null character at
503 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
504 // a null character.
505 //
506 Destination = Destination + DestLen;
507 while ((*Source != 0) && (SourceLen > 0)) {
508 *(Destination++) = *(Source++);
509 SourceLen--;
510 }
511 *Destination = 0;
512
513 return RETURN_SUCCESS;
514}
515
516/**
517 Returns the length of a Null-terminated Ascii string.
518
519 @param String A pointer to a Null-terminated Ascii string.
520 @param MaxSize The maximum number of Destination Ascii
521 char, including terminating null char.
522
523 @retval 0 If String is NULL.
524 @retval MaxSize If there is no null character in the first MaxSize characters of String.
525 @return The number of characters that percede the terminating null character.
526
527**/
528UINTN
529EFIAPI
530AsciiStrnLenS (
531 IN CONST CHAR8 *String,
532 IN UINTN MaxSize
533 )
534{
535 UINTN Length;
536
537 //
538 // If String is a null pointer, then the AsciiStrnLenS function returns zero.
539 //
540 if (String == NULL) {
541 return 0;
542 }
543
544 //
545 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
546 // terminating null character. If there is no null character in the first MaxSize characters of
547 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
548 // be accessed by AsciiStrnLenS.
549 //
550 for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {
551 ;
552 }
553 return Length;
554}
555
556/**
557 Copies the string pointed to by Source (including the terminating null char)
558 to the array pointed to by Destination.
559
560 @param Destination A pointer to a Null-terminated Ascii string.
561 @param DestMax The maximum number of Destination Ascii
562 char, including terminating null char.
563 @param Source A pointer to a Null-terminated Ascii string.
564
565 @retval RETURN_SUCCESS String is copied.
566 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
567 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
568 If Source is NULL.
569 If PcdMaximumAsciiStringLength is not zero,
570 and DestMax is greater than
571 PcdMaximumAsciiStringLength.
572 If DestMax is 0.
573 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
574**/
575RETURN_STATUS
576EFIAPI
577AsciiStrCpyS (
578 OUT CHAR8 *Destination,
579 IN UINTN DestMax,
580 IN CONST CHAR8 *Source
581 )
582{
583 UINTN SourceLen;
584
585 //
586 // 1. Neither Destination nor Source shall be a null pointer.
587 //
588 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
589 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
590
591 //
592 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
593 //
594 if (ASCII_RSIZE_MAX != 0) {
595 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
596 }
597
598 //
599 // 3. DestMax shall not equal zero.
600 //
601 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
602
603 //
604 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
605 //
606 SourceLen = AsciiStrnLenS (Source, DestMax);
607 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
608
609 //
610 // 5. Copying shall not take place between objects that overlap.
611 //
612 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
613
614 //
615 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
616 // null character) into the array pointed to by Destination.
617 //
618 while (*Source != 0) {
619 *(Destination++) = *(Source++);
620 }
621 *Destination = 0;
622
623 return RETURN_SUCCESS;
624}
625
626/**
627 Copies not more than Length successive char from the string pointed to by
628 Source to the array pointed to by Destination. If no null char is copied from
629 Source, then Destination[Length] is always set to null.
630
631 @param Destination A pointer to a Null-terminated Ascii string.
632 @param DestMax The maximum number of Destination Ascii
633 char, including terminating null char.
634 @param Source A pointer to a Null-terminated Ascii string.
635 @param Length The maximum number of Ascii characters to copy.
636
637 @retval RETURN_SUCCESS String is copied.
638 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
639 MIN(StrLen(Source), Length).
640 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
641 If Source is NULL.
642 If PcdMaximumAsciiStringLength is not zero,
643 and DestMax is greater than
644 PcdMaximumAsciiStringLength.
645 If DestMax is 0.
646 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
647**/
648RETURN_STATUS
649EFIAPI
650AsciiStrnCpyS (
651 OUT CHAR8 *Destination,
652 IN UINTN DestMax,
653 IN CONST CHAR8 *Source,
654 IN UINTN Length
655 )
656{
657 UINTN SourceLen;
658
659 //
660 // 1. Neither Destination nor Source shall be a null pointer.
661 //
662 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
663 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
664
665 //
666 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
667 //
668 if (ASCII_RSIZE_MAX != 0) {
669 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
670 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
671 }
672
673 //
674 // 3. DestMax shall not equal zero.
675 //
676 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
677
678 //
679 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
680 //
681 SourceLen = AsciiStrnLenS (Source, DestMax);
682 if (Length >= DestMax) {
683 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
684 }
685
686 //
687 // 5. Copying shall not take place between objects that overlap.
688 //
689 if (SourceLen > Length) {
690 SourceLen = Length;
691 }
692 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
693
694 //
695 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
696 // follow a null character are not copied) from the array pointed to by Source to the array
697 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
698 // character.
699 //
700 while ((*Source != 0) && (SourceLen > 0)) {
701 *(Destination++) = *(Source++);
702 SourceLen--;
703 }
704 *Destination = 0;
705
706 return RETURN_SUCCESS;
707}
708
709/**
710 Appends a copy of the string pointed to by Source (including the terminating
711 null char) to the end of the string pointed to by Destination.
712
713 @param Destination A pointer to a Null-terminated Ascii string.
714 @param DestMax The maximum number of Destination Ascii
715 char, including terminating null char.
716 @param Source A pointer to a Null-terminated Ascii string.
717
718 @retval RETURN_SUCCESS String is appended.
719 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
720 StrLen(Destination).
721 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
722 greater than StrLen(Source).
723 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
724 If Source is NULL.
725 If PcdMaximumAsciiStringLength is not zero,
726 and DestMax is greater than
727 PcdMaximumAsciiStringLength.
728 If DestMax is 0.
729 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
730**/
731RETURN_STATUS
732EFIAPI
733AsciiStrCatS (
734 IN OUT CHAR8 *Destination,
735 IN UINTN DestMax,
736 IN CONST CHAR8 *Source
737 )
738{
739 UINTN DestLen;
740 UINTN CopyLen;
741 UINTN SourceLen;
742
743 //
744 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
745 //
746 DestLen = AsciiStrnLenS (Destination, DestMax);
747 CopyLen = DestMax - DestLen;
748
749 //
750 // 1. Neither Destination nor Source shall be a null pointer.
751 //
752 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
753 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
754
755 //
756 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
757 //
758 if (ASCII_RSIZE_MAX != 0) {
759 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
760 }
761
762 //
763 // 3. DestMax shall not equal zero.
764 //
765 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
766
767 //
768 // 4. CopyLen shall not equal zero.
769 //
770 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
771
772 //
773 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
774 //
775 SourceLen = AsciiStrnLenS (Source, CopyLen);
776 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
777
778 //
779 // 6. Copying shall not take place between objects that overlap.
780 //
781 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
782
783 //
784 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
785 // terminating null character) to the end of the string pointed to by Destination. The initial character
786 // from Source overwrites the null character at the end of Destination.
787 //
788 Destination = Destination + DestLen;
789 while (*Source != 0) {
790 *(Destination++) = *(Source++);
791 }
792 *Destination = 0;
793
794 return RETURN_SUCCESS;
795}
796
797/**
798 Appends not more than Length successive char from the string pointed to by
799 Source to the end of the string pointed to by Destination. If no null char is
800 copied from Source, then Destination[StrLen(Destination) + Length] is always
801 set to null.
802
803 @param Destination A pointer to a Null-terminated Ascii string.
804 @param DestMax The maximum number of Destination Ascii
805 char, including terminating null char.
806 @param Source A pointer to a Null-terminated Ascii string.
807 @param Length The maximum number of Ascii characters to copy.
808
809 @retval RETURN_SUCCESS String is appended.
810 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
811 StrLen(Destination).
812 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
813 greater than MIN(StrLen(Source), Length).
814 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
815 If Source is NULL.
816 If PcdMaximumAsciiStringLength is not zero,
817 and DestMax is greater than
818 PcdMaximumAsciiStringLength.
819 If DestMax is 0.
820 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
821**/
822RETURN_STATUS
823EFIAPI
824AsciiStrnCatS (
825 IN OUT CHAR8 *Destination,
826 IN UINTN DestMax,
827 IN CONST CHAR8 *Source,
828 IN UINTN Length
829 )
830{
831 UINTN DestLen;
832 UINTN CopyLen;
833 UINTN SourceLen;
834
835 //
836 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
837 //
838 DestLen = AsciiStrnLenS (Destination, DestMax);
839 CopyLen = DestMax - DestLen;
840
841 //
842 // 1. Neither Destination nor Source shall be a null pointer.
843 //
844 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
845 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
846
847 //
848 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
849 //
850 if (ASCII_RSIZE_MAX != 0) {
851 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
852 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
853 }
854
855 //
856 // 3. DestMax shall not equal zero.
857 //
858 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
859
860 //
861 // 4. CopyLen shall not equal zero.
862 //
863 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);
864
865 //
866 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
867 //
868 SourceLen = AsciiStrnLenS (Source, CopyLen);
869 if (Length >= CopyLen) {
870 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);
871 }
872
873 //
874 // 6. Copying shall not take place between objects that overlap.
875 //
876 if (SourceLen > Length) {
877 SourceLen = Length;
878 }
879 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
880
881 //
882 // The AsciiStrnCatS function appends not more than Length successive characters (characters
883 // that follow a null character are not copied) from the array pointed to by Source to the end of
884 // the string pointed to by Destination. The initial character from Source overwrites the null character at
885 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
886 // a null character.
887 //
888 Destination = Destination + DestLen;
889 while ((*Source != 0) && (SourceLen > 0)) {
890 *(Destination++) = *(Source++);
891 SourceLen--;
892 }
893 *Destination = 0;
894
895 return RETURN_SUCCESS;
896}