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