]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/SafeString.c
MdePkg/BaseLib: Add safe string functions [U|A]StrnTo[A|U]StrS
[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
d8af3301 15#include "BaseLibInternals.h"\r
c058d59f
JY
16\r
17#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))\r
18\r
19#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))\r
20\r
21#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \\r
22 do { \\r
23 ASSERT (Expression); \\r
24 if (!(Expression)) { \\r
25 return Status; \\r
26 } \\r
27 } while (FALSE)\r
28\r
29/**\r
30 Returns if 2 memory blocks are overlapped.\r
31\r
32 @param Base1 Base address of 1st memory block.\r
33 @param Size1 Size of 1st memory block.\r
34 @param Base2 Base address of 2nd memory block.\r
35 @param Size2 Size of 2nd memory block.\r
36\r
37 @retval TRUE 2 memory blocks are overlapped.\r
38 @retval FALSE 2 memory blocks are not overlapped.\r
39**/\r
40BOOLEAN\r
41InternalSafeStringIsOverlap (\r
42 IN VOID *Base1,\r
43 IN UINTN Size1,\r
44 IN VOID *Base2,\r
45 IN UINTN Size2\r
46 )\r
47{\r
48 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||\r
49 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {\r
50 return TRUE;\r
51 }\r
52 return FALSE;\r
53}\r
54\r
55/**\r
56 Returns if 2 Unicode strings are not overlapped.\r
57\r
58 @param Str1 Start address of 1st Unicode string.\r
59 @param Size1 The number of char in 1st Unicode string,\r
60 including terminating null char.\r
61 @param Str2 Start address of 2nd Unicode string.\r
62 @param Size2 The number of char in 2nd Unicode string,\r
63 including terminating null char.\r
64\r
65 @retval TRUE 2 Unicode strings are NOT overlapped.\r
66 @retval FALSE 2 Unicode strings are overlapped.\r
67**/\r
68BOOLEAN\r
69InternalSafeStringNoStrOverlap (\r
70 IN CHAR16 *Str1,\r
71 IN UINTN Size1,\r
72 IN CHAR16 *Str2,\r
73 IN UINTN Size2\r
74 )\r
75{\r
76 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));\r
77}\r
78\r
79/**\r
80 Returns if 2 Ascii strings are not overlapped.\r
81\r
82 @param Str1 Start address of 1st Ascii string.\r
83 @param Size1 The number of char in 1st Ascii string,\r
84 including terminating null char.\r
85 @param Str2 Start address of 2nd Ascii string.\r
86 @param Size2 The number of char in 2nd Ascii string,\r
87 including terminating null char.\r
88\r
89 @retval TRUE 2 Ascii strings are NOT overlapped.\r
90 @retval FALSE 2 Ascii strings are overlapped.\r
91**/\r
92BOOLEAN\r
93InternalSafeStringNoAsciiStrOverlap (\r
94 IN CHAR8 *Str1,\r
95 IN UINTN Size1,\r
96 IN CHAR8 *Str2,\r
97 IN UINTN Size2\r
98 )\r
99{\r
100 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);\r
101}\r
102\r
103/**\r
104 Returns the length of a Null-terminated Unicode string.\r
105\r
328f84b1
JY
106 This function is similar as strlen_s defined in C11.\r
107\r
c058d59f
JY
108 If String is not aligned on a 16-bit boundary, then ASSERT().\r
109\r
110 @param String A pointer to a Null-terminated Unicode string.\r
111 @param MaxSize The maximum number of Destination Unicode\r
112 char, including terminating null char.\r
113\r
114 @retval 0 If String is NULL.\r
115 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
116 @return The number of characters that percede the terminating null character.\r
117\r
118**/\r
119UINTN\r
120EFIAPI\r
121StrnLenS (\r
122 IN CONST CHAR16 *String,\r
123 IN UINTN MaxSize\r
124 )\r
125{\r
126 UINTN Length;\r
127\r
128 ASSERT (((UINTN) String & BIT0) == 0);\r
129\r
130 //\r
131 // If String is a null pointer, then the StrnLenS function returns zero.\r
132 //\r
133 if (String == NULL) {\r
134 return 0;\r
135 }\r
136\r
137 //\r
138 // Otherwise, the StrnLenS function returns the number of characters that precede the\r
139 // terminating null character. If there is no null character in the first MaxSize characters of\r
140 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
141 // be accessed by StrnLenS.\r
142 //\r
c07c517c
HW
143 Length = 0;\r
144 while (String[Length] != 0) {\r
145 if (Length >= MaxSize - 1) {\r
146 return MaxSize;\r
147 }\r
148 Length++;\r
c058d59f
JY
149 }\r
150 return Length;\r
151}\r
152\r
b590e43a
HW
153/**\r
154 Returns the size of a Null-terminated Unicode string in bytes, including the\r
155 Null terminator.\r
156\r
157 This function returns the size of the Null-terminated Unicode string\r
158 specified by String in bytes, including the Null terminator.\r
159\r
160 If String is not aligned on a 16-bit boundary, then ASSERT().\r
161\r
162 @param String A pointer to a Null-terminated Unicode string.\r
163 @param MaxSize The maximum number of Destination Unicode\r
164 char, including the Null terminator.\r
165\r
166 @retval 0 If String is NULL.\r
167 @retval (sizeof (CHAR16) * (MaxSize + 1))\r
168 If there is no Null terminator in the first MaxSize characters of\r
169 String.\r
170 @return The size of the Null-terminated Unicode string in bytes, including\r
171 the Null terminator.\r
172\r
173**/\r
174UINTN\r
175EFIAPI\r
176StrnSizeS (\r
177 IN CONST CHAR16 *String,\r
178 IN UINTN MaxSize\r
179 )\r
180{\r
181 //\r
182 // If String is a null pointer, then the StrnSizeS function returns zero.\r
183 //\r
184 if (String == NULL) {\r
185 return 0;\r
186 }\r
187\r
188 //\r
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated\r
190 // Unicode string in bytes, including the Null terminator. If there is no\r
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS\r
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with\r
193 // the StrnLenS function.\r
194 //\r
195 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
196}\r
197\r
c058d59f
JY
198/**\r
199 Copies the string pointed to by Source (including the terminating null char)\r
200 to the array pointed to by Destination.\r
201\r
328f84b1
JY
202 This function is similar as strcpy_s defined in C11.\r
203\r
c058d59f
JY
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
205 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 206 If an error would be returned, then the function will also ASSERT().\r
c058d59f 207\r
328f84b1
JY
208 If an error is returned, then the Destination is unmodified.\r
209\r
c058d59f
JY
210 @param Destination A pointer to a Null-terminated Unicode string.\r
211 @param DestMax The maximum number of Destination Unicode\r
212 char, including terminating null char.\r
213 @param Source A pointer to a Null-terminated Unicode string.\r
214\r
215 @retval RETURN_SUCCESS String is copied.\r
216 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
217 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
218 If Source is NULL.\r
219 If PcdMaximumUnicodeStringLength is not zero,\r
220 and DestMax is greater than \r
221 PcdMaximumUnicodeStringLength.\r
222 If DestMax is 0.\r
223 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
224**/\r
225RETURN_STATUS\r
226EFIAPI\r
227StrCpyS (\r
228 OUT CHAR16 *Destination,\r
229 IN UINTN DestMax,\r
230 IN CONST CHAR16 *Source\r
231 )\r
232{\r
233 UINTN SourceLen;\r
234 \r
235 ASSERT (((UINTN) Destination & BIT0) == 0);\r
236 ASSERT (((UINTN) Source & BIT0) == 0);\r
237\r
238 //\r
239 // 1. Neither Destination nor Source shall be a null pointer.\r
240 //\r
241 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
242 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
243\r
244 //\r
245 // 2. DestMax shall not be greater than RSIZE_MAX.\r
246 //\r
247 if (RSIZE_MAX != 0) {\r
248 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
249 }\r
250\r
251 //\r
252 // 3. DestMax shall not equal zero.\r
253 //\r
254 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
255\r
256 //\r
257 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).\r
258 //\r
259 SourceLen = StrnLenS (Source, DestMax);\r
260 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
261\r
262 //\r
263 // 5. Copying shall not take place between objects that overlap.\r
264 //\r
265 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
266\r
267 //\r
268 // The StrCpyS function copies the string pointed to by Source (including the terminating\r
269 // null character) into the array pointed to by Destination.\r
270 //\r
271 while (*Source != 0) {\r
272 *(Destination++) = *(Source++);\r
273 }\r
274 *Destination = 0;\r
275\r
276 return RETURN_SUCCESS;\r
277}\r
278\r
279/**\r
280 Copies not more than Length successive char from the string pointed to by\r
281 Source to the array pointed to by Destination. If no null char is copied from\r
282 Source, then Destination[Length] is always set to null.\r
283\r
328f84b1
JY
284 This function is similar as strncpy_s defined in C11.\r
285\r
c058d59f
JY
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 288 If an error would be returned, then the function will also ASSERT().\r
c058d59f 289\r
328f84b1
JY
290 If an error is returned, then the Destination is unmodified.\r
291\r
c058d59f
JY
292 @param Destination A pointer to a Null-terminated Unicode string.\r
293 @param DestMax The maximum number of Destination Unicode\r
294 char, including terminating null char.\r
295 @param Source A pointer to a Null-terminated Unicode string.\r
296 @param Length The maximum number of Unicode characters to copy.\r
297\r
298 @retval RETURN_SUCCESS String is copied.\r
299 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than \r
300 MIN(StrLen(Source), Length).\r
301 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
302 If Source is NULL.\r
303 If PcdMaximumUnicodeStringLength is not zero,\r
304 and DestMax is greater than \r
305 PcdMaximumUnicodeStringLength.\r
306 If DestMax is 0.\r
307 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
308**/\r
309RETURN_STATUS\r
310EFIAPI\r
311StrnCpyS (\r
312 OUT CHAR16 *Destination,\r
313 IN UINTN DestMax,\r
314 IN CONST CHAR16 *Source,\r
315 IN UINTN Length\r
316 )\r
317{\r
318 UINTN SourceLen;\r
319\r
320 ASSERT (((UINTN) Destination & BIT0) == 0);\r
321 ASSERT (((UINTN) Source & BIT0) == 0);\r
322\r
323 //\r
324 // 1. Neither Destination nor Source shall be a null pointer.\r
325 //\r
326 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
327 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
328\r
329 //\r
330 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX\r
331 //\r
332 if (RSIZE_MAX != 0) {\r
333 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
334 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
335 }\r
336\r
337 //\r
338 // 3. DestMax shall not equal zero.\r
339 //\r
340 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
341\r
342 //\r
343 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).\r
344 //\r
345 SourceLen = StrnLenS (Source, DestMax);\r
346 if (Length >= DestMax) {\r
347 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
348 }\r
349\r
350 //\r
351 // 5. Copying shall not take place between objects that overlap.\r
352 //\r
353 if (SourceLen > Length) {\r
354 SourceLen = Length;\r
355 }\r
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
357\r
358 //\r
359 // The StrnCpyS function copies not more than Length successive characters (characters that\r
360 // follow a null character are not copied) from the array pointed to by Source to the array\r
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
362 // character.\r
363 //\r
364 while ((*Source != 0) && (SourceLen > 0)) {\r
365 *(Destination++) = *(Source++);\r
366 SourceLen--;\r
367 }\r
368 *Destination = 0;\r
369\r
370 return RETURN_SUCCESS;\r
371}\r
372\r
373/**\r
374 Appends a copy of the string pointed to by Source (including the terminating\r
375 null char) to the end of the string pointed to by Destination.\r
376\r
328f84b1
JY
377 This function is similar as strcat_s defined in C11.\r
378\r
c058d59f
JY
379 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
380 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 381 If an error would be returned, then the function will also ASSERT().\r
c058d59f 382\r
328f84b1
JY
383 If an error is returned, then the Destination is unmodified.\r
384\r
c058d59f
JY
385 @param Destination A pointer to a Null-terminated Unicode string.\r
386 @param DestMax The maximum number of Destination Unicode\r
387 char, including terminating null char.\r
388 @param Source A pointer to a Null-terminated Unicode string.\r
389\r
390 @retval RETURN_SUCCESS String is appended.\r
391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than \r
392 StrLen(Destination).\r
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
394 greater than StrLen(Source).\r
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
396 If Source is NULL.\r
397 If PcdMaximumUnicodeStringLength is not zero,\r
398 and DestMax is greater than \r
399 PcdMaximumUnicodeStringLength.\r
400 If DestMax is 0.\r
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
402**/\r
403RETURN_STATUS\r
404EFIAPI\r
405StrCatS (\r
406 IN OUT CHAR16 *Destination,\r
407 IN UINTN DestMax,\r
408 IN CONST CHAR16 *Source\r
409 )\r
410{\r
411 UINTN DestLen;\r
412 UINTN CopyLen;\r
413 UINTN SourceLen;\r
414 \r
415 ASSERT (((UINTN) Destination & BIT0) == 0);\r
416 ASSERT (((UINTN) Source & BIT0) == 0);\r
417\r
418 //\r
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.\r
420 //\r
421 DestLen = StrnLenS (Destination, DestMax);\r
422 CopyLen = DestMax - DestLen;\r
423\r
424 //\r
425 // 1. Neither Destination nor Source shall be a null pointer.\r
426 //\r
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
428 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
429\r
430 //\r
431 // 2. DestMax shall not be greater than RSIZE_MAX.\r
432 //\r
433 if (RSIZE_MAX != 0) {\r
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
435 }\r
436\r
437 //\r
438 // 3. DestMax shall not equal zero.\r
439 //\r
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
441\r
442 //\r
443 // 4. CopyLen shall not equal zero.\r
444 //\r
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
446\r
447 //\r
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
449 //\r
450 SourceLen = StrnLenS (Source, CopyLen);\r
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
452\r
453 //\r
454 // 6. Copying shall not take place between objects that overlap.\r
455 //\r
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
457\r
458 //\r
459 // The StrCatS function appends a copy of the string pointed to by Source (including the\r
460 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
461 // from Source overwrites the null character at the end of Destination.\r
462 //\r
463 Destination = Destination + DestLen;\r
464 while (*Source != 0) {\r
465 *(Destination++) = *(Source++);\r
466 }\r
467 *Destination = 0;\r
468\r
469 return RETURN_SUCCESS;\r
470}\r
471\r
472/**\r
473 Appends not more than Length successive char from the string pointed to by\r
474 Source to the end of the string pointed to by Destination. If no null char is\r
475 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
476 set to null.\r
477\r
328f84b1
JY
478 This function is similar as strncat_s defined in C11.\r
479\r
c058d59f 480 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb
JY
481 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
482 If an error would be returned, then the function will also ASSERT().\r
c058d59f 483\r
328f84b1
JY
484 If an error is returned, then the Destination is unmodified.\r
485\r
c058d59f
JY
486 @param Destination A pointer to a Null-terminated Unicode string.\r
487 @param DestMax The maximum number of Destination Unicode\r
488 char, including terminating null char.\r
489 @param Source A pointer to a Null-terminated Unicode string.\r
490 @param Length The maximum number of Unicode characters to copy.\r
491\r
492 @retval RETURN_SUCCESS String is appended.\r
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
494 StrLen(Destination).\r
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
496 greater than MIN(StrLen(Source), Length).\r
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
498 If Source is NULL.\r
499 If PcdMaximumUnicodeStringLength is not zero,\r
500 and DestMax is greater than \r
501 PcdMaximumUnicodeStringLength.\r
502 If DestMax is 0.\r
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
504**/\r
505RETURN_STATUS\r
506EFIAPI\r
507StrnCatS (\r
508 IN OUT CHAR16 *Destination,\r
509 IN UINTN DestMax,\r
510 IN CONST CHAR16 *Source,\r
511 IN UINTN Length\r
512 )\r
513{\r
514 UINTN DestLen;\r
515 UINTN CopyLen;\r
516 UINTN SourceLen;\r
517 \r
518 ASSERT (((UINTN) Destination & BIT0) == 0);\r
519 ASSERT (((UINTN) Source & BIT0) == 0);\r
520\r
521 //\r
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.\r
523 //\r
524 DestLen = StrnLenS (Destination, DestMax);\r
525 CopyLen = DestMax - DestLen;\r
526\r
527 //\r
528 // 1. Neither Destination nor Source shall be a null pointer.\r
529 //\r
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
531 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
532\r
533 //\r
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.\r
535 //\r
536 if (RSIZE_MAX != 0) {\r
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
538 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
539 }\r
540\r
541 //\r
542 // 3. DestMax shall not equal zero.\r
543 //\r
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
545\r
546 //\r
547 // 4. CopyLen shall not equal zero.\r
548 //\r
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
550\r
551 //\r
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
553 //\r
554 SourceLen = StrnLenS (Source, CopyLen);\r
555 if (Length >= CopyLen) {\r
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
557 }\r
558\r
559 //\r
560 // 6. Copying shall not take place between objects that overlap.\r
561 //\r
562 if (SourceLen > Length) {\r
563 SourceLen = Length;\r
564 }\r
565 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
566\r
567 //\r
568 // The StrnCatS function appends not more than Length successive characters (characters\r
569 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
570 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
571 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
572 // a null character.\r
573 //\r
574 Destination = Destination + DestLen;\r
575 while ((*Source != 0) && (SourceLen > 0)) {\r
576 *(Destination++) = *(Source++);\r
577 SourceLen--;\r
578 }\r
579 *Destination = 0;\r
580\r
581 return RETURN_SUCCESS;\r
582}\r
583\r
d8af3301
HW
584/**\r
585 Convert a Null-terminated Unicode decimal string to a value of type UINTN.\r
586\r
587 This function outputs a value of type UINTN by interpreting the contents of\r
588 the Unicode string specified by String as a decimal number. The format of the\r
589 input Unicode string String is:\r
590\r
591 [spaces] [decimal digits].\r
592\r
593 The valid decimal digit character is in the range [0-9]. The function will\r
594 ignore the pad space, which includes spaces or tab characters, before\r
595 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
596 be ignored. Then, the function stops at the first character that is a not a\r
597 valid decimal character or a Null-terminator, whichever one comes first.\r
598\r
599 If String is NULL, then ASSERT().\r
600 If Data is NULL, then ASSERT().\r
601 If String is not aligned in a 16-bit boundary, then ASSERT().\r
602 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
603 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
604 Null-terminator, then ASSERT().\r
605\r
606 If String has no valid decimal digits in the above format, then 0 is stored\r
607 at the location pointed to by Data.\r
608 If the number represented by String exceeds the range defined by UINTN, then\r
609 MAX_UINTN is stored at the location pointed to by Data.\r
610\r
611 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
612 is stored at the location pointed to by EndPointer. If String has no valid\r
613 decimal digits right after the optional pad spaces, the value of String is\r
614 stored at the location pointed to by EndPointer.\r
615\r
616 @param String Pointer to a Null-terminated Unicode string.\r
617 @param EndPointer Pointer to character that stops scan.\r
618 @param Data Pointer to the converted value.\r
619\r
620 @retval RETURN_SUCCESS Value is translated from String.\r
621 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
622 If Data is NULL.\r
623 If PcdMaximumUnicodeStringLength is not\r
624 zero, and String contains more than\r
625 PcdMaximumUnicodeStringLength Unicode\r
626 characters, not including the\r
627 Null-terminator.\r
628 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
629 the range defined by UINTN.\r
630\r
631**/\r
632RETURN_STATUS\r
633EFIAPI\r
634StrDecimalToUintnS (\r
635 IN CONST CHAR16 *String,\r
636 OUT CHAR16 **EndPointer, OPTIONAL\r
637 OUT UINTN *Data\r
638 )\r
639{\r
640 ASSERT (((UINTN) String & BIT0) == 0);\r
641\r
642 //\r
643 // 1. Neither String nor Data shall be a null pointer.\r
644 //\r
645 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
646 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
647\r
648 //\r
649 // 2. The length of String shall not be greater than RSIZE_MAX.\r
650 //\r
651 if (RSIZE_MAX != 0) {\r
652 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
653 }\r
654\r
655 if (EndPointer != NULL) {\r
656 *EndPointer = (CHAR16 *) String;\r
657 }\r
658\r
659 //\r
660 // Ignore the pad spaces (space or tab)\r
661 //\r
662 while ((*String == L' ') || (*String == L'\t')) {\r
663 String++;\r
664 }\r
665\r
666 //\r
667 // Ignore leading Zeros after the spaces\r
668 //\r
669 while (*String == L'0') {\r
670 String++;\r
671 }\r
672\r
673 *Data = 0;\r
674\r
675 while (InternalIsDecimalDigitCharacter (*String)) {\r
676 //\r
677 // If the number represented by String overflows according to the range\r
678 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
679 // RETURN_UNSUPPORTED is returned.\r
680 //\r
681 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {\r
682 *Data = MAX_UINTN;\r
683 if (EndPointer != NULL) {\r
684 *EndPointer = (CHAR16 *) String;\r
685 }\r
686 return RETURN_UNSUPPORTED;\r
687 }\r
688\r
689 *Data = *Data * 10 + (*String - L'0');\r
690 String++;\r
691 }\r
692\r
693 if (EndPointer != NULL) {\r
694 *EndPointer = (CHAR16 *) String;\r
695 }\r
696 return RETURN_SUCCESS;\r
697}\r
698\r
699/**\r
700 Convert a Null-terminated Unicode decimal string to a value of type UINT64.\r
701\r
702 This function outputs a value of type UINT64 by interpreting the contents of\r
703 the Unicode string specified by String as a decimal number. The format of the\r
704 input Unicode string String is:\r
705\r
706 [spaces] [decimal digits].\r
707\r
708 The valid decimal digit character is in the range [0-9]. The function will\r
709 ignore the pad space, which includes spaces or tab characters, before\r
710 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
711 be ignored. Then, the function stops at the first character that is a not a\r
712 valid decimal character or a Null-terminator, whichever one comes first.\r
713\r
714 If String is NULL, then ASSERT().\r
715 If Data is NULL, then ASSERT().\r
716 If String is not aligned in a 16-bit boundary, then ASSERT().\r
717 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
718 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
719 Null-terminator, then ASSERT().\r
720\r
721 If String has no valid decimal digits in the above format, then 0 is stored\r
722 at the location pointed to by Data.\r
723 If the number represented by String exceeds the range defined by UINT64, then\r
724 MAX_UINT64 is stored at the location pointed to by Data.\r
725\r
726 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
727 is stored at the location pointed to by EndPointer. If String has no valid\r
728 decimal digits right after the optional pad spaces, the value of String is\r
729 stored at the location pointed to by EndPointer.\r
730\r
731 @param String Pointer to a Null-terminated Unicode string.\r
732 @param EndPointer Pointer to character that stops scan.\r
733 @param Data Pointer to the converted value.\r
734\r
735 @retval RETURN_SUCCESS Value is translated from String.\r
736 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
737 If Data is NULL.\r
738 If PcdMaximumUnicodeStringLength is not\r
739 zero, and String contains more than\r
740 PcdMaximumUnicodeStringLength Unicode\r
741 characters, not including the\r
742 Null-terminator.\r
743 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
744 the range defined by UINT64.\r
745\r
746**/\r
747RETURN_STATUS\r
748EFIAPI\r
749StrDecimalToUint64S (\r
750 IN CONST CHAR16 *String,\r
751 OUT CHAR16 **EndPointer, OPTIONAL\r
752 OUT UINT64 *Data\r
753 )\r
754{\r
755 ASSERT (((UINTN) String & BIT0) == 0);\r
756\r
757 //\r
758 // 1. Neither String nor Data shall be a null pointer.\r
759 //\r
760 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
761 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
762\r
763 //\r
764 // 2. The length of String shall not be greater than RSIZE_MAX.\r
765 //\r
766 if (RSIZE_MAX != 0) {\r
767 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
768 }\r
769\r
770 if (EndPointer != NULL) {\r
771 *EndPointer = (CHAR16 *) String;\r
772 }\r
773\r
774 //\r
775 // Ignore the pad spaces (space or tab)\r
776 //\r
777 while ((*String == L' ') || (*String == L'\t')) {\r
778 String++;\r
779 }\r
780\r
781 //\r
782 // Ignore leading Zeros after the spaces\r
783 //\r
784 while (*String == L'0') {\r
785 String++;\r
786 }\r
787\r
788 *Data = 0;\r
789\r
790 while (InternalIsDecimalDigitCharacter (*String)) {\r
791 //\r
792 // If the number represented by String overflows according to the range\r
793 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
794 // RETURN_UNSUPPORTED is returned.\r
795 //\r
796 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {\r
797 *Data = MAX_UINT64;\r
798 if (EndPointer != NULL) {\r
799 *EndPointer = (CHAR16 *) String;\r
800 }\r
801 return RETURN_UNSUPPORTED;\r
802 }\r
803\r
804 *Data = MultU64x32 (*Data, 10) + (*String - L'0');\r
805 String++;\r
806 }\r
807\r
808 if (EndPointer != NULL) {\r
809 *EndPointer = (CHAR16 *) String;\r
810 }\r
811 return RETURN_SUCCESS;\r
812}\r
813\r
814/**\r
815 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
816 UINTN.\r
817\r
818 This function outputs a value of type UINTN by interpreting the contents of\r
819 the Unicode string specified by String as a hexadecimal number. The format of\r
820 the input Unicode string String is:\r
821\r
822 [spaces][zeros][x][hexadecimal digits].\r
823\r
824 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
825 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
826 If "x" appears in the input string, it must be prefixed with at least one 0.\r
827 The function will ignore the pad space, which includes spaces or tab\r
828 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
829 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
830 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
831 the first character that is a not a valid hexadecimal character or NULL,\r
832 whichever one comes first.\r
833\r
834 If String is NULL, then ASSERT().\r
835 If Data is NULL, then ASSERT().\r
836 If String is not aligned in a 16-bit boundary, then ASSERT().\r
837 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
838 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
839 Null-terminator, then ASSERT().\r
840\r
841 If String has no valid hexadecimal digits in the above format, then 0 is\r
842 stored at the location pointed to by Data.\r
843 If the number represented by String exceeds the range defined by UINTN, then\r
844 MAX_UINTN is stored at the location pointed to by Data.\r
845\r
846 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
847 is stored at the location pointed to by EndPointer. If String has no valid\r
848 hexadecimal digits right after the optional pad spaces, the value of String\r
849 is stored at the location pointed to by EndPointer.\r
850\r
851 @param String Pointer to a Null-terminated Unicode string.\r
852 @param EndPointer Pointer to character that stops scan.\r
853 @param Data Pointer to the converted value.\r
854\r
855 @retval RETURN_SUCCESS Value is translated from String.\r
856 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
857 If Data is NULL.\r
858 If PcdMaximumUnicodeStringLength is not\r
859 zero, and String contains more than\r
860 PcdMaximumUnicodeStringLength Unicode\r
861 characters, not including the\r
862 Null-terminator.\r
863 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
864 the range defined by UINTN.\r
865\r
866**/\r
867RETURN_STATUS\r
868EFIAPI\r
869StrHexToUintnS (\r
870 IN CONST CHAR16 *String,\r
871 OUT CHAR16 **EndPointer, OPTIONAL\r
872 OUT UINTN *Data\r
873 )\r
874{\r
875 ASSERT (((UINTN) String & BIT0) == 0);\r
876\r
877 //\r
878 // 1. Neither String nor Data shall be a null pointer.\r
879 //\r
880 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
881 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
882\r
883 //\r
884 // 2. The length of String shall not be greater than RSIZE_MAX.\r
885 //\r
886 if (RSIZE_MAX != 0) {\r
887 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
888 }\r
889\r
890 if (EndPointer != NULL) {\r
891 *EndPointer = (CHAR16 *) String;\r
892 }\r
893\r
894 //\r
895 // Ignore the pad spaces (space or tab)\r
896 //\r
897 while ((*String == L' ') || (*String == L'\t')) {\r
898 String++;\r
899 }\r
900\r
901 //\r
902 // Ignore leading Zeros after the spaces\r
903 //\r
904 while (*String == L'0') {\r
905 String++;\r
906 }\r
907\r
908 if (InternalCharToUpper (*String) == L'X') {\r
909 if (*(String - 1) != L'0') {\r
910 *Data = 0;\r
911 return RETURN_SUCCESS;\r
912 }\r
913 //\r
914 // Skip the 'X'\r
915 //\r
916 String++;\r
917 }\r
918\r
919 *Data = 0;\r
920\r
921 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
922 //\r
923 // If the number represented by String overflows according to the range\r
924 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
925 // RETURN_UNSUPPORTED is returned.\r
926 //\r
927 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {\r
928 *Data = MAX_UINTN;\r
929 if (EndPointer != NULL) {\r
930 *EndPointer = (CHAR16 *) String;\r
931 }\r
932 return RETURN_UNSUPPORTED;\r
933 }\r
934\r
935 *Data = (*Data << 4) + InternalHexCharToUintn (*String);\r
936 String++;\r
937 }\r
938\r
939 if (EndPointer != NULL) {\r
940 *EndPointer = (CHAR16 *) String;\r
941 }\r
942 return RETURN_SUCCESS;\r
943}\r
944\r
945/**\r
946 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
947 UINT64.\r
948\r
949 This function outputs a value of type UINT64 by interpreting the contents of\r
950 the Unicode string specified by String as a hexadecimal number. The format of\r
951 the input Unicode string String is:\r
952\r
953 [spaces][zeros][x][hexadecimal digits].\r
954\r
955 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
956 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
957 If "x" appears in the input string, it must be prefixed with at least one 0.\r
958 The function will ignore the pad space, which includes spaces or tab\r
959 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
960 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
961 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
962 the first character that is a not a valid hexadecimal character or NULL,\r
963 whichever one comes first.\r
964\r
965 If String is NULL, then ASSERT().\r
966 If Data is NULL, then ASSERT().\r
967 If String is not aligned in a 16-bit boundary, then ASSERT().\r
968 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
969 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
970 Null-terminator, then ASSERT().\r
971\r
972 If String has no valid hexadecimal digits in the above format, then 0 is\r
973 stored at the location pointed to by Data.\r
974 If the number represented by String exceeds the range defined by UINT64, then\r
975 MAX_UINT64 is stored at the location pointed to by Data.\r
976\r
977 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
978 is stored at the location pointed to by EndPointer. If String has no valid\r
979 hexadecimal digits right after the optional pad spaces, the value of String\r
980 is stored at the location pointed to by EndPointer.\r
981\r
982 @param String Pointer to a Null-terminated Unicode string.\r
983 @param EndPointer Pointer to character that stops scan.\r
984 @param Data Pointer to the converted value.\r
985\r
986 @retval RETURN_SUCCESS Value is translated from String.\r
987 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
988 If Data is NULL.\r
989 If PcdMaximumUnicodeStringLength is not\r
990 zero, and String contains more than\r
991 PcdMaximumUnicodeStringLength Unicode\r
992 characters, not including the\r
993 Null-terminator.\r
994 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
995 the range defined by UINT64.\r
996\r
997**/\r
998RETURN_STATUS\r
999EFIAPI\r
1000StrHexToUint64S (\r
1001 IN CONST CHAR16 *String,\r
1002 OUT CHAR16 **EndPointer, OPTIONAL\r
1003 OUT UINT64 *Data\r
1004 )\r
1005{\r
1006 ASSERT (((UINTN) String & BIT0) == 0);\r
1007\r
1008 //\r
1009 // 1. Neither String nor Data shall be a null pointer.\r
1010 //\r
1011 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1012 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1013\r
1014 //\r
1015 // 2. The length of String shall not be greater than RSIZE_MAX.\r
1016 //\r
1017 if (RSIZE_MAX != 0) {\r
1018 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1019 }\r
1020\r
1021 if (EndPointer != NULL) {\r
1022 *EndPointer = (CHAR16 *) String;\r
1023 }\r
1024\r
1025 //\r
1026 // Ignore the pad spaces (space or tab)\r
1027 //\r
1028 while ((*String == L' ') || (*String == L'\t')) {\r
1029 String++;\r
1030 }\r
1031\r
1032 //\r
1033 // Ignore leading Zeros after the spaces\r
1034 //\r
1035 while (*String == L'0') {\r
1036 String++;\r
1037 }\r
1038\r
1039 if (InternalCharToUpper (*String) == L'X') {\r
1040 if (*(String - 1) != L'0') {\r
1041 *Data = 0;\r
1042 return RETURN_SUCCESS;\r
1043 }\r
1044 //\r
1045 // Skip the 'X'\r
1046 //\r
1047 String++;\r
1048 }\r
1049\r
1050 *Data = 0;\r
1051\r
1052 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
1053 //\r
1054 // If the number represented by String overflows according to the range\r
1055 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1056 // RETURN_UNSUPPORTED is returned.\r
1057 //\r
1058 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {\r
1059 *Data = MAX_UINT64;\r
1060 if (EndPointer != NULL) {\r
1061 *EndPointer = (CHAR16 *) String;\r
1062 }\r
1063 return RETURN_UNSUPPORTED;\r
1064 }\r
1065\r
1066 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);\r
1067 String++;\r
1068 }\r
1069\r
1070 if (EndPointer != NULL) {\r
1071 *EndPointer = (CHAR16 *) String;\r
1072 }\r
1073 return RETURN_SUCCESS;\r
1074}\r
1075\r
c058d59f
JY
1076/**\r
1077 Returns the length of a Null-terminated Ascii string.\r
1078\r
328f84b1
JY
1079 This function is similar as strlen_s defined in C11.\r
1080\r
c058d59f
JY
1081 @param String A pointer to a Null-terminated Ascii string.\r
1082 @param MaxSize The maximum number of Destination Ascii\r
1083 char, including terminating null char.\r
1084\r
1085 @retval 0 If String is NULL.\r
1086 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
1087 @return The number of characters that percede the terminating null character.\r
1088\r
1089**/\r
1090UINTN\r
1091EFIAPI\r
1092AsciiStrnLenS (\r
1093 IN CONST CHAR8 *String,\r
1094 IN UINTN MaxSize\r
1095 )\r
1096{\r
1097 UINTN Length;\r
1098\r
1099 //\r
1100 // If String is a null pointer, then the AsciiStrnLenS function returns zero.\r
1101 //\r
1102 if (String == NULL) {\r
1103 return 0;\r
1104 }\r
1105\r
1106 //\r
1107 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the\r
1108 // terminating null character. If there is no null character in the first MaxSize characters of\r
1109 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
1110 // be accessed by AsciiStrnLenS.\r
1111 //\r
c07c517c
HW
1112 Length = 0;\r
1113 while (String[Length] != 0) {\r
1114 if (Length >= MaxSize - 1) {\r
1115 return MaxSize;\r
1116 }\r
1117 Length++;\r
c058d59f
JY
1118 }\r
1119 return Length;\r
1120}\r
1121\r
b590e43a
HW
1122/**\r
1123 Returns the size of a Null-terminated Ascii string in bytes, including the\r
1124 Null terminator.\r
1125\r
1126 This function returns the size of the Null-terminated Ascii string specified\r
1127 by String in bytes, including the Null terminator.\r
1128\r
1129 @param String A pointer to a Null-terminated Ascii string.\r
1130 @param MaxSize The maximum number of Destination Ascii\r
1131 char, including the Null terminator.\r
1132\r
1133 @retval 0 If String is NULL.\r
1134 @retval (sizeof (CHAR8) * (MaxSize + 1))\r
1135 If there is no Null terminator in the first MaxSize characters of\r
1136 String.\r
1137 @return The size of the Null-terminated Ascii string in bytes, including the\r
1138 Null terminator.\r
1139\r
1140**/\r
1141UINTN\r
1142EFIAPI\r
1143AsciiStrnSizeS (\r
1144 IN CONST CHAR8 *String,\r
1145 IN UINTN MaxSize\r
1146 )\r
1147{\r
1148 //\r
1149 // If String is a null pointer, then the AsciiStrnSizeS function returns\r
1150 // zero.\r
1151 //\r
1152 if (String == NULL) {\r
1153 return 0;\r
1154 }\r
1155\r
1156 //\r
1157 // Otherwise, the AsciiStrnSizeS function returns the size of the\r
1158 // Null-terminated Ascii string in bytes, including the Null terminator. If\r
1159 // there is no Null terminator in the first MaxSize characters of String,\r
1160 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
1161 // consistent map with the AsciiStrnLenS function.\r
1162 //\r
1163 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
1164}\r
1165\r
c058d59f
JY
1166/**\r
1167 Copies the string pointed to by Source (including the terminating null char)\r
1168 to the array pointed to by Destination.\r
1169\r
328f84b1
JY
1170 This function is similar as strcpy_s defined in C11.\r
1171\r
0e93edbb
JY
1172 If an error would be returned, then the function will also ASSERT().\r
1173\r
328f84b1
JY
1174 If an error is returned, then the Destination is unmodified.\r
1175\r
c058d59f
JY
1176 @param Destination A pointer to a Null-terminated Ascii string.\r
1177 @param DestMax The maximum number of Destination Ascii\r
1178 char, including terminating null char.\r
1179 @param Source A pointer to a Null-terminated Ascii string.\r
1180\r
1181 @retval RETURN_SUCCESS String is copied.\r
1182 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
1183 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1184 If Source is NULL.\r
1185 If PcdMaximumAsciiStringLength is not zero,\r
1186 and DestMax is greater than \r
1187 PcdMaximumAsciiStringLength.\r
1188 If DestMax is 0.\r
1189 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1190**/\r
1191RETURN_STATUS\r
1192EFIAPI\r
1193AsciiStrCpyS (\r
1194 OUT CHAR8 *Destination,\r
1195 IN UINTN DestMax,\r
1196 IN CONST CHAR8 *Source\r
1197 )\r
1198{\r
1199 UINTN SourceLen;\r
1200 \r
1201 //\r
1202 // 1. Neither Destination nor Source shall be a null pointer.\r
1203 //\r
1204 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1205 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1206\r
1207 //\r
1208 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1209 //\r
1210 if (ASCII_RSIZE_MAX != 0) {\r
1211 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1212 }\r
1213\r
1214 //\r
1215 // 3. DestMax shall not equal zero.\r
1216 //\r
1217 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1218\r
1219 //\r
1220 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1221 //\r
1222 SourceLen = AsciiStrnLenS (Source, DestMax);\r
1223 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1224\r
1225 //\r
1226 // 5. Copying shall not take place between objects that overlap.\r
1227 //\r
1228 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1229\r
1230 //\r
1231 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating\r
1232 // null character) into the array pointed to by Destination.\r
1233 //\r
1234 while (*Source != 0) {\r
1235 *(Destination++) = *(Source++);\r
1236 }\r
1237 *Destination = 0;\r
1238\r
1239 return RETURN_SUCCESS;\r
1240}\r
1241\r
1242/**\r
1243 Copies not more than Length successive char from the string pointed to by\r
1244 Source to the array pointed to by Destination. If no null char is copied from\r
1245 Source, then Destination[Length] is always set to null.\r
1246\r
328f84b1
JY
1247 This function is similar as strncpy_s defined in C11.\r
1248\r
0e93edbb
JY
1249 If an error would be returned, then the function will also ASSERT().\r
1250\r
328f84b1
JY
1251 If an error is returned, then the Destination is unmodified.\r
1252\r
c058d59f
JY
1253 @param Destination A pointer to a Null-terminated Ascii string.\r
1254 @param DestMax The maximum number of Destination Ascii\r
1255 char, including terminating null char.\r
1256 @param Source A pointer to a Null-terminated Ascii string.\r
1257 @param Length The maximum number of Ascii characters to copy.\r
1258\r
1259 @retval RETURN_SUCCESS String is copied.\r
1260 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than \r
1261 MIN(StrLen(Source), Length).\r
1262 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1263 If Source is NULL.\r
1264 If PcdMaximumAsciiStringLength is not zero,\r
1265 and DestMax is greater than \r
1266 PcdMaximumAsciiStringLength.\r
1267 If DestMax is 0.\r
1268 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1269**/\r
1270RETURN_STATUS\r
1271EFIAPI\r
1272AsciiStrnCpyS (\r
1273 OUT CHAR8 *Destination,\r
1274 IN UINTN DestMax,\r
1275 IN CONST CHAR8 *Source,\r
1276 IN UINTN Length\r
1277 )\r
1278{\r
1279 UINTN SourceLen;\r
1280\r
1281 //\r
1282 // 1. Neither Destination nor Source shall be a null pointer.\r
1283 //\r
1284 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1285 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1286\r
1287 //\r
1288 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
1289 //\r
1290 if (ASCII_RSIZE_MAX != 0) {\r
1291 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1292 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1293 }\r
1294\r
1295 //\r
1296 // 3. DestMax shall not equal zero.\r
1297 //\r
1298 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1299\r
1300 //\r
1301 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1302 //\r
1303 SourceLen = AsciiStrnLenS (Source, DestMax);\r
1304 if (Length >= DestMax) {\r
1305 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1306 }\r
1307\r
1308 //\r
1309 // 5. Copying shall not take place between objects that overlap.\r
1310 //\r
1311 if (SourceLen > Length) {\r
1312 SourceLen = Length;\r
1313 }\r
1314 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1315\r
1316 //\r
1317 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that\r
1318 // follow a null character are not copied) from the array pointed to by Source to the array\r
1319 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
1320 // character.\r
1321 //\r
1322 while ((*Source != 0) && (SourceLen > 0)) {\r
1323 *(Destination++) = *(Source++);\r
1324 SourceLen--;\r
1325 }\r
1326 *Destination = 0;\r
1327\r
1328 return RETURN_SUCCESS;\r
1329}\r
1330\r
1331/**\r
1332 Appends a copy of the string pointed to by Source (including the terminating\r
1333 null char) to the end of the string pointed to by Destination.\r
1334\r
328f84b1
JY
1335 This function is similar as strcat_s defined in C11.\r
1336\r
0e93edbb
JY
1337 If an error would be returned, then the function will also ASSERT().\r
1338\r
328f84b1
JY
1339 If an error is returned, then the Destination is unmodified.\r
1340\r
c058d59f
JY
1341 @param Destination A pointer to a Null-terminated Ascii string.\r
1342 @param DestMax The maximum number of Destination Ascii\r
1343 char, including terminating null char.\r
1344 @param Source A pointer to a Null-terminated Ascii string.\r
1345\r
1346 @retval RETURN_SUCCESS String is appended.\r
1347 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than \r
1348 StrLen(Destination).\r
1349 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
1350 greater than StrLen(Source).\r
1351 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1352 If Source is NULL.\r
1353 If PcdMaximumAsciiStringLength is not zero,\r
1354 and DestMax is greater than \r
1355 PcdMaximumAsciiStringLength.\r
1356 If DestMax is 0.\r
1357 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1358**/\r
1359RETURN_STATUS\r
1360EFIAPI\r
1361AsciiStrCatS (\r
1362 IN OUT CHAR8 *Destination,\r
1363 IN UINTN DestMax,\r
1364 IN CONST CHAR8 *Source\r
1365 )\r
1366{\r
1367 UINTN DestLen;\r
1368 UINTN CopyLen;\r
1369 UINTN SourceLen;\r
1370 \r
1371 //\r
1372 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.\r
1373 //\r
1374 DestLen = AsciiStrnLenS (Destination, DestMax);\r
1375 CopyLen = DestMax - DestLen;\r
1376\r
1377 //\r
1378 // 1. Neither Destination nor Source shall be a null pointer.\r
1379 //\r
1380 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1381 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1382\r
1383 //\r
1384 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1385 //\r
1386 if (ASCII_RSIZE_MAX != 0) {\r
1387 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1388 }\r
1389\r
1390 //\r
1391 // 3. DestMax shall not equal zero.\r
1392 //\r
1393 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1394\r
1395 //\r
1396 // 4. CopyLen shall not equal zero.\r
1397 //\r
1398 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
1399\r
1400 //\r
1401 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
1402 //\r
1403 SourceLen = AsciiStrnLenS (Source, CopyLen);\r
1404 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1405\r
1406 //\r
1407 // 6. Copying shall not take place between objects that overlap.\r
1408 //\r
1409 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1410\r
1411 //\r
1412 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the\r
1413 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
1414 // from Source overwrites the null character at the end of Destination.\r
1415 //\r
1416 Destination = Destination + DestLen;\r
1417 while (*Source != 0) {\r
1418 *(Destination++) = *(Source++);\r
1419 }\r
1420 *Destination = 0;\r
1421\r
1422 return RETURN_SUCCESS;\r
1423}\r
1424\r
1425/**\r
1426 Appends not more than Length successive char from the string pointed to by\r
1427 Source to the end of the string pointed to by Destination. If no null char is\r
1428 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
1429 set to null.\r
1430\r
328f84b1
JY
1431 This function is similar as strncat_s defined in C11.\r
1432\r
0e93edbb
JY
1433 If an error would be returned, then the function will also ASSERT().\r
1434\r
328f84b1
JY
1435 If an error is returned, then the Destination is unmodified.\r
1436\r
c058d59f
JY
1437 @param Destination A pointer to a Null-terminated Ascii string.\r
1438 @param DestMax The maximum number of Destination Ascii\r
1439 char, including terminating null char.\r
1440 @param Source A pointer to a Null-terminated Ascii string.\r
1441 @param Length The maximum number of Ascii characters to copy.\r
1442\r
1443 @retval RETURN_SUCCESS String is appended.\r
1444 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
1445 StrLen(Destination).\r
1446 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
1447 greater than MIN(StrLen(Source), Length).\r
1448 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1449 If Source is NULL.\r
1450 If PcdMaximumAsciiStringLength is not zero,\r
1451 and DestMax is greater than \r
1452 PcdMaximumAsciiStringLength.\r
1453 If DestMax is 0.\r
1454 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1455**/\r
1456RETURN_STATUS\r
1457EFIAPI\r
1458AsciiStrnCatS (\r
1459 IN OUT CHAR8 *Destination,\r
1460 IN UINTN DestMax,\r
1461 IN CONST CHAR8 *Source,\r
1462 IN UINTN Length\r
1463 )\r
1464{\r
1465 UINTN DestLen;\r
1466 UINTN CopyLen;\r
1467 UINTN SourceLen;\r
1468 \r
1469 //\r
1470 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.\r
1471 //\r
1472 DestLen = AsciiStrnLenS (Destination, DestMax);\r
1473 CopyLen = DestMax - DestLen;\r
1474\r
1475 //\r
1476 // 1. Neither Destination nor Source shall be a null pointer.\r
1477 //\r
1478 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1479 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1480\r
1481 //\r
1482 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
1483 //\r
1484 if (ASCII_RSIZE_MAX != 0) {\r
1485 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1486 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1487 }\r
1488\r
1489 //\r
1490 // 3. DestMax shall not equal zero.\r
1491 //\r
1492 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1493\r
1494 //\r
1495 // 4. CopyLen shall not equal zero.\r
1496 //\r
1497 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
1498\r
1499 //\r
1500 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
1501 //\r
1502 SourceLen = AsciiStrnLenS (Source, CopyLen);\r
1503 if (Length >= CopyLen) {\r
1504 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1505 }\r
1506\r
1507 //\r
1508 // 6. Copying shall not take place between objects that overlap.\r
1509 //\r
1510 if (SourceLen > Length) {\r
1511 SourceLen = Length;\r
1512 }\r
1513 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1514\r
1515 //\r
1516 // The AsciiStrnCatS function appends not more than Length successive characters (characters\r
1517 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
1518 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
1519 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
1520 // a null character.\r
1521 //\r
1522 Destination = Destination + DestLen;\r
1523 while ((*Source != 0) && (SourceLen > 0)) {\r
1524 *(Destination++) = *(Source++);\r
1525 SourceLen--;\r
1526 }\r
1527 *Destination = 0;\r
1528\r
d8af3301
HW
1529 return RETURN_SUCCESS;\r
1530}\r
1531\r
1532/**\r
1533 Convert a Null-terminated Ascii decimal string to a value of type UINTN.\r
1534\r
1535 This function outputs a value of type UINTN by interpreting the contents of\r
1536 the Ascii string specified by String as a decimal number. The format of the\r
1537 input Ascii string String is:\r
1538\r
1539 [spaces] [decimal digits].\r
1540\r
1541 The valid decimal digit character is in the range [0-9]. The function will\r
1542 ignore the pad space, which includes spaces or tab characters, before\r
1543 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
1544 be ignored. Then, the function stops at the first character that is a not a\r
1545 valid decimal character or a Null-terminator, whichever one comes first.\r
1546\r
1547 If String is NULL, then ASSERT().\r
1548 If Data is NULL, then ASSERT().\r
1549 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1550 PcdMaximumAsciiStringLength Ascii characters, not including the\r
1551 Null-terminator, then ASSERT().\r
1552\r
1553 If String has no valid decimal digits in the above format, then 0 is stored\r
1554 at the location pointed to by Data.\r
1555 If the number represented by String exceeds the range defined by UINTN, then\r
1556 MAX_UINTN is stored at the location pointed to by Data.\r
1557\r
1558 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
1559 is stored at the location pointed to by EndPointer. If String has no valid\r
1560 decimal digits right after the optional pad spaces, the value of String is\r
1561 stored at the location pointed to by EndPointer.\r
1562\r
1563 @param String Pointer to a Null-terminated Ascii string.\r
1564 @param EndPointer Pointer to character that stops scan.\r
1565 @param Data Pointer to the converted value.\r
1566\r
1567 @retval RETURN_SUCCESS Value is translated from String.\r
1568 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1569 If Data is NULL.\r
1570 If PcdMaximumAsciiStringLength is not zero,\r
1571 and String contains more than\r
1572 PcdMaximumAsciiStringLength Ascii\r
1573 characters, not including the\r
1574 Null-terminator.\r
1575 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
1576 the range defined by UINTN.\r
1577\r
1578**/\r
1579RETURN_STATUS\r
1580EFIAPI\r
1581AsciiStrDecimalToUintnS (\r
1582 IN CONST CHAR8 *String,\r
1583 OUT CHAR8 **EndPointer, OPTIONAL\r
1584 OUT UINTN *Data\r
1585 )\r
1586{\r
1587 //\r
1588 // 1. Neither String nor Data shall be a null pointer.\r
1589 //\r
1590 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1591 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1592\r
1593 //\r
1594 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
1595 //\r
1596 if (ASCII_RSIZE_MAX != 0) {\r
1597 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1598 }\r
1599\r
1600 if (EndPointer != NULL) {\r
1601 *EndPointer = (CHAR8 *) String;\r
1602 }\r
1603\r
1604 //\r
1605 // Ignore the pad spaces (space or tab)\r
1606 //\r
1607 while ((*String == ' ') || (*String == '\t')) {\r
1608 String++;\r
1609 }\r
1610\r
1611 //\r
1612 // Ignore leading Zeros after the spaces\r
1613 //\r
1614 while (*String == '0') {\r
1615 String++;\r
1616 }\r
1617\r
1618 *Data = 0;\r
1619\r
1620 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
1621 //\r
1622 // If the number represented by String overflows according to the range\r
1623 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
1624 // RETURN_UNSUPPORTED is returned.\r
1625 //\r
1626 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {\r
1627 *Data = MAX_UINTN;\r
1628 if (EndPointer != NULL) {\r
1629 *EndPointer = (CHAR8 *) String;\r
1630 }\r
1631 return RETURN_UNSUPPORTED;\r
1632 }\r
1633\r
1634 *Data = *Data * 10 + (*String - '0');\r
1635 String++;\r
1636 }\r
1637\r
1638 if (EndPointer != NULL) {\r
1639 *EndPointer = (CHAR8 *) String;\r
1640 }\r
1641 return RETURN_SUCCESS;\r
1642}\r
1643\r
1644/**\r
1645 Convert a Null-terminated Ascii decimal string to a value of type UINT64.\r
1646\r
1647 This function outputs a value of type UINT64 by interpreting the contents of\r
1648 the Ascii string specified by String as a decimal number. The format of the\r
1649 input Ascii string String is:\r
1650\r
1651 [spaces] [decimal digits].\r
1652\r
1653 The valid decimal digit character is in the range [0-9]. The function will\r
1654 ignore the pad space, which includes spaces or tab characters, before\r
1655 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
1656 be ignored. Then, the function stops at the first character that is a not a\r
1657 valid decimal character or a Null-terminator, whichever one comes first.\r
1658\r
1659 If String is NULL, then ASSERT().\r
1660 If Data is NULL, then ASSERT().\r
1661 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1662 PcdMaximumAsciiStringLength Ascii characters, not including the\r
1663 Null-terminator, then ASSERT().\r
1664\r
1665 If String has no valid decimal digits in the above format, then 0 is stored\r
1666 at the location pointed to by Data.\r
1667 If the number represented by String exceeds the range defined by UINT64, then\r
1668 MAX_UINT64 is stored at the location pointed to by Data.\r
1669\r
1670 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
1671 is stored at the location pointed to by EndPointer. If String has no valid\r
1672 decimal digits right after the optional pad spaces, the value of String is\r
1673 stored at the location pointed to by EndPointer.\r
1674\r
1675 @param String Pointer to a Null-terminated Ascii string.\r
1676 @param EndPointer Pointer to character that stops scan.\r
1677 @param Data Pointer to the converted value.\r
1678\r
1679 @retval RETURN_SUCCESS Value is translated from String.\r
1680 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1681 If Data is NULL.\r
1682 If PcdMaximumAsciiStringLength is not zero,\r
1683 and String contains more than\r
1684 PcdMaximumAsciiStringLength Ascii\r
1685 characters, not including the\r
1686 Null-terminator.\r
1687 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
1688 the range defined by UINT64.\r
1689\r
1690**/\r
1691RETURN_STATUS\r
1692EFIAPI\r
1693AsciiStrDecimalToUint64S (\r
1694 IN CONST CHAR8 *String,\r
1695 OUT CHAR8 **EndPointer, OPTIONAL\r
1696 OUT UINT64 *Data\r
1697 )\r
1698{\r
1699 //\r
1700 // 1. Neither String nor Data shall be a null pointer.\r
1701 //\r
1702 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1703 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1704\r
1705 //\r
1706 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
1707 //\r
1708 if (ASCII_RSIZE_MAX != 0) {\r
1709 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1710 }\r
1711\r
1712 if (EndPointer != NULL) {\r
1713 *EndPointer = (CHAR8 *) String;\r
1714 }\r
1715\r
1716 //\r
1717 // Ignore the pad spaces (space or tab)\r
1718 //\r
1719 while ((*String == ' ') || (*String == '\t')) {\r
1720 String++;\r
1721 }\r
1722\r
1723 //\r
1724 // Ignore leading Zeros after the spaces\r
1725 //\r
1726 while (*String == '0') {\r
1727 String++;\r
1728 }\r
1729\r
1730 *Data = 0;\r
1731\r
1732 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
1733 //\r
1734 // If the number represented by String overflows according to the range\r
1735 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1736 // RETURN_UNSUPPORTED is returned.\r
1737 //\r
1738 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {\r
1739 *Data = MAX_UINT64;\r
1740 if (EndPointer != NULL) {\r
1741 *EndPointer = (CHAR8 *) String;\r
1742 }\r
1743 return RETURN_UNSUPPORTED;\r
1744 }\r
1745\r
1746 *Data = MultU64x32 (*Data, 10) + (*String - '0');\r
1747 String++;\r
1748 }\r
1749\r
1750 if (EndPointer != NULL) {\r
1751 *EndPointer = (CHAR8 *) String;\r
1752 }\r
1753 return RETURN_SUCCESS;\r
1754}\r
1755\r
1756/**\r
1757 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.\r
1758\r
1759 This function outputs a value of type UINTN by interpreting the contents of\r
1760 the Ascii string specified by String as a hexadecimal number. The format of\r
1761 the input Ascii string String is:\r
1762\r
1763 [spaces][zeros][x][hexadecimal digits].\r
1764\r
1765 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1766 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
1767 "x" appears in the input string, it must be prefixed with at least one 0. The\r
1768 function will ignore the pad space, which includes spaces or tab characters,\r
1769 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
1770 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
1771 the first valid hexadecimal digit. Then, the function stops at the first\r
1772 character that is a not a valid hexadecimal character or Null-terminator,\r
1773 whichever on comes first.\r
1774\r
1775 If String is NULL, then ASSERT().\r
1776 If Data is NULL, then ASSERT().\r
1777 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1778 PcdMaximumAsciiStringLength Ascii characters, not including the\r
1779 Null-terminator, then ASSERT().\r
1780\r
1781 If String has no valid hexadecimal digits in the above format, then 0 is\r
1782 stored at the location pointed to by Data.\r
1783 If the number represented by String exceeds the range defined by UINTN, then\r
1784 MAX_UINTN is stored at the location pointed to by Data.\r
1785\r
1786 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
1787 is stored at the location pointed to by EndPointer. If String has no valid\r
1788 hexadecimal digits right after the optional pad spaces, the value of String\r
1789 is stored at the location pointed to by EndPointer.\r
1790\r
1791 @param String Pointer to a Null-terminated Ascii string.\r
1792 @param EndPointer Pointer to character that stops scan.\r
1793 @param Data Pointer to the converted value.\r
1794\r
1795 @retval RETURN_SUCCESS Value is translated from String.\r
1796 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1797 If Data is NULL.\r
1798 If PcdMaximumAsciiStringLength is not zero,\r
1799 and String contains more than\r
1800 PcdMaximumAsciiStringLength Ascii\r
1801 characters, not including the\r
1802 Null-terminator.\r
1803 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
1804 the range defined by UINTN.\r
1805\r
1806**/\r
1807RETURN_STATUS\r
1808EFIAPI\r
1809AsciiStrHexToUintnS (\r
1810 IN CONST CHAR8 *String,\r
1811 OUT CHAR8 **EndPointer, OPTIONAL\r
1812 OUT UINTN *Data\r
1813 )\r
1814{\r
1815 //\r
1816 // 1. Neither String nor Data shall be a null pointer.\r
1817 //\r
1818 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1819 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1820\r
1821 //\r
1822 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
1823 //\r
1824 if (ASCII_RSIZE_MAX != 0) {\r
1825 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1826 }\r
1827\r
1828 if (EndPointer != NULL) {\r
1829 *EndPointer = (CHAR8 *) String;\r
1830 }\r
1831\r
1832 //\r
1833 // Ignore the pad spaces (space or tab)\r
1834 //\r
1835 while ((*String == ' ') || (*String == '\t')) {\r
1836 String++;\r
1837 }\r
1838\r
1839 //\r
1840 // Ignore leading Zeros after the spaces\r
1841 //\r
1842 while (*String == '0') {\r
1843 String++;\r
1844 }\r
1845\r
1846 if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
1847 if (*(String - 1) != '0') {\r
1848 *Data = 0;\r
1849 return RETURN_SUCCESS;\r
1850 }\r
1851 //\r
1852 // Skip the 'X'\r
1853 //\r
1854 String++;\r
1855 }\r
1856\r
1857 *Data = 0;\r
1858\r
1859 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
1860 //\r
1861 // If the number represented by String overflows according to the range\r
1862 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
1863 // RETURN_UNSUPPORTED is returned.\r
1864 //\r
1865 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {\r
1866 *Data = MAX_UINTN;\r
1867 if (EndPointer != NULL) {\r
1868 *EndPointer = (CHAR8 *) String;\r
1869 }\r
1870 return RETURN_UNSUPPORTED;\r
1871 }\r
1872\r
1873 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);\r
1874 String++;\r
1875 }\r
1876\r
1877 if (EndPointer != NULL) {\r
1878 *EndPointer = (CHAR8 *) String;\r
1879 }\r
1880 return RETURN_SUCCESS;\r
1881}\r
1882\r
1883/**\r
1884 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.\r
1885\r
1886 This function outputs a value of type UINT64 by interpreting the contents of\r
1887 the Ascii string specified by String as a hexadecimal number. The format of\r
1888 the input Ascii string String is:\r
1889\r
1890 [spaces][zeros][x][hexadecimal digits].\r
1891\r
1892 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1893 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
1894 "x" appears in the input string, it must be prefixed with at least one 0. The\r
1895 function will ignore the pad space, which includes spaces or tab characters,\r
1896 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
1897 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
1898 the first valid hexadecimal digit. Then, the function stops at the first\r
1899 character that is a not a valid hexadecimal character or Null-terminator,\r
1900 whichever on comes first.\r
1901\r
1902 If String is NULL, then ASSERT().\r
1903 If Data is NULL, then ASSERT().\r
1904 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1905 PcdMaximumAsciiStringLength Ascii characters, not including the\r
1906 Null-terminator, then ASSERT().\r
1907\r
1908 If String has no valid hexadecimal digits in the above format, then 0 is\r
1909 stored at the location pointed to by Data.\r
1910 If the number represented by String exceeds the range defined by UINT64, then\r
1911 MAX_UINT64 is stored at the location pointed to by Data.\r
1912\r
1913 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
1914 is stored at the location pointed to by EndPointer. If String has no valid\r
1915 hexadecimal digits right after the optional pad spaces, the value of String\r
1916 is stored at the location pointed to by EndPointer.\r
1917\r
1918 @param String Pointer to a Null-terminated Ascii string.\r
1919 @param EndPointer Pointer to character that stops scan.\r
1920 @param Data Pointer to the converted value.\r
1921\r
1922 @retval RETURN_SUCCESS Value is translated from String.\r
1923 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1924 If Data is NULL.\r
1925 If PcdMaximumAsciiStringLength is not zero,\r
1926 and String contains more than\r
1927 PcdMaximumAsciiStringLength Ascii\r
1928 characters, not including the\r
1929 Null-terminator.\r
1930 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
1931 the range defined by UINT64.\r
1932\r
1933**/\r
1934RETURN_STATUS\r
1935EFIAPI\r
1936AsciiStrHexToUint64S (\r
1937 IN CONST CHAR8 *String,\r
1938 OUT CHAR8 **EndPointer, OPTIONAL\r
1939 OUT UINT64 *Data\r
1940 )\r
1941{\r
1942 //\r
1943 // 1. Neither String nor Data shall be a null pointer.\r
1944 //\r
1945 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1946 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1947\r
1948 //\r
1949 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
1950 //\r
1951 if (ASCII_RSIZE_MAX != 0) {\r
1952 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1953 }\r
1954\r
1955 if (EndPointer != NULL) {\r
1956 *EndPointer = (CHAR8 *) String;\r
1957 }\r
1958\r
1959 //\r
1960 // Ignore the pad spaces (space or tab)\r
1961 //\r
1962 while ((*String == ' ') || (*String == '\t')) {\r
1963 String++;\r
1964 }\r
1965\r
1966 //\r
1967 // Ignore leading Zeros after the spaces\r
1968 //\r
1969 while (*String == '0') {\r
1970 String++;\r
1971 }\r
1972\r
1973 if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
1974 if (*(String - 1) != '0') {\r
1975 *Data = 0;\r
1976 return RETURN_SUCCESS;\r
1977 }\r
1978 //\r
1979 // Skip the 'X'\r
1980 //\r
1981 String++;\r
1982 }\r
1983\r
1984 *Data = 0;\r
1985\r
1986 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
1987 //\r
1988 // If the number represented by String overflows according to the range\r
1989 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1990 // RETURN_UNSUPPORTED is returned.\r
1991 //\r
1992 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {\r
1993 *Data = MAX_UINT64;\r
1994 if (EndPointer != NULL) {\r
1995 *EndPointer = (CHAR8 *) String;\r
1996 }\r
1997 return RETURN_UNSUPPORTED;\r
1998 }\r
1999\r
2000 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);\r
2001 String++;\r
2002 }\r
2003\r
2004 if (EndPointer != NULL) {\r
2005 *EndPointer = (CHAR8 *) String;\r
2006 }\r
c058d59f
JY
2007 return RETURN_SUCCESS;\r
2008}\r
3ab41b7a
JY
2009\r
2010/**\r
2011 Convert a Null-terminated Unicode string to a Null-terminated\r
2012 ASCII string.\r
2013\r
2014 This function is similar to AsciiStrCpyS.\r
2015\r
2016 This function converts the content of the Unicode string Source\r
2017 to the ASCII string Destination by copying the lower 8 bits of\r
2018 each Unicode character. The function terminates the ASCII string\r
2019 Destination by appending a Null-terminator character at the end.\r
2020\r
2021 The caller is responsible to make sure Destination points to a buffer with size\r
2022 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.\r
2023\r
2024 If any Unicode characters in Source contain non-zero value in\r
2025 the upper 8 bits, then ASSERT().\r
2026\r
2027 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
2028 If an error would be returned, then the function will also ASSERT().\r
2029\r
2030 If an error is returned, then the Destination is unmodified.\r
2031\r
2032 @param Source The pointer to a Null-terminated Unicode string.\r
2033 @param Destination The pointer to a Null-terminated ASCII string.\r
2034 @param DestMax The maximum number of Destination Ascii\r
2035 char, including terminating null char.\r
2036\r
2037 @retval RETURN_SUCCESS String is converted.\r
2038 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2039 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2040 If Source is NULL.\r
2041 If PcdMaximumAsciiStringLength is not zero,\r
2042 and DestMax is greater than\r
2043 PcdMaximumAsciiStringLength.\r
2044 If PcdMaximumUnicodeStringLength is not zero,\r
2045 and DestMax is greater than\r
2046 PcdMaximumUnicodeStringLength.\r
2047 If DestMax is 0.\r
2048 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2049\r
2050**/\r
2051RETURN_STATUS\r
2052EFIAPI\r
2053UnicodeStrToAsciiStrS (\r
2054 IN CONST CHAR16 *Source,\r
2055 OUT CHAR8 *Destination,\r
2056 IN UINTN DestMax\r
2057 )\r
2058{\r
2059 UINTN SourceLen;\r
2060\r
2061 ASSERT (((UINTN) Source & BIT0) == 0);\r
2062\r
2063 //\r
2064 // 1. Neither Destination nor Source shall be a null pointer.\r
2065 //\r
2066 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2067 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2068\r
2069 //\r
2070 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.\r
2071 //\r
2072 if (ASCII_RSIZE_MAX != 0) {\r
2073 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2074 }\r
2075 if (RSIZE_MAX != 0) {\r
2076 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2077 }\r
2078\r
2079 //\r
2080 // 3. DestMax shall not equal zero.\r
2081 //\r
2082 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2083\r
2084 //\r
2085 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).\r
2086 //\r
2087 SourceLen = StrnLenS (Source, DestMax);\r
2088 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2089\r
2090 //\r
2091 // 5. Copying shall not take place between objects that overlap.\r
2092 //\r
2093 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
2094\r
2095 //\r
2096 // convert string\r
2097 //\r
2098 while (*Source != '\0') {\r
2099 //\r
2100 // If any Unicode characters in Source contain\r
2101 // non-zero value in the upper 8 bits, then ASSERT().\r
2102 //\r
2103 ASSERT (*Source < 0x100);\r
2104 *(Destination++) = (CHAR8) *(Source++);\r
2105 }\r
2106 *Destination = '\0';\r
2107\r
2108 return RETURN_SUCCESS;\r
2109}\r
2110\r
02263214
HW
2111/**\r
2112 Convert not more than Length successive characters from a Null-terminated\r
2113 Unicode string to a Null-terminated Ascii string. If no null char is copied\r
2114 from Source, then Destination[Length] is always set to null.\r
2115\r
2116 This function converts not more than Length successive characters from the\r
2117 Unicode string Source to the Ascii string Destination by copying the lower 8\r
2118 bits of each Unicode character. The function terminates the Ascii string\r
2119 Destination by appending a Null-terminator character at the end.\r
2120\r
2121 The caller is responsible to make sure Destination points to a buffer with\r
2122 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))\r
2123 in bytes.\r
2124\r
2125 If any Unicode characters in Source contain non-zero value in the upper 8\r
2126 bits, then ASSERT().\r
2127 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
2128 If an error would be returned, then the function will also ASSERT().\r
2129\r
2130 If an error is returned, then Destination and DestinationLength are\r
2131 unmodified.\r
2132\r
2133 @param Source The pointer to a Null-terminated Unicode string.\r
2134 @param Length The maximum number of Unicode characters to\r
2135 convert.\r
2136 @param Destination The pointer to a Null-terminated Ascii string.\r
2137 @param DestMax The maximum number of Destination Ascii char,\r
2138 including terminating null char.\r
2139 @param DestinationLength The number of Unicode characters converted.\r
2140\r
2141 @retval RETURN_SUCCESS String is converted.\r
2142 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2143 If Source is NULL.\r
2144 If DestinationLength is NULL.\r
2145 If PcdMaximumAsciiStringLength is not zero,\r
2146 and Length or DestMax is greater than\r
2147 PcdMaximumAsciiStringLength.\r
2148 If PcdMaximumUnicodeStringLength is not\r
2149 zero, and Length or DestMax is greater than\r
2150 PcdMaximumUnicodeStringLength.\r
2151 If DestMax is 0.\r
2152 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2153 MIN(StrLen(Source), Length).\r
2154 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2155\r
2156**/\r
2157RETURN_STATUS\r
2158EFIAPI\r
2159UnicodeStrnToAsciiStrS (\r
2160 IN CONST CHAR16 *Source,\r
2161 IN UINTN Length,\r
2162 OUT CHAR8 *Destination,\r
2163 IN UINTN DestMax,\r
2164 OUT UINTN *DestinationLength\r
2165 )\r
2166{\r
2167 UINTN SourceLen;\r
2168\r
2169 ASSERT (((UINTN) Source & BIT0) == 0);\r
2170\r
2171 //\r
2172 // 1. None of Destination, Source or DestinationLength shall be a null\r
2173 // pointer.\r
2174 //\r
2175 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2176 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2177 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2178\r
2179 //\r
2180 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2181 // RSIZE_MAX.\r
2182 //\r
2183 if (ASCII_RSIZE_MAX != 0) {\r
2184 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2185 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2186 }\r
2187 if (RSIZE_MAX != 0) {\r
2188 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2189 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2190 }\r
2191\r
2192 //\r
2193 // 3. DestMax shall not equal zero.\r
2194 //\r
2195 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2196\r
2197 //\r
2198 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2199 // StrnLenS(Source, DestMax).\r
2200 //\r
2201 SourceLen = StrnLenS (Source, DestMax);\r
2202 if (Length >= DestMax) {\r
2203 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2204 }\r
2205\r
2206 //\r
2207 // 5. Copying shall not take place between objects that overlap.\r
2208 //\r
2209 if (SourceLen > Length) {\r
2210 SourceLen = Length;\r
2211 }\r
2212 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
2213\r
2214 *DestinationLength = 0;\r
2215\r
2216 //\r
2217 // Convert string\r
2218 //\r
2219 while ((*Source != 0) && (SourceLen > 0)) {\r
2220 //\r
2221 // If any Unicode characters in Source contain non-zero value in the upper\r
2222 // 8 bits, then ASSERT().\r
2223 //\r
2224 ASSERT (*Source < 0x100);\r
2225 *(Destination++) = (CHAR8) *(Source++);\r
2226 SourceLen--;\r
2227 (*DestinationLength)++;\r
2228 }\r
2229 *Destination = 0;\r
2230\r
2231 return RETURN_SUCCESS;\r
2232}\r
3ab41b7a
JY
2233\r
2234/**\r
2235 Convert one Null-terminated ASCII string to a Null-terminated\r
2236 Unicode string.\r
2237\r
2238 This function is similar to StrCpyS.\r
2239\r
2240 This function converts the contents of the ASCII string Source to the Unicode\r
2241 string Destination. The function terminates the Unicode string Destination by\r
2242 appending a Null-terminator character at the end.\r
2243\r
2244 The caller is responsible to make sure Destination points to a buffer with size\r
2245 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
2246\r
2247 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
2248 If an error would be returned, then the function will also ASSERT().\r
2249\r
2250 If an error is returned, then the Destination is unmodified.\r
2251\r
2252 @param Source The pointer to a Null-terminated ASCII string.\r
2253 @param Destination The pointer to a Null-terminated Unicode string.\r
2254 @param DestMax The maximum number of Destination Unicode\r
2255 char, including terminating null char.\r
2256\r
2257 @retval RETURN_SUCCESS String is converted.\r
2258 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2259 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2260 If Source is NULL.\r
2261 If PcdMaximumUnicodeStringLength is not zero,\r
2262 and DestMax is greater than\r
2263 PcdMaximumUnicodeStringLength.\r
2264 If PcdMaximumAsciiStringLength is not zero,\r
2265 and DestMax is greater than\r
2266 PcdMaximumAsciiStringLength.\r
2267 If DestMax is 0.\r
2268 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2269\r
2270**/\r
2271RETURN_STATUS\r
2272EFIAPI\r
2273AsciiStrToUnicodeStrS (\r
2274 IN CONST CHAR8 *Source,\r
2275 OUT CHAR16 *Destination,\r
2276 IN UINTN DestMax\r
2277 )\r
2278{\r
2279 UINTN SourceLen;\r
2280\r
2281 ASSERT (((UINTN) Destination & BIT0) == 0);\r
2282\r
2283 //\r
2284 // 1. Neither Destination nor Source shall be a null pointer.\r
2285 //\r
2286 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2287 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2288\r
2289 //\r
2290 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.\r
2291 //\r
2292 if (RSIZE_MAX != 0) {\r
2293 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2294 }\r
2295 if (ASCII_RSIZE_MAX != 0) {\r
2296 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2297 }\r
2298\r
2299 //\r
2300 // 3. DestMax shall not equal zero.\r
2301 //\r
2302 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2303\r
2304 //\r
2305 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
2306 //\r
2307 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2308 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2309\r
2310 //\r
2311 // 5. Copying shall not take place between objects that overlap.\r
2312 //\r
2313 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2314\r
2315 //\r
2316 // Convert string\r
2317 //\r
2318 while (*Source != '\0') {\r
2319 *(Destination++) = (CHAR16)*(Source++);\r
2320 }\r
2321 *Destination = '\0';\r
2322\r
2323 return RETURN_SUCCESS;\r
2324}\r
02263214
HW
2325\r
2326/**\r
2327 Convert not more than Length successive characters from a Null-terminated\r
2328 Ascii string to a Null-terminated Unicode string. If no null char is copied\r
2329 from Source, then Destination[Length] is always set to null.\r
2330\r
2331 This function converts not more than Length successive characters from the\r
2332 Ascii string Source to the Unicode string Destination. The function\r
2333 terminates the Unicode string Destination by appending a Null-terminator\r
2334 character at the end.\r
2335\r
2336 The caller is responsible to make sure Destination points to a buffer with\r
2337 size not smaller than\r
2338 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.\r
2339\r
2340 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
2341 If an error would be returned, then the function will also ASSERT().\r
2342\r
2343 If an error is returned, then Destination and DestinationLength are\r
2344 unmodified.\r
2345\r
2346 @param Source The pointer to a Null-terminated Ascii string.\r
2347 @param Length The maximum number of Ascii characters to convert.\r
2348 @param Destination The pointer to a Null-terminated Unicode string.\r
2349 @param DestMax The maximum number of Destination Unicode char,\r
2350 including terminating null char.\r
2351 @param DestinationLength The number of Ascii characters converted.\r
2352\r
2353 @retval RETURN_SUCCESS String is converted.\r
2354 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2355 If Source is NULL.\r
2356 If DestinationLength is NULL.\r
2357 If PcdMaximumUnicodeStringLength is not\r
2358 zero, and Length or DestMax is greater than\r
2359 PcdMaximumUnicodeStringLength.\r
2360 If PcdMaximumAsciiStringLength is not zero,\r
2361 and Length or DestMax is greater than\r
2362 PcdMaximumAsciiStringLength.\r
2363 If DestMax is 0.\r
2364 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2365 MIN(AsciiStrLen(Source), Length).\r
2366 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2367\r
2368**/\r
2369RETURN_STATUS\r
2370EFIAPI\r
2371AsciiStrnToUnicodeStrS (\r
2372 IN CONST CHAR8 *Source,\r
2373 IN UINTN Length,\r
2374 OUT CHAR16 *Destination,\r
2375 IN UINTN DestMax,\r
2376 OUT UINTN *DestinationLength\r
2377 )\r
2378{\r
2379 UINTN SourceLen;\r
2380\r
2381 ASSERT (((UINTN) Destination & BIT0) == 0);\r
2382\r
2383 //\r
2384 // 1. None of Destination, Source or DestinationLength shall be a null\r
2385 // pointer.\r
2386 //\r
2387 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2388 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2389 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2390\r
2391 //\r
2392 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2393 // RSIZE_MAX.\r
2394 //\r
2395 if (RSIZE_MAX != 0) {\r
2396 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2397 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2398 }\r
2399 if (ASCII_RSIZE_MAX != 0) {\r
2400 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2401 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2402 }\r
2403\r
2404 //\r
2405 // 3. DestMax shall not equal zero.\r
2406 //\r
2407 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2408\r
2409 //\r
2410 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2411 // AsciiStrnLenS(Source, DestMax).\r
2412 //\r
2413 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2414 if (Length >= DestMax) {\r
2415 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2416 }\r
2417\r
2418 //\r
2419 // 5. Copying shall not take place between objects that overlap.\r
2420 //\r
2421 if (SourceLen > Length) {\r
2422 SourceLen = Length;\r
2423 }\r
2424 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2425\r
2426 *DestinationLength = 0;\r
2427\r
2428 //\r
2429 // Convert string\r
2430 //\r
2431 while ((*Source != 0) && (SourceLen > 0)) {\r
2432 *(Destination++) = (CHAR16)*(Source++);\r
2433 SourceLen--;\r
2434 (*DestinationLength)++;\r
2435 }\r
2436 *Destination = 0;\r
2437\r
2438 return RETURN_SUCCESS;\r
2439}\r