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