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