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