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