]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/SafeString.c
SecurityPkg: Change default value source
[mirror_edk2.git] / MdePkg / Library / BaseLib / SafeString.c
CommitLineData
c058d59f
JY
1/** @file\r
2 Safe String functions.\r
3\r
5dbfa01e 4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
c058d59f
JY
6\r
7**/\r
8\r
d8af3301 9#include "BaseLibInternals.h"\r
c058d59f
JY
10\r
11#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))\r
12\r
13#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))\r
14\r
15#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \\r
16 do { \\r
17 ASSERT (Expression); \\r
18 if (!(Expression)) { \\r
19 return Status; \\r
20 } \\r
21 } while (FALSE)\r
22\r
23/**\r
24 Returns if 2 memory blocks are overlapped.\r
25\r
26 @param Base1 Base address of 1st memory block.\r
27 @param Size1 Size of 1st memory block.\r
28 @param Base2 Base address of 2nd memory block.\r
29 @param Size2 Size of 2nd memory block.\r
30\r
31 @retval TRUE 2 memory blocks are overlapped.\r
32 @retval FALSE 2 memory blocks are not overlapped.\r
33**/\r
34BOOLEAN\r
35InternalSafeStringIsOverlap (\r
36 IN VOID *Base1,\r
37 IN UINTN Size1,\r
38 IN VOID *Base2,\r
39 IN UINTN Size2\r
40 )\r
41{\r
42 if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||\r
43 (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {\r
44 return TRUE;\r
45 }\r
46 return FALSE;\r
47}\r
48\r
49/**\r
50 Returns if 2 Unicode strings are not overlapped.\r
51\r
52 @param Str1 Start address of 1st Unicode string.\r
53 @param Size1 The number of char in 1st Unicode string,\r
54 including terminating null char.\r
55 @param Str2 Start address of 2nd Unicode string.\r
56 @param Size2 The number of char in 2nd Unicode string,\r
57 including terminating null char.\r
58\r
59 @retval TRUE 2 Unicode strings are NOT overlapped.\r
60 @retval FALSE 2 Unicode strings are overlapped.\r
61**/\r
62BOOLEAN\r
63InternalSafeStringNoStrOverlap (\r
64 IN CHAR16 *Str1,\r
65 IN UINTN Size1,\r
66 IN CHAR16 *Str2,\r
67 IN UINTN Size2\r
68 )\r
69{\r
70 return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));\r
71}\r
72\r
73/**\r
74 Returns if 2 Ascii strings are not overlapped.\r
75\r
76 @param Str1 Start address of 1st Ascii string.\r
77 @param Size1 The number of char in 1st Ascii string,\r
78 including terminating null char.\r
79 @param Str2 Start address of 2nd Ascii string.\r
80 @param Size2 The number of char in 2nd Ascii string,\r
81 including terminating null char.\r
82\r
83 @retval TRUE 2 Ascii strings are NOT overlapped.\r
84 @retval FALSE 2 Ascii strings are overlapped.\r
85**/\r
86BOOLEAN\r
87InternalSafeStringNoAsciiStrOverlap (\r
88 IN CHAR8 *Str1,\r
89 IN UINTN Size1,\r
90 IN CHAR8 *Str2,\r
91 IN UINTN Size2\r
92 )\r
93{\r
94 return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);\r
95}\r
96\r
97/**\r
98 Returns the length of a Null-terminated Unicode string.\r
99\r
328f84b1
JY
100 This function is similar as strlen_s defined in C11.\r
101\r
c058d59f
JY
102 If String is not aligned on a 16-bit boundary, then ASSERT().\r
103\r
104 @param String A pointer to a Null-terminated Unicode string.\r
105 @param MaxSize The maximum number of Destination Unicode\r
106 char, including terminating null char.\r
107\r
108 @retval 0 If String is NULL.\r
109 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
110 @return The number of characters that percede the terminating null character.\r
111\r
112**/\r
113UINTN\r
114EFIAPI\r
115StrnLenS (\r
116 IN CONST CHAR16 *String,\r
117 IN UINTN MaxSize\r
118 )\r
119{\r
120 UINTN Length;\r
121\r
122 ASSERT (((UINTN) String & BIT0) == 0);\r
123\r
124 //\r
cb867499 125 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.\r
c058d59f 126 //\r
cb867499 127 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
128 return 0;\r
129 }\r
130\r
131 //\r
132 // Otherwise, the StrnLenS function returns the number of characters that precede the\r
133 // terminating null character. If there is no null character in the first MaxSize characters of\r
134 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
135 // be accessed by StrnLenS.\r
136 //\r
c07c517c
HW
137 Length = 0;\r
138 while (String[Length] != 0) {\r
139 if (Length >= MaxSize - 1) {\r
140 return MaxSize;\r
141 }\r
142 Length++;\r
c058d59f
JY
143 }\r
144 return Length;\r
145}\r
146\r
b590e43a
HW
147/**\r
148 Returns the size of a Null-terminated Unicode string in bytes, including the\r
149 Null terminator.\r
150\r
151 This function returns the size of the Null-terminated Unicode string\r
152 specified by String in bytes, including the Null terminator.\r
153\r
154 If String is not aligned on a 16-bit boundary, then ASSERT().\r
155\r
156 @param String A pointer to a Null-terminated Unicode string.\r
157 @param MaxSize The maximum number of Destination Unicode\r
158 char, including the Null terminator.\r
159\r
160 @retval 0 If String is NULL.\r
161 @retval (sizeof (CHAR16) * (MaxSize + 1))\r
162 If there is no Null terminator in the first MaxSize characters of\r
163 String.\r
164 @return The size of the Null-terminated Unicode string in bytes, including\r
165 the Null terminator.\r
166\r
167**/\r
168UINTN\r
169EFIAPI\r
170StrnSizeS (\r
171 IN CONST CHAR16 *String,\r
172 IN UINTN MaxSize\r
173 )\r
174{\r
175 //\r
176 // If String is a null pointer, then the StrnSizeS function returns zero.\r
177 //\r
178 if (String == NULL) {\r
179 return 0;\r
180 }\r
181\r
182 //\r
183 // Otherwise, the StrnSizeS function returns the size of the Null-terminated\r
184 // Unicode string in bytes, including the Null terminator. If there is no\r
185 // Null terminator in the first MaxSize characters of String, then StrnSizeS\r
186 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with\r
187 // the StrnLenS function.\r
188 //\r
189 return (StrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
190}\r
191\r
c058d59f
JY
192/**\r
193 Copies the string pointed to by Source (including the terminating null char)\r
194 to the array pointed to by Destination.\r
195\r
328f84b1
JY
196 This function is similar as strcpy_s defined in C11.\r
197\r
c058d59f
JY
198 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
199 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 200 If an error would be returned, then the function will also ASSERT().\r
c058d59f 201\r
328f84b1
JY
202 If an error is returned, then the Destination is unmodified.\r
203\r
c058d59f
JY
204 @param Destination A pointer to a Null-terminated Unicode string.\r
205 @param DestMax The maximum number of Destination Unicode\r
206 char, including terminating null char.\r
207 @param Source A pointer to a Null-terminated Unicode string.\r
208\r
209 @retval RETURN_SUCCESS String is copied.\r
210 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
211 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
212 If Source is NULL.\r
213 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 214 and DestMax is greater than\r
c058d59f
JY
215 PcdMaximumUnicodeStringLength.\r
216 If DestMax is 0.\r
217 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
218**/\r
219RETURN_STATUS\r
220EFIAPI\r
221StrCpyS (\r
222 OUT CHAR16 *Destination,\r
223 IN UINTN DestMax,\r
224 IN CONST CHAR16 *Source\r
225 )\r
226{\r
227 UINTN SourceLen;\r
973f8862 228\r
c058d59f
JY
229 ASSERT (((UINTN) Destination & BIT0) == 0);\r
230 ASSERT (((UINTN) Source & BIT0) == 0);\r
231\r
232 //\r
233 // 1. Neither Destination nor Source shall be a null pointer.\r
234 //\r
235 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
236 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
237\r
238 //\r
239 // 2. DestMax shall not be greater than RSIZE_MAX.\r
240 //\r
241 if (RSIZE_MAX != 0) {\r
242 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
243 }\r
244\r
245 //\r
246 // 3. DestMax shall not equal zero.\r
247 //\r
248 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
249\r
250 //\r
251 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).\r
252 //\r
253 SourceLen = StrnLenS (Source, DestMax);\r
254 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
255\r
256 //\r
257 // 5. Copying shall not take place between objects that overlap.\r
258 //\r
259 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
260\r
261 //\r
262 // The StrCpyS function copies the string pointed to by Source (including the terminating\r
263 // null character) into the array pointed to by Destination.\r
264 //\r
265 while (*Source != 0) {\r
266 *(Destination++) = *(Source++);\r
267 }\r
268 *Destination = 0;\r
269\r
270 return RETURN_SUCCESS;\r
271}\r
272\r
273/**\r
274 Copies not more than Length successive char from the string pointed to by\r
275 Source to the array pointed to by Destination. If no null char is copied from\r
276 Source, then Destination[Length] is always set to null.\r
277\r
328f84b1
JY
278 This function is similar as strncpy_s defined in C11.\r
279\r
c058d59f
JY
280 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
281 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 282 If an error would be returned, then the function will also ASSERT().\r
c058d59f 283\r
328f84b1
JY
284 If an error is returned, then the Destination is unmodified.\r
285\r
c058d59f
JY
286 @param Destination A pointer to a Null-terminated Unicode string.\r
287 @param DestMax The maximum number of Destination Unicode\r
288 char, including terminating null char.\r
289 @param Source A pointer to a Null-terminated Unicode string.\r
290 @param Length The maximum number of Unicode characters to copy.\r
291\r
292 @retval RETURN_SUCCESS String is copied.\r
973f8862 293 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
294 MIN(StrLen(Source), Length).\r
295 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
296 If Source is NULL.\r
297 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 298 and DestMax is greater than\r
c058d59f
JY
299 PcdMaximumUnicodeStringLength.\r
300 If DestMax is 0.\r
301 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
302**/\r
303RETURN_STATUS\r
304EFIAPI\r
305StrnCpyS (\r
306 OUT CHAR16 *Destination,\r
307 IN UINTN DestMax,\r
308 IN CONST CHAR16 *Source,\r
309 IN UINTN Length\r
310 )\r
311{\r
312 UINTN SourceLen;\r
313\r
314 ASSERT (((UINTN) Destination & BIT0) == 0);\r
315 ASSERT (((UINTN) Source & BIT0) == 0);\r
316\r
317 //\r
318 // 1. Neither Destination nor Source shall be a null pointer.\r
319 //\r
320 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
321 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
322\r
323 //\r
324 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX\r
325 //\r
326 if (RSIZE_MAX != 0) {\r
327 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
328 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
329 }\r
330\r
331 //\r
332 // 3. DestMax shall not equal zero.\r
333 //\r
334 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
335\r
336 //\r
337 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).\r
338 //\r
56658c22 339 SourceLen = StrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
340 if (Length >= DestMax) {\r
341 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
342 }\r
343\r
344 //\r
345 // 5. Copying shall not take place between objects that overlap.\r
346 //\r
347 if (SourceLen > Length) {\r
348 SourceLen = Length;\r
349 }\r
350 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
351\r
352 //\r
353 // The StrnCpyS function copies not more than Length successive characters (characters that\r
354 // follow a null character are not copied) from the array pointed to by Source to the array\r
355 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
356 // character.\r
357 //\r
56658c22 358 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
359 *(Destination++) = *(Source++);\r
360 SourceLen--;\r
361 }\r
362 *Destination = 0;\r
363\r
364 return RETURN_SUCCESS;\r
365}\r
366\r
367/**\r
368 Appends a copy of the string pointed to by Source (including the terminating\r
369 null char) to the end of the string pointed to by Destination.\r
370\r
328f84b1
JY
371 This function is similar as strcat_s defined in C11.\r
372\r
c058d59f
JY
373 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
374 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb 375 If an error would be returned, then the function will also ASSERT().\r
c058d59f 376\r
328f84b1
JY
377 If an error is returned, then the Destination is unmodified.\r
378\r
c058d59f
JY
379 @param Destination A pointer to a Null-terminated Unicode string.\r
380 @param DestMax The maximum number of Destination Unicode\r
381 char, including terminating null char.\r
382 @param Source A pointer to a Null-terminated Unicode string.\r
383\r
384 @retval RETURN_SUCCESS String is appended.\r
973f8862 385 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
386 StrLen(Destination).\r
387 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
388 greater than StrLen(Source).\r
389 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
390 If Source is NULL.\r
391 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 392 and DestMax is greater than\r
c058d59f
JY
393 PcdMaximumUnicodeStringLength.\r
394 If DestMax is 0.\r
395 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
396**/\r
397RETURN_STATUS\r
398EFIAPI\r
399StrCatS (\r
400 IN OUT CHAR16 *Destination,\r
401 IN UINTN DestMax,\r
402 IN CONST CHAR16 *Source\r
403 )\r
404{\r
405 UINTN DestLen;\r
406 UINTN CopyLen;\r
407 UINTN SourceLen;\r
973f8862 408\r
c058d59f
JY
409 ASSERT (((UINTN) Destination & BIT0) == 0);\r
410 ASSERT (((UINTN) Source & BIT0) == 0);\r
411\r
412 //\r
413 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.\r
414 //\r
415 DestLen = StrnLenS (Destination, DestMax);\r
416 CopyLen = DestMax - DestLen;\r
417\r
418 //\r
419 // 1. Neither Destination nor Source shall be a null pointer.\r
420 //\r
421 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
422 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
423\r
424 //\r
425 // 2. DestMax shall not be greater than RSIZE_MAX.\r
426 //\r
427 if (RSIZE_MAX != 0) {\r
428 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
429 }\r
430\r
431 //\r
432 // 3. DestMax shall not equal zero.\r
433 //\r
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
435\r
436 //\r
437 // 4. CopyLen shall not equal zero.\r
438 //\r
439 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
440\r
441 //\r
442 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
443 //\r
444 SourceLen = StrnLenS (Source, CopyLen);\r
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
446\r
447 //\r
448 // 6. Copying shall not take place between objects that overlap.\r
449 //\r
450 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
451\r
452 //\r
453 // The StrCatS function appends a copy of the string pointed to by Source (including the\r
454 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
455 // from Source overwrites the null character at the end of Destination.\r
456 //\r
457 Destination = Destination + DestLen;\r
458 while (*Source != 0) {\r
459 *(Destination++) = *(Source++);\r
460 }\r
461 *Destination = 0;\r
462\r
463 return RETURN_SUCCESS;\r
464}\r
465\r
466/**\r
467 Appends not more than Length successive char from the string pointed to by\r
468 Source to the end of the string pointed to by Destination. If no null char is\r
469 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
470 set to null.\r
471\r
328f84b1
JY
472 This function is similar as strncat_s defined in C11.\r
473\r
c058d59f 474 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
0e93edbb
JY
475 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
476 If an error would be returned, then the function will also ASSERT().\r
c058d59f 477\r
328f84b1
JY
478 If an error is returned, then the Destination is unmodified.\r
479\r
c058d59f
JY
480 @param Destination A pointer to a Null-terminated Unicode string.\r
481 @param DestMax The maximum number of Destination Unicode\r
482 char, including terminating null char.\r
483 @param Source A pointer to a Null-terminated Unicode string.\r
484 @param Length The maximum number of Unicode characters to copy.\r
485\r
486 @retval RETURN_SUCCESS String is appended.\r
487 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
488 StrLen(Destination).\r
489 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
490 greater than MIN(StrLen(Source), Length).\r
491 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
492 If Source is NULL.\r
493 If PcdMaximumUnicodeStringLength is not zero,\r
973f8862 494 and DestMax is greater than\r
c058d59f
JY
495 PcdMaximumUnicodeStringLength.\r
496 If DestMax is 0.\r
497 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
498**/\r
499RETURN_STATUS\r
500EFIAPI\r
501StrnCatS (\r
502 IN OUT CHAR16 *Destination,\r
503 IN UINTN DestMax,\r
504 IN CONST CHAR16 *Source,\r
505 IN UINTN Length\r
506 )\r
507{\r
508 UINTN DestLen;\r
509 UINTN CopyLen;\r
510 UINTN SourceLen;\r
973f8862 511\r
c058d59f
JY
512 ASSERT (((UINTN) Destination & BIT0) == 0);\r
513 ASSERT (((UINTN) Source & BIT0) == 0);\r
514\r
515 //\r
516 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.\r
517 //\r
518 DestLen = StrnLenS (Destination, DestMax);\r
519 CopyLen = DestMax - DestLen;\r
520\r
521 //\r
522 // 1. Neither Destination nor Source shall be a null pointer.\r
523 //\r
524 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
525 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
526\r
527 //\r
528 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.\r
529 //\r
530 if (RSIZE_MAX != 0) {\r
531 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
532 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
533 }\r
534\r
535 //\r
536 // 3. DestMax shall not equal zero.\r
537 //\r
538 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
539\r
540 //\r
541 // 4. CopyLen shall not equal zero.\r
542 //\r
543 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
544\r
545 //\r
546 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).\r
547 //\r
56658c22 548 SourceLen = StrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
549 if (Length >= CopyLen) {\r
550 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
551 }\r
552\r
553 //\r
554 // 6. Copying shall not take place between objects that overlap.\r
555 //\r
556 if (SourceLen > Length) {\r
557 SourceLen = Length;\r
558 }\r
559 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
560\r
561 //\r
562 // The StrnCatS function appends not more than Length successive characters (characters\r
563 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
564 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
565 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
566 // a null character.\r
567 //\r
568 Destination = Destination + DestLen;\r
56658c22 569 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
570 *(Destination++) = *(Source++);\r
571 SourceLen--;\r
572 }\r
573 *Destination = 0;\r
574\r
575 return RETURN_SUCCESS;\r
576}\r
577\r
d8af3301
HW
578/**\r
579 Convert a Null-terminated Unicode decimal string to a value of type UINTN.\r
580\r
581 This function outputs a value of type UINTN by interpreting the contents of\r
582 the Unicode string specified by String as a decimal number. The format of the\r
583 input Unicode string String is:\r
584\r
585 [spaces] [decimal digits].\r
586\r
587 The valid decimal digit character is in the range [0-9]. The function will\r
588 ignore the pad space, which includes spaces or tab characters, before\r
589 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
590 be ignored. Then, the function stops at the first character that is a not a\r
591 valid decimal character or a Null-terminator, whichever one comes first.\r
592\r
593 If String is NULL, then ASSERT().\r
594 If Data is NULL, then ASSERT().\r
595 If String is not aligned in a 16-bit boundary, then ASSERT().\r
596 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
597 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
598 Null-terminator, then ASSERT().\r
599\r
600 If String has no valid decimal digits in the above format, then 0 is stored\r
601 at the location pointed to by Data.\r
602 If the number represented by String exceeds the range defined by UINTN, then\r
603 MAX_UINTN is stored at the location pointed to by Data.\r
604\r
605 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
606 is stored at the location pointed to by EndPointer. If String has no valid\r
607 decimal digits right after the optional pad spaces, the value of String is\r
608 stored at the location pointed to by EndPointer.\r
609\r
610 @param String Pointer to a Null-terminated Unicode string.\r
611 @param EndPointer Pointer to character that stops scan.\r
612 @param Data Pointer to the converted value.\r
613\r
614 @retval RETURN_SUCCESS Value is translated from String.\r
615 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
616 If Data is NULL.\r
617 If PcdMaximumUnicodeStringLength is not\r
618 zero, and String contains more than\r
619 PcdMaximumUnicodeStringLength Unicode\r
620 characters, not including the\r
621 Null-terminator.\r
622 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
623 the range defined by UINTN.\r
624\r
625**/\r
626RETURN_STATUS\r
627EFIAPI\r
628StrDecimalToUintnS (\r
629 IN CONST CHAR16 *String,\r
630 OUT CHAR16 **EndPointer, OPTIONAL\r
631 OUT UINTN *Data\r
632 )\r
633{\r
634 ASSERT (((UINTN) String & BIT0) == 0);\r
635\r
636 //\r
637 // 1. Neither String nor Data shall be a null pointer.\r
638 //\r
639 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
640 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
641\r
642 //\r
643 // 2. The length of String shall not be greater than RSIZE_MAX.\r
644 //\r
645 if (RSIZE_MAX != 0) {\r
646 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
647 }\r
648\r
649 if (EndPointer != NULL) {\r
650 *EndPointer = (CHAR16 *) String;\r
651 }\r
652\r
653 //\r
654 // Ignore the pad spaces (space or tab)\r
655 //\r
656 while ((*String == L' ') || (*String == L'\t')) {\r
657 String++;\r
658 }\r
659\r
660 //\r
661 // Ignore leading Zeros after the spaces\r
662 //\r
663 while (*String == L'0') {\r
664 String++;\r
665 }\r
666\r
667 *Data = 0;\r
668\r
669 while (InternalIsDecimalDigitCharacter (*String)) {\r
670 //\r
671 // If the number represented by String overflows according to the range\r
672 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
673 // RETURN_UNSUPPORTED is returned.\r
674 //\r
675 if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) {\r
676 *Data = MAX_UINTN;\r
677 if (EndPointer != NULL) {\r
678 *EndPointer = (CHAR16 *) String;\r
679 }\r
680 return RETURN_UNSUPPORTED;\r
681 }\r
682\r
683 *Data = *Data * 10 + (*String - L'0');\r
684 String++;\r
685 }\r
686\r
687 if (EndPointer != NULL) {\r
688 *EndPointer = (CHAR16 *) String;\r
689 }\r
690 return RETURN_SUCCESS;\r
691}\r
692\r
693/**\r
694 Convert a Null-terminated Unicode decimal string to a value of type UINT64.\r
695\r
696 This function outputs a value of type UINT64 by interpreting the contents of\r
697 the Unicode string specified by String as a decimal number. The format of the\r
698 input Unicode string String is:\r
699\r
700 [spaces] [decimal digits].\r
701\r
702 The valid decimal digit character is in the range [0-9]. The function will\r
703 ignore the pad space, which includes spaces or tab characters, before\r
704 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
705 be ignored. Then, the function stops at the first character that is a not a\r
706 valid decimal character or a Null-terminator, whichever one comes first.\r
707\r
708 If String is NULL, then ASSERT().\r
709 If Data is NULL, then ASSERT().\r
710 If String is not aligned in a 16-bit boundary, then ASSERT().\r
711 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
712 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
713 Null-terminator, then ASSERT().\r
714\r
715 If String has no valid decimal digits in the above format, then 0 is stored\r
716 at the location pointed to by Data.\r
717 If the number represented by String exceeds the range defined by UINT64, then\r
718 MAX_UINT64 is stored at the location pointed to by Data.\r
719\r
720 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
721 is stored at the location pointed to by EndPointer. If String has no valid\r
722 decimal digits right after the optional pad spaces, the value of String is\r
723 stored at the location pointed to by EndPointer.\r
724\r
725 @param String Pointer to a Null-terminated Unicode string.\r
726 @param EndPointer Pointer to character that stops scan.\r
727 @param Data Pointer to the converted value.\r
728\r
729 @retval RETURN_SUCCESS Value is translated from String.\r
730 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
731 If Data is NULL.\r
732 If PcdMaximumUnicodeStringLength is not\r
733 zero, and String contains more than\r
734 PcdMaximumUnicodeStringLength Unicode\r
735 characters, not including the\r
736 Null-terminator.\r
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
738 the range defined by UINT64.\r
739\r
740**/\r
741RETURN_STATUS\r
742EFIAPI\r
743StrDecimalToUint64S (\r
744 IN CONST CHAR16 *String,\r
745 OUT CHAR16 **EndPointer, OPTIONAL\r
746 OUT UINT64 *Data\r
747 )\r
748{\r
749 ASSERT (((UINTN) String & BIT0) == 0);\r
750\r
751 //\r
752 // 1. Neither String nor Data shall be a null pointer.\r
753 //\r
754 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
755 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
756\r
757 //\r
758 // 2. The length of String shall not be greater than RSIZE_MAX.\r
759 //\r
760 if (RSIZE_MAX != 0) {\r
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
762 }\r
763\r
764 if (EndPointer != NULL) {\r
765 *EndPointer = (CHAR16 *) String;\r
766 }\r
767\r
768 //\r
769 // Ignore the pad spaces (space or tab)\r
770 //\r
771 while ((*String == L' ') || (*String == L'\t')) {\r
772 String++;\r
773 }\r
774\r
775 //\r
776 // Ignore leading Zeros after the spaces\r
777 //\r
778 while (*String == L'0') {\r
779 String++;\r
780 }\r
781\r
782 *Data = 0;\r
783\r
784 while (InternalIsDecimalDigitCharacter (*String)) {\r
785 //\r
786 // If the number represented by String overflows according to the range\r
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
788 // RETURN_UNSUPPORTED is returned.\r
789 //\r
790 if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) {\r
791 *Data = MAX_UINT64;\r
792 if (EndPointer != NULL) {\r
793 *EndPointer = (CHAR16 *) String;\r
794 }\r
795 return RETURN_UNSUPPORTED;\r
796 }\r
797\r
798 *Data = MultU64x32 (*Data, 10) + (*String - L'0');\r
799 String++;\r
800 }\r
801\r
802 if (EndPointer != NULL) {\r
803 *EndPointer = (CHAR16 *) String;\r
804 }\r
805 return RETURN_SUCCESS;\r
806}\r
807\r
808/**\r
809 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
810 UINTN.\r
811\r
812 This function outputs a value of type UINTN by interpreting the contents of\r
813 the Unicode string specified by String as a hexadecimal number. The format of\r
814 the input Unicode string String is:\r
815\r
816 [spaces][zeros][x][hexadecimal digits].\r
817\r
818 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
819 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
820 If "x" appears in the input string, it must be prefixed with at least one 0.\r
821 The function will ignore the pad space, which includes spaces or tab\r
822 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
823 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
824 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
825 the first character that is a not a valid hexadecimal character or NULL,\r
826 whichever one comes first.\r
827\r
828 If String is NULL, then ASSERT().\r
829 If Data is NULL, then ASSERT().\r
830 If String is not aligned in a 16-bit boundary, then ASSERT().\r
831 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
832 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
833 Null-terminator, then ASSERT().\r
834\r
835 If String has no valid hexadecimal digits in the above format, then 0 is\r
836 stored at the location pointed to by Data.\r
837 If the number represented by String exceeds the range defined by UINTN, then\r
838 MAX_UINTN is stored at the location pointed to by Data.\r
839\r
840 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
841 is stored at the location pointed to by EndPointer. If String has no valid\r
842 hexadecimal digits right after the optional pad spaces, the value of String\r
843 is stored at the location pointed to by EndPointer.\r
844\r
845 @param String Pointer to a Null-terminated Unicode string.\r
846 @param EndPointer Pointer to character that stops scan.\r
847 @param Data Pointer to the converted value.\r
848\r
849 @retval RETURN_SUCCESS Value is translated from String.\r
850 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
851 If Data is NULL.\r
852 If PcdMaximumUnicodeStringLength is not\r
853 zero, and String contains more than\r
854 PcdMaximumUnicodeStringLength Unicode\r
855 characters, not including the\r
856 Null-terminator.\r
857 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
858 the range defined by UINTN.\r
859\r
860**/\r
861RETURN_STATUS\r
862EFIAPI\r
863StrHexToUintnS (\r
864 IN CONST CHAR16 *String,\r
865 OUT CHAR16 **EndPointer, OPTIONAL\r
866 OUT UINTN *Data\r
867 )\r
868{\r
869 ASSERT (((UINTN) String & BIT0) == 0);\r
870\r
871 //\r
872 // 1. Neither String nor Data shall be a null pointer.\r
873 //\r
874 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
875 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
876\r
877 //\r
878 // 2. The length of String shall not be greater than RSIZE_MAX.\r
879 //\r
880 if (RSIZE_MAX != 0) {\r
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
882 }\r
883\r
884 if (EndPointer != NULL) {\r
885 *EndPointer = (CHAR16 *) String;\r
886 }\r
887\r
888 //\r
889 // Ignore the pad spaces (space or tab)\r
890 //\r
891 while ((*String == L' ') || (*String == L'\t')) {\r
892 String++;\r
893 }\r
894\r
895 //\r
896 // Ignore leading Zeros after the spaces\r
897 //\r
898 while (*String == L'0') {\r
899 String++;\r
900 }\r
901\r
5dbfa01e 902 if (CharToUpper (*String) == L'X') {\r
d8af3301
HW
903 if (*(String - 1) != L'0') {\r
904 *Data = 0;\r
905 return RETURN_SUCCESS;\r
906 }\r
907 //\r
908 // Skip the 'X'\r
909 //\r
910 String++;\r
911 }\r
912\r
913 *Data = 0;\r
914\r
915 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
916 //\r
917 // If the number represented by String overflows according to the range\r
918 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
919 // RETURN_UNSUPPORTED is returned.\r
920 //\r
921 if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) {\r
922 *Data = MAX_UINTN;\r
923 if (EndPointer != NULL) {\r
924 *EndPointer = (CHAR16 *) String;\r
925 }\r
926 return RETURN_UNSUPPORTED;\r
927 }\r
928\r
929 *Data = (*Data << 4) + InternalHexCharToUintn (*String);\r
930 String++;\r
931 }\r
932\r
933 if (EndPointer != NULL) {\r
934 *EndPointer = (CHAR16 *) String;\r
935 }\r
936 return RETURN_SUCCESS;\r
937}\r
938\r
939/**\r
940 Convert a Null-terminated Unicode hexadecimal string to a value of type\r
941 UINT64.\r
942\r
943 This function outputs a value of type UINT64 by interpreting the contents of\r
944 the Unicode string specified by String as a hexadecimal number. The format of\r
945 the input Unicode string String is:\r
946\r
947 [spaces][zeros][x][hexadecimal digits].\r
948\r
949 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
950 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
951 If "x" appears in the input string, it must be prefixed with at least one 0.\r
952 The function will ignore the pad space, which includes spaces or tab\r
953 characters, before [zeros], [x] or [hexadecimal digit]. The running zero\r
954 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts\r
955 after [x] or the first valid hexadecimal digit. Then, the function stops at\r
956 the first character that is a not a valid hexadecimal character or NULL,\r
957 whichever one comes first.\r
958\r
959 If String is NULL, then ASSERT().\r
960 If Data is NULL, then ASSERT().\r
961 If String is not aligned in a 16-bit boundary, then ASSERT().\r
962 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
963 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
964 Null-terminator, then ASSERT().\r
965\r
966 If String has no valid hexadecimal digits in the above format, then 0 is\r
967 stored at the location pointed to by Data.\r
968 If the number represented by String exceeds the range defined by UINT64, then\r
969 MAX_UINT64 is stored at the location pointed to by Data.\r
970\r
971 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
972 is stored at the location pointed to by EndPointer. If String has no valid\r
973 hexadecimal digits right after the optional pad spaces, the value of String\r
974 is stored at the location pointed to by EndPointer.\r
975\r
976 @param String Pointer to a Null-terminated Unicode string.\r
977 @param EndPointer Pointer to character that stops scan.\r
978 @param Data Pointer to the converted value.\r
979\r
980 @retval RETURN_SUCCESS Value is translated from String.\r
981 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
982 If Data is NULL.\r
983 If PcdMaximumUnicodeStringLength is not\r
984 zero, and String contains more than\r
985 PcdMaximumUnicodeStringLength Unicode\r
986 characters, not including the\r
987 Null-terminator.\r
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
989 the range defined by UINT64.\r
990\r
991**/\r
992RETURN_STATUS\r
993EFIAPI\r
994StrHexToUint64S (\r
995 IN CONST CHAR16 *String,\r
996 OUT CHAR16 **EndPointer, OPTIONAL\r
997 OUT UINT64 *Data\r
998 )\r
999{\r
1000 ASSERT (((UINTN) String & BIT0) == 0);\r
1001\r
1002 //\r
1003 // 1. Neither String nor Data shall be a null pointer.\r
1004 //\r
1005 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1006 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
1007\r
1008 //\r
1009 // 2. The length of String shall not be greater than RSIZE_MAX.\r
1010 //\r
1011 if (RSIZE_MAX != 0) {\r
1012 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1013 }\r
1014\r
1015 if (EndPointer != NULL) {\r
1016 *EndPointer = (CHAR16 *) String;\r
1017 }\r
1018\r
1019 //\r
1020 // Ignore the pad spaces (space or tab)\r
1021 //\r
1022 while ((*String == L' ') || (*String == L'\t')) {\r
1023 String++;\r
1024 }\r
1025\r
1026 //\r
1027 // Ignore leading Zeros after the spaces\r
1028 //\r
1029 while (*String == L'0') {\r
1030 String++;\r
1031 }\r
1032\r
5dbfa01e 1033 if (CharToUpper (*String) == L'X') {\r
d8af3301
HW
1034 if (*(String - 1) != L'0') {\r
1035 *Data = 0;\r
1036 return RETURN_SUCCESS;\r
1037 }\r
1038 //\r
1039 // Skip the 'X'\r
1040 //\r
1041 String++;\r
1042 }\r
1043\r
1044 *Data = 0;\r
1045\r
1046 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
1047 //\r
1048 // If the number represented by String overflows according to the range\r
1049 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
1050 // RETURN_UNSUPPORTED is returned.\r
1051 //\r
1052 if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) {\r
1053 *Data = MAX_UINT64;\r
1054 if (EndPointer != NULL) {\r
1055 *EndPointer = (CHAR16 *) String;\r
1056 }\r
1057 return RETURN_UNSUPPORTED;\r
1058 }\r
1059\r
1060 *Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String);\r
1061 String++;\r
1062 }\r
1063\r
1064 if (EndPointer != NULL) {\r
1065 *EndPointer = (CHAR16 *) String;\r
1066 }\r
1067 return RETURN_SUCCESS;\r
1068}\r
1069\r
36396ea2
RN
1070/**\r
1071 Convert a Null-terminated Unicode string to IPv6 address and prefix length.\r
1072\r
1073 This function outputs a value of type IPv6_ADDRESS and may output a value\r
1074 of type UINT8 by interpreting the contents of the Unicode string specified\r
1075 by String. The format of the input Unicode string String is as follows:\r
1076\r
1077 X:X:X:X:X:X:X:X[/P]\r
1078\r
1079 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
1080 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
1081 memory address and high byte is stored in high memory address. P contains decimal\r
1082 digit characters in the range [0-9]. The running zero in the beginning of P will\r
1083 be ignored. /P is optional.\r
1084\r
1085 When /P is not in the String, the function stops at the first character that is\r
1086 not a valid hexadecimal digit character after eight X's are converted.\r
1087\r
1088 When /P is in the String, the function stops at the first character that is not\r
1089 a valid decimal digit character after P is converted.\r
1090\r
1091 "::" can be used to compress one or more groups of X when X contains only 0.\r
1092 The "::" can only appear once in the String.\r
1093\r
1094 If String is NULL, then ASSERT().\r
1095\r
1096 If Address is NULL, then ASSERT().\r
1097\r
1098 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1099\r
1100 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
1101 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
1102 Null-terminator, then ASSERT().\r
1103\r
1104 If EndPointer is not NULL and Address is translated from String, a pointer\r
1105 to the character that stopped the scan is stored at the location pointed to\r
1106 by EndPointer.\r
1107\r
1108 @param String Pointer to a Null-terminated Unicode string.\r
1109 @param EndPointer Pointer to character that stops scan.\r
1110 @param Address Pointer to the converted IPv6 address.\r
1111 @param PrefixLength Pointer to the converted IPv6 address prefix\r
1112 length. MAX_UINT8 is returned when /P is\r
1113 not in the String.\r
1114\r
1115 @retval RETURN_SUCCESS Address is translated from String.\r
1116 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1117 If Data is NULL.\r
1118 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
1119 digit characters.\r
1120 If String contains "::" and number of X\r
1121 is not less than 8.\r
1122 If P starts with character that is not a\r
1123 valid decimal digit character.\r
1124 If the decimal number converted from P\r
1125 exceeds 128.\r
1126\r
1127**/\r
1128RETURN_STATUS\r
1129EFIAPI\r
1130StrToIpv6Address (\r
1131 IN CONST CHAR16 *String,\r
1132 OUT CHAR16 **EndPointer, OPTIONAL\r
1133 OUT IPv6_ADDRESS *Address,\r
1134 OUT UINT8 *PrefixLength OPTIONAL\r
1135 )\r
1136{\r
1137 RETURN_STATUS Status;\r
1138 UINTN AddressIndex;\r
1139 UINTN Uintn;\r
1140 IPv6_ADDRESS LocalAddress;\r
1141 UINT8 LocalPrefixLength;\r
1142 CONST CHAR16 *Pointer;\r
1143 CHAR16 *End;\r
1144 UINTN CompressStart;\r
1145 BOOLEAN ExpectPrefix;\r
1146\r
1147 LocalPrefixLength = MAX_UINT8;\r
1148 CompressStart = ARRAY_SIZE (Address->Addr);\r
1149 ExpectPrefix = FALSE;\r
1150\r
1151 ASSERT (((UINTN) String & BIT0) == 0);\r
1152\r
1153 //\r
1154 // 1. None of String or Guid shall be a null pointer.\r
1155 //\r
1156 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1157 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1158\r
1159 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
1160 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1161 if (*Pointer != L':') {\r
1162 //\r
1163 // ":" or "/" should be followed by digit characters.\r
1164 //\r
1165 return RETURN_UNSUPPORTED;\r
1166 }\r
1167\r
1168 //\r
1169 // Meet second ":" after previous ":" or "/"\r
1170 // or meet first ":" in the beginning of String.\r
1171 //\r
1172 if (ExpectPrefix) {\r
1173 //\r
1174 // ":" shall not be after "/"\r
1175 //\r
1176 return RETURN_UNSUPPORTED;\r
1177 }\r
1178\r
1179 if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1180 //\r
1181 // "::" can only appear once.\r
1182 // "::" can only appear when address is not full length.\r
1183 //\r
1184 return RETURN_UNSUPPORTED;\r
1185 } else {\r
1186 //\r
1187 // Remember the start of zero compressing.\r
1188 //\r
1189 CompressStart = AddressIndex;\r
1190 Pointer++;\r
1191\r
1192 if (CompressStart == 0) {\r
1193 if (*Pointer != L':') {\r
1194 //\r
1195 // Single ":" shall not be in the beginning of String.\r
1196 //\r
1197 return RETURN_UNSUPPORTED;\r
1198 }\r
1199 Pointer++;\r
1200 }\r
1201 }\r
1202 }\r
1203\r
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {\r
1205 if (*Pointer == L'/') {\r
1206 //\r
1207 // Might be optional "/P" after "::".\r
1208 //\r
1209 if (CompressStart != AddressIndex) {\r
1210 return RETURN_UNSUPPORTED;\r
1211 }\r
1212 } else {\r
1213 break;\r
1214 }\r
1215 } else {\r
1216 if (!ExpectPrefix) {\r
1217 //\r
1218 // Get X.\r
1219 //\r
1220 Status = StrHexToUintnS (Pointer, &End, &Uintn);\r
1221 if (RETURN_ERROR (Status) || End - Pointer > 4) {\r
1222 //\r
1223 // Number of hexadecimal digit characters is no more than 4.\r
1224 //\r
1225 return RETURN_UNSUPPORTED;\r
1226 }\r
1227 Pointer = End;\r
1228 //\r
1229 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
1230 //\r
5b0ce08a 1231 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
36396ea2
RN
1232 LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);\r
1233 LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;\r
1234 AddressIndex += 2;\r
1235 } else {\r
1236 //\r
1237 // Get P, then exit the loop.\r
1238 //\r
1239 Status = StrDecimalToUintnS (Pointer, &End, &Uintn);\r
1240 if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {\r
1241 //\r
1242 // Prefix length should not exceed 128.\r
1243 //\r
1244 return RETURN_UNSUPPORTED;\r
1245 }\r
1246 LocalPrefixLength = (UINT8) Uintn;\r
1247 Pointer = End;\r
1248 break;\r
1249 }\r
1250 }\r
1251\r
1252 //\r
1253 // Skip ':' or "/"\r
1254 //\r
1255 if (*Pointer == L'/') {\r
1256 ExpectPrefix = TRUE;\r
1257 } else if (*Pointer == L':') {\r
1258 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1259 //\r
1260 // Meet additional ":" after all 8 16-bit address\r
1261 //\r
1262 break;\r
1263 }\r
1264 } else {\r
1265 //\r
1266 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
1267 //\r
1268 break;\r
1269 }\r
1270 Pointer++;\r
1271 }\r
1272\r
1273 if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||\r
1274 (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))\r
1275 ) {\r
1276 //\r
1277 // Full length of address shall not have compressing zeros.\r
1278 // Non-full length of address shall have compressing zeros.\r
1279 //\r
1280 return RETURN_UNSUPPORTED;\r
1281 }\r
1282 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
1283 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
1284 if (AddressIndex > CompressStart) {\r
1285 CopyMem (\r
1286 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
1287 &LocalAddress.Addr[CompressStart],\r
1288 AddressIndex - CompressStart\r
1289 );\r
1290 }\r
36396ea2
RN
1291\r
1292 if (PrefixLength != NULL) {\r
1293 *PrefixLength = LocalPrefixLength;\r
1294 }\r
1295 if (EndPointer != NULL) {\r
1296 *EndPointer = (CHAR16 *) Pointer;\r
1297 }\r
1298\r
1299 return RETURN_SUCCESS;\r
1300}\r
1301\r
1302/**\r
1303 Convert a Null-terminated Unicode string to IPv4 address and prefix length.\r
1304\r
1305 This function outputs a value of type IPv4_ADDRESS and may output a value\r
1306 of type UINT8 by interpreting the contents of the Unicode string specified\r
1307 by String. The format of the input Unicode string String is as follows:\r
1308\r
1309 D.D.D.D[/P]\r
1310\r
1311 D and P are decimal digit characters in the range [0-9]. The running zero in\r
1312 the beginning of D and P will be ignored. /P is optional.\r
1313\r
1314 When /P is not in the String, the function stops at the first character that is\r
1315 not a valid decimal digit character after four D's are converted.\r
1316\r
1317 When /P is in the String, the function stops at the first character that is not\r
1318 a valid decimal digit character after P is converted.\r
1319\r
1320 If String is NULL, then ASSERT().\r
1321\r
1322 If Address is NULL, then ASSERT().\r
1323\r
1324 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1325\r
1326 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
1327 PcdMaximumUnicodeStringLength Unicode characters, not including the\r
1328 Null-terminator, then ASSERT().\r
1329\r
1330 If EndPointer is not NULL and Address is translated from String, a pointer\r
1331 to the character that stopped the scan is stored at the location pointed to\r
1332 by EndPointer.\r
1333\r
1334 @param String Pointer to a Null-terminated Unicode string.\r
1335 @param EndPointer Pointer to character that stops scan.\r
1336 @param Address Pointer to the converted IPv4 address.\r
1337 @param PrefixLength Pointer to the converted IPv4 address prefix\r
1338 length. MAX_UINT8 is returned when /P is\r
1339 not in the String.\r
1340\r
1341 @retval RETURN_SUCCESS Address is translated from String.\r
1342 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1343 If Data is NULL.\r
1344 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
1345 If any decimal number converted from D\r
1346 exceeds 255.\r
1347 If the decimal number converted from P\r
1348 exceeds 32.\r
1349\r
1350**/\r
1351RETURN_STATUS\r
1352EFIAPI\r
1353StrToIpv4Address (\r
1354 IN CONST CHAR16 *String,\r
1355 OUT CHAR16 **EndPointer, OPTIONAL\r
1356 OUT IPv4_ADDRESS *Address,\r
1357 OUT UINT8 *PrefixLength OPTIONAL\r
1358 )\r
1359{\r
1360 RETURN_STATUS Status;\r
1361 UINTN AddressIndex;\r
1362 UINTN Uintn;\r
1363 IPv4_ADDRESS LocalAddress;\r
1364 UINT8 LocalPrefixLength;\r
1365 CHAR16 *Pointer;\r
1366\r
1367 LocalPrefixLength = MAX_UINT8;\r
1368\r
1369 ASSERT (((UINTN) String & BIT0) == 0);\r
1370\r
1371 //\r
1372 // 1. None of String or Guid shall be a null pointer.\r
1373 //\r
1374 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1375 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
1376\r
1377 for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
1378 if (!InternalIsDecimalDigitCharacter (*Pointer)) {\r
1379 //\r
1380 // D or P contains invalid characters.\r
1381 //\r
1382 break;\r
1383 }\r
1384\r
1385 //\r
1386 // Get D or P.\r
1387 //\r
1388 Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);\r
1389 if (RETURN_ERROR (Status)) {\r
1390 return RETURN_UNSUPPORTED;\r
1391 }\r
1392 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1393 //\r
1394 // It's P.\r
1395 //\r
1396 if (Uintn > 32) {\r
1397 return RETURN_UNSUPPORTED;\r
1398 }\r
1399 LocalPrefixLength = (UINT8) Uintn;\r
1400 } else {\r
1401 //\r
1402 // It's D.\r
1403 //\r
1404 if (Uintn > MAX_UINT8) {\r
1405 return RETURN_UNSUPPORTED;\r
1406 }\r
1407 LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;\r
1408 AddressIndex++;\r
1409 }\r
1410\r
1411 //\r
1412 // Check the '.' or '/', depending on the AddressIndex.\r
1413 //\r
1414 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
1415 if (*Pointer == L'/') {\r
1416 //\r
1417 // '/P' is in the String.\r
1418 // Skip "/" and get P in next loop.\r
1419 //\r
1420 Pointer++;\r
1421 } else {\r
1422 //\r
1423 // '/P' is not in the String.\r
1424 //\r
1425 break;\r
1426 }\r
1427 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1428 if (*Pointer == L'.') {\r
1429 //\r
1430 // D should be followed by '.'\r
1431 //\r
1432 Pointer++;\r
1433 } else {\r
1434 return RETURN_UNSUPPORTED;\r
1435 }\r
1436 }\r
1437 }\r
1438\r
1439 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
1440 return RETURN_UNSUPPORTED;\r
1441 }\r
1442\r
1443 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
1444 if (PrefixLength != NULL) {\r
1445 *PrefixLength = LocalPrefixLength;\r
1446 }\r
1447 if (EndPointer != NULL) {\r
1448 *EndPointer = Pointer;\r
1449 }\r
1450\r
1451 return RETURN_SUCCESS;\r
1452}\r
1453\r
1454/**\r
1455 Convert a Null-terminated Unicode GUID string to a value of type\r
1456 EFI_GUID.\r
1457\r
1458 This function outputs a GUID value by interpreting the contents of\r
1459 the Unicode string specified by String. The format of the input\r
1460 Unicode string String consists of 36 characters, as follows:\r
1461\r
1462 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
1463\r
1464 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
1465 [A-F], with each pair representing a single byte hexadecimal value.\r
1466\r
1467 The mapping between String and the EFI_GUID structure is as follows:\r
1468 aa Data1[24:31]\r
1469 bb Data1[16:23]\r
1470 cc Data1[8:15]\r
1471 dd Data1[0:7]\r
1472 ee Data2[8:15]\r
1473 ff Data2[0:7]\r
1474 gg Data3[8:15]\r
1475 hh Data3[0:7]\r
1476 ii Data4[0:7]\r
1477 jj Data4[8:15]\r
1478 kk Data4[16:23]\r
1479 ll Data4[24:31]\r
1480 mm Data4[32:39]\r
1481 nn Data4[40:47]\r
1482 oo Data4[48:55]\r
1483 pp Data4[56:63]\r
1484\r
1485 If String is NULL, then ASSERT().\r
1486 If Guid is NULL, then ASSERT().\r
1487 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1488\r
1489 @param String Pointer to a Null-terminated Unicode string.\r
1490 @param Guid Pointer to the converted GUID.\r
1491\r
1492 @retval RETURN_SUCCESS Guid is translated from String.\r
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1494 If Data is NULL.\r
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
1496\r
1497**/\r
1498RETURN_STATUS\r
1499EFIAPI\r
1500StrToGuid (\r
1501 IN CONST CHAR16 *String,\r
1502 OUT GUID *Guid\r
1503 )\r
1504{\r
1505 RETURN_STATUS Status;\r
1506 GUID LocalGuid;\r
1507\r
1508 ASSERT (((UINTN) String & BIT0) == 0);\r
1509\r
1510 //\r
1511 // 1. None of String or Guid shall be a null pointer.\r
1512 //\r
1513 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
1515\r
1516 //\r
1517 // Get aabbccdd in big-endian.\r
1518 //\r
1519 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
1520 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {\r
1521 return RETURN_UNSUPPORTED;\r
1522 }\r
1523 //\r
1524 // Convert big-endian to little-endian.\r
1525 //\r
1526 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
1527 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
1528\r
1529 //\r
1530 // Get eeff in big-endian.\r
1531 //\r
1532 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
1533 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {\r
1534 return RETURN_UNSUPPORTED;\r
1535 }\r
1536 //\r
1537 // Convert big-endian to little-endian.\r
1538 //\r
1539 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
1540 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
1541\r
1542 //\r
1543 // Get gghh in big-endian.\r
1544 //\r
1545 Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
1546 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {\r
1547 return RETURN_UNSUPPORTED;\r
1548 }\r
1549 //\r
1550 // Convert big-endian to little-endian.\r
1551 //\r
1552 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
1553 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
1554\r
1555 //\r
1556 // Get iijj.\r
1557 //\r
1558 Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
1559 if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {\r
1560 return RETURN_UNSUPPORTED;\r
1561 }\r
1562 String += 2 * 2 + 1;\r
1563\r
1564 //\r
1565 // Get kkllmmnnoopp.\r
1566 //\r
1567 Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
1568 if (RETURN_ERROR (Status)) {\r
1569 return RETURN_UNSUPPORTED;\r
1570 }\r
1571\r
1572 CopyGuid (Guid, &LocalGuid);\r
1573 return RETURN_SUCCESS;\r
1574}\r
1575\r
1576/**\r
1577 Convert a Null-terminated Unicode hexadecimal string to a byte array.\r
1578\r
1579 This function outputs a byte array by interpreting the contents of\r
1580 the Unicode string specified by String in hexadecimal format. The format of\r
1581 the input Unicode string String is:\r
1582\r
1583 [XX]*\r
1584\r
1585 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
1586 The function decodes every two hexadecimal digit characters as one byte. The\r
1587 decoding stops after Length of characters and outputs Buffer containing\r
1588 (Length / 2) bytes.\r
1589\r
1590 If String is not aligned in a 16-bit boundary, then ASSERT().\r
1591\r
1592 If String is NULL, then ASSERT().\r
1593\r
1594 If Buffer is NULL, then ASSERT().\r
1595\r
1596 If Length is not multiple of 2, then ASSERT().\r
1597\r
1598 If PcdMaximumUnicodeStringLength is not zero and Length is greater than\r
1599 PcdMaximumUnicodeStringLength, then ASSERT().\r
1600\r
1601 If MaxBufferSize is less than (Length / 2), then ASSERT().\r
1602\r
1603 @param String Pointer to a Null-terminated Unicode string.\r
1604 @param Length The number of Unicode characters to decode.\r
1605 @param Buffer Pointer to the converted bytes array.\r
1606 @param MaxBufferSize The maximum size of Buffer.\r
1607\r
1608 @retval RETURN_SUCCESS Buffer is translated from String.\r
1609 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
1610 If Data is NULL.\r
1611 If Length is not multiple of 2.\r
1612 If PcdMaximumUnicodeStringLength is not zero,\r
1613 and Length is greater than\r
1614 PcdMaximumUnicodeStringLength.\r
1615 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
1616 a character that is not valid hexadecimal\r
1617 digit characters, or a Null-terminator.\r
1618 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
1619**/\r
1620RETURN_STATUS\r
1621EFIAPI\r
1622StrHexToBytes (\r
1623 IN CONST CHAR16 *String,\r
1624 IN UINTN Length,\r
1625 OUT UINT8 *Buffer,\r
1626 IN UINTN MaxBufferSize\r
1627 )\r
1628{\r
1629 UINTN Index;\r
1630\r
1631 ASSERT (((UINTN) String & BIT0) == 0);\r
1632\r
1633 //\r
1634 // 1. None of String or Buffer shall be a null pointer.\r
1635 //\r
1636 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
1637 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
1638\r
1639 //\r
1640 // 2. Length shall not be greater than RSIZE_MAX.\r
1641 //\r
1642 if (RSIZE_MAX != 0) {\r
1643 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1644 }\r
1645\r
1646 //\r
1647 // 3. Length shall not be odd.\r
1648 //\r
1649 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
1650\r
1651 //\r
1652 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
1653 //\r
1654 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
1655\r
1656 //\r
1657 // 5. String shall not contains invalid hexadecimal digits.\r
1658 //\r
1659 for (Index = 0; Index < Length; Index++) {\r
1660 if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {\r
1661 break;\r
1662 }\r
1663 }\r
1664 if (Index != Length) {\r
1665 return RETURN_UNSUPPORTED;\r
1666 }\r
1667\r
1668 //\r
1669 // Convert the hex string to bytes.\r
1670 //\r
1671 for(Index = 0; Index < Length; Index++) {\r
1672\r
1673 //\r
1674 // For even characters, write the upper nibble for each buffer byte,\r
1675 // and for even characters, the lower nibble.\r
1676 //\r
1677 if ((Index & BIT0) == 0) {\r
1678 Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;\r
1679 } else {\r
1680 Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);\r
1681 }\r
1682 }\r
1683 return RETURN_SUCCESS;\r
1684}\r
1685\r
c058d59f
JY
1686/**\r
1687 Returns the length of a Null-terminated Ascii string.\r
1688\r
328f84b1
JY
1689 This function is similar as strlen_s defined in C11.\r
1690\r
c058d59f
JY
1691 @param String A pointer to a Null-terminated Ascii string.\r
1692 @param MaxSize The maximum number of Destination Ascii\r
1693 char, including terminating null char.\r
1694\r
1695 @retval 0 If String is NULL.\r
1696 @retval MaxSize If there is no null character in the first MaxSize characters of String.\r
1697 @return The number of characters that percede the terminating null character.\r
1698\r
1699**/\r
1700UINTN\r
1701EFIAPI\r
1702AsciiStrnLenS (\r
1703 IN CONST CHAR8 *String,\r
1704 IN UINTN MaxSize\r
1705 )\r
1706{\r
1707 UINTN Length;\r
1708\r
1709 //\r
cb867499 1710 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.\r
c058d59f 1711 //\r
cb867499 1712 if ((String == NULL) || (MaxSize == 0)) {\r
c058d59f
JY
1713 return 0;\r
1714 }\r
1715\r
1716 //\r
1717 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the\r
1718 // terminating null character. If there is no null character in the first MaxSize characters of\r
1719 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall\r
1720 // be accessed by AsciiStrnLenS.\r
1721 //\r
c07c517c
HW
1722 Length = 0;\r
1723 while (String[Length] != 0) {\r
1724 if (Length >= MaxSize - 1) {\r
1725 return MaxSize;\r
1726 }\r
1727 Length++;\r
c058d59f
JY
1728 }\r
1729 return Length;\r
1730}\r
1731\r
b590e43a
HW
1732/**\r
1733 Returns the size of a Null-terminated Ascii string in bytes, including the\r
1734 Null terminator.\r
1735\r
1736 This function returns the size of the Null-terminated Ascii string specified\r
1737 by String in bytes, including the Null terminator.\r
1738\r
1739 @param String A pointer to a Null-terminated Ascii string.\r
1740 @param MaxSize The maximum number of Destination Ascii\r
1741 char, including the Null terminator.\r
1742\r
1743 @retval 0 If String is NULL.\r
1744 @retval (sizeof (CHAR8) * (MaxSize + 1))\r
1745 If there is no Null terminator in the first MaxSize characters of\r
1746 String.\r
1747 @return The size of the Null-terminated Ascii string in bytes, including the\r
1748 Null terminator.\r
1749\r
1750**/\r
1751UINTN\r
1752EFIAPI\r
1753AsciiStrnSizeS (\r
1754 IN CONST CHAR8 *String,\r
1755 IN UINTN MaxSize\r
1756 )\r
1757{\r
1758 //\r
1759 // If String is a null pointer, then the AsciiStrnSizeS function returns\r
1760 // zero.\r
1761 //\r
1762 if (String == NULL) {\r
1763 return 0;\r
1764 }\r
1765\r
1766 //\r
1767 // Otherwise, the AsciiStrnSizeS function returns the size of the\r
1768 // Null-terminated Ascii string in bytes, including the Null terminator. If\r
1769 // there is no Null terminator in the first MaxSize characters of String,\r
1770 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a\r
1771 // consistent map with the AsciiStrnLenS function.\r
1772 //\r
1773 return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String);\r
1774}\r
1775\r
c058d59f
JY
1776/**\r
1777 Copies the string pointed to by Source (including the terminating null char)\r
1778 to the array pointed to by Destination.\r
1779\r
328f84b1
JY
1780 This function is similar as strcpy_s defined in C11.\r
1781\r
0e93edbb
JY
1782 If an error would be returned, then the function will also ASSERT().\r
1783\r
328f84b1
JY
1784 If an error is returned, then the Destination is unmodified.\r
1785\r
c058d59f
JY
1786 @param Destination A pointer to a Null-terminated Ascii string.\r
1787 @param DestMax The maximum number of Destination Ascii\r
1788 char, including terminating null char.\r
1789 @param Source A pointer to a Null-terminated Ascii string.\r
1790\r
1791 @retval RETURN_SUCCESS String is copied.\r
1792 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
1793 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1794 If Source is NULL.\r
1795 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1796 and DestMax is greater than\r
c058d59f
JY
1797 PcdMaximumAsciiStringLength.\r
1798 If DestMax is 0.\r
1799 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1800**/\r
1801RETURN_STATUS\r
1802EFIAPI\r
1803AsciiStrCpyS (\r
1804 OUT CHAR8 *Destination,\r
1805 IN UINTN DestMax,\r
1806 IN CONST CHAR8 *Source\r
1807 )\r
1808{\r
1809 UINTN SourceLen;\r
973f8862 1810\r
c058d59f
JY
1811 //\r
1812 // 1. Neither Destination nor Source shall be a null pointer.\r
1813 //\r
1814 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1815 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1816\r
1817 //\r
1818 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1819 //\r
1820 if (ASCII_RSIZE_MAX != 0) {\r
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1822 }\r
1823\r
1824 //\r
1825 // 3. DestMax shall not equal zero.\r
1826 //\r
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1828\r
1829 //\r
1830 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1831 //\r
1832 SourceLen = AsciiStrnLenS (Source, DestMax);\r
1833 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1834\r
1835 //\r
1836 // 5. Copying shall not take place between objects that overlap.\r
1837 //\r
1838 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1839\r
1840 //\r
1841 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating\r
1842 // null character) into the array pointed to by Destination.\r
1843 //\r
1844 while (*Source != 0) {\r
1845 *(Destination++) = *(Source++);\r
1846 }\r
1847 *Destination = 0;\r
1848\r
1849 return RETURN_SUCCESS;\r
1850}\r
1851\r
1852/**\r
1853 Copies not more than Length successive char from the string pointed to by\r
1854 Source to the array pointed to by Destination. If no null char is copied from\r
1855 Source, then Destination[Length] is always set to null.\r
1856\r
328f84b1
JY
1857 This function is similar as strncpy_s defined in C11.\r
1858\r
0e93edbb
JY
1859 If an error would be returned, then the function will also ASSERT().\r
1860\r
328f84b1
JY
1861 If an error is returned, then the Destination is unmodified.\r
1862\r
c058d59f
JY
1863 @param Destination A pointer to a Null-terminated Ascii string.\r
1864 @param DestMax The maximum number of Destination Ascii\r
1865 char, including terminating null char.\r
1866 @param Source A pointer to a Null-terminated Ascii string.\r
1867 @param Length The maximum number of Ascii characters to copy.\r
1868\r
1869 @retval RETURN_SUCCESS String is copied.\r
973f8862 1870 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
c058d59f
JY
1871 MIN(StrLen(Source), Length).\r
1872 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1873 If Source is NULL.\r
1874 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1875 and DestMax is greater than\r
c058d59f
JY
1876 PcdMaximumAsciiStringLength.\r
1877 If DestMax is 0.\r
1878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1879**/\r
1880RETURN_STATUS\r
1881EFIAPI\r
1882AsciiStrnCpyS (\r
1883 OUT CHAR8 *Destination,\r
1884 IN UINTN DestMax,\r
1885 IN CONST CHAR8 *Source,\r
1886 IN UINTN Length\r
1887 )\r
1888{\r
1889 UINTN SourceLen;\r
1890\r
1891 //\r
1892 // 1. Neither Destination nor Source shall be a null pointer.\r
1893 //\r
1894 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1895 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1896\r
1897 //\r
1898 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX\r
1899 //\r
1900 if (ASCII_RSIZE_MAX != 0) {\r
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1902 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1903 }\r
1904\r
1905 //\r
1906 // 3. DestMax shall not equal zero.\r
1907 //\r
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
1909\r
1910 //\r
1911 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
1912 //\r
56658c22 1913 SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length));\r
c058d59f
JY
1914 if (Length >= DestMax) {\r
1915 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
1916 }\r
1917\r
1918 //\r
1919 // 5. Copying shall not take place between objects that overlap.\r
1920 //\r
1921 if (SourceLen > Length) {\r
1922 SourceLen = Length;\r
1923 }\r
1924 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
1925\r
1926 //\r
1927 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that\r
1928 // follow a null character are not copied) from the array pointed to by Source to the array\r
1929 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null\r
1930 // character.\r
1931 //\r
56658c22 1932 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
1933 *(Destination++) = *(Source++);\r
1934 SourceLen--;\r
1935 }\r
1936 *Destination = 0;\r
1937\r
1938 return RETURN_SUCCESS;\r
1939}\r
1940\r
1941/**\r
1942 Appends a copy of the string pointed to by Source (including the terminating\r
1943 null char) to the end of the string pointed to by Destination.\r
1944\r
328f84b1
JY
1945 This function is similar as strcat_s defined in C11.\r
1946\r
0e93edbb
JY
1947 If an error would be returned, then the function will also ASSERT().\r
1948\r
328f84b1
JY
1949 If an error is returned, then the Destination is unmodified.\r
1950\r
c058d59f
JY
1951 @param Destination A pointer to a Null-terminated Ascii string.\r
1952 @param DestMax The maximum number of Destination Ascii\r
1953 char, including terminating null char.\r
1954 @param Source A pointer to a Null-terminated Ascii string.\r
1955\r
1956 @retval RETURN_SUCCESS String is appended.\r
973f8862 1957 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
c058d59f
JY
1958 StrLen(Destination).\r
1959 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
1960 greater than StrLen(Source).\r
1961 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
1962 If Source is NULL.\r
1963 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 1964 and DestMax is greater than\r
c058d59f
JY
1965 PcdMaximumAsciiStringLength.\r
1966 If DestMax is 0.\r
1967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
1968**/\r
1969RETURN_STATUS\r
1970EFIAPI\r
1971AsciiStrCatS (\r
1972 IN OUT CHAR8 *Destination,\r
1973 IN UINTN DestMax,\r
1974 IN CONST CHAR8 *Source\r
1975 )\r
1976{\r
1977 UINTN DestLen;\r
1978 UINTN CopyLen;\r
1979 UINTN SourceLen;\r
973f8862 1980\r
c058d59f
JY
1981 //\r
1982 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.\r
1983 //\r
1984 DestLen = AsciiStrnLenS (Destination, DestMax);\r
1985 CopyLen = DestMax - DestLen;\r
1986\r
1987 //\r
1988 // 1. Neither Destination nor Source shall be a null pointer.\r
1989 //\r
1990 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
1991 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
1992\r
1993 //\r
1994 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.\r
1995 //\r
1996 if (ASCII_RSIZE_MAX != 0) {\r
1997 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
1998 }\r
1999\r
2000 //\r
2001 // 3. DestMax shall not equal zero.\r
2002 //\r
2003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2004\r
2005 //\r
2006 // 4. CopyLen shall not equal zero.\r
2007 //\r
2008 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
2009\r
2010 //\r
2011 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
2012 //\r
2013 SourceLen = AsciiStrnLenS (Source, CopyLen);\r
2014 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2015\r
2016 //\r
2017 // 6. Copying shall not take place between objects that overlap.\r
2018 //\r
2019 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2020\r
2021 //\r
2022 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the\r
2023 // terminating null character) to the end of the string pointed to by Destination. The initial character\r
2024 // from Source overwrites the null character at the end of Destination.\r
2025 //\r
2026 Destination = Destination + DestLen;\r
2027 while (*Source != 0) {\r
2028 *(Destination++) = *(Source++);\r
2029 }\r
2030 *Destination = 0;\r
2031\r
2032 return RETURN_SUCCESS;\r
2033}\r
2034\r
2035/**\r
2036 Appends not more than Length successive char from the string pointed to by\r
2037 Source to the end of the string pointed to by Destination. If no null char is\r
2038 copied from Source, then Destination[StrLen(Destination) + Length] is always\r
2039 set to null.\r
2040\r
328f84b1
JY
2041 This function is similar as strncat_s defined in C11.\r
2042\r
0e93edbb
JY
2043 If an error would be returned, then the function will also ASSERT().\r
2044\r
328f84b1
JY
2045 If an error is returned, then the Destination is unmodified.\r
2046\r
c058d59f
JY
2047 @param Destination A pointer to a Null-terminated Ascii string.\r
2048 @param DestMax The maximum number of Destination Ascii\r
2049 char, including terminating null char.\r
2050 @param Source A pointer to a Null-terminated Ascii string.\r
2051 @param Length The maximum number of Ascii characters to copy.\r
2052\r
2053 @retval RETURN_SUCCESS String is appended.\r
2054 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than\r
2055 StrLen(Destination).\r
2056 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT\r
2057 greater than MIN(StrLen(Source), Length).\r
2058 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2059 If Source is NULL.\r
2060 If PcdMaximumAsciiStringLength is not zero,\r
973f8862 2061 and DestMax is greater than\r
c058d59f
JY
2062 PcdMaximumAsciiStringLength.\r
2063 If DestMax is 0.\r
2064 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2065**/\r
2066RETURN_STATUS\r
2067EFIAPI\r
2068AsciiStrnCatS (\r
2069 IN OUT CHAR8 *Destination,\r
2070 IN UINTN DestMax,\r
2071 IN CONST CHAR8 *Source,\r
2072 IN UINTN Length\r
2073 )\r
2074{\r
2075 UINTN DestLen;\r
2076 UINTN CopyLen;\r
2077 UINTN SourceLen;\r
973f8862 2078\r
c058d59f
JY
2079 //\r
2080 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.\r
2081 //\r
2082 DestLen = AsciiStrnLenS (Destination, DestMax);\r
2083 CopyLen = DestMax - DestLen;\r
2084\r
2085 //\r
2086 // 1. Neither Destination nor Source shall be a null pointer.\r
2087 //\r
2088 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2089 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2090\r
2091 //\r
2092 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.\r
2093 //\r
2094 if (ASCII_RSIZE_MAX != 0) {\r
2095 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2096 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2097 }\r
2098\r
2099 //\r
2100 // 3. DestMax shall not equal zero.\r
2101 //\r
2102 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2103\r
2104 //\r
2105 // 4. CopyLen shall not equal zero.\r
2106 //\r
2107 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);\r
2108\r
2109 //\r
2110 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).\r
2111 //\r
56658c22 2112 SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length));\r
c058d59f
JY
2113 if (Length >= CopyLen) {\r
2114 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2115 }\r
2116\r
2117 //\r
2118 // 6. Copying shall not take place between objects that overlap.\r
2119 //\r
2120 if (SourceLen > Length) {\r
2121 SourceLen = Length;\r
2122 }\r
2123 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2124\r
2125 //\r
2126 // The AsciiStrnCatS function appends not more than Length successive characters (characters\r
2127 // that follow a null character are not copied) from the array pointed to by Source to the end of\r
2128 // the string pointed to by Destination. The initial character from Source overwrites the null character at\r
2129 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to\r
2130 // a null character.\r
2131 //\r
2132 Destination = Destination + DestLen;\r
56658c22 2133 while ((SourceLen > 0) && (*Source != 0)) {\r
c058d59f
JY
2134 *(Destination++) = *(Source++);\r
2135 SourceLen--;\r
2136 }\r
2137 *Destination = 0;\r
2138\r
d8af3301
HW
2139 return RETURN_SUCCESS;\r
2140}\r
2141\r
2142/**\r
2143 Convert a Null-terminated Ascii decimal string to a value of type UINTN.\r
2144\r
2145 This function outputs a value of type UINTN by interpreting the contents of\r
2146 the Ascii string specified by String as a decimal number. The format of the\r
2147 input Ascii string String is:\r
2148\r
2149 [spaces] [decimal digits].\r
2150\r
2151 The valid decimal digit character is in the range [0-9]. The function will\r
2152 ignore the pad space, which includes spaces or tab characters, before\r
2153 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2154 be ignored. Then, the function stops at the first character that is a not a\r
2155 valid decimal character or a Null-terminator, whichever one comes first.\r
2156\r
2157 If String is NULL, then ASSERT().\r
2158 If Data is NULL, then ASSERT().\r
2159 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
2160 PcdMaximumAsciiStringLength Ascii characters, not including the\r
2161 Null-terminator, then ASSERT().\r
2162\r
2163 If String has no valid decimal digits in the above format, then 0 is stored\r
2164 at the location pointed to by Data.\r
2165 If the number represented by String exceeds the range defined by UINTN, then\r
2166 MAX_UINTN is stored at the location pointed to by Data.\r
2167\r
2168 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2169 is stored at the location pointed to by EndPointer. If String has no valid\r
2170 decimal digits right after the optional pad spaces, the value of String is\r
2171 stored at the location pointed to by EndPointer.\r
2172\r
2173 @param String Pointer to a Null-terminated Ascii string.\r
2174 @param EndPointer Pointer to character that stops scan.\r
2175 @param Data Pointer to the converted value.\r
2176\r
2177 @retval RETURN_SUCCESS Value is translated from String.\r
2178 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2179 If Data is NULL.\r
2180 If PcdMaximumAsciiStringLength is not zero,\r
2181 and String contains more than\r
2182 PcdMaximumAsciiStringLength Ascii\r
2183 characters, not including the\r
2184 Null-terminator.\r
2185 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2186 the range defined by UINTN.\r
2187\r
2188**/\r
2189RETURN_STATUS\r
2190EFIAPI\r
2191AsciiStrDecimalToUintnS (\r
2192 IN CONST CHAR8 *String,\r
2193 OUT CHAR8 **EndPointer, OPTIONAL\r
2194 OUT UINTN *Data\r
2195 )\r
2196{\r
2197 //\r
2198 // 1. Neither String nor Data shall be a null pointer.\r
2199 //\r
2200 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2201 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2202\r
2203 //\r
2204 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2205 //\r
2206 if (ASCII_RSIZE_MAX != 0) {\r
2207 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2208 }\r
2209\r
2210 if (EndPointer != NULL) {\r
2211 *EndPointer = (CHAR8 *) String;\r
2212 }\r
2213\r
2214 //\r
2215 // Ignore the pad spaces (space or tab)\r
2216 //\r
2217 while ((*String == ' ') || (*String == '\t')) {\r
2218 String++;\r
2219 }\r
2220\r
2221 //\r
2222 // Ignore leading Zeros after the spaces\r
2223 //\r
2224 while (*String == '0') {\r
2225 String++;\r
2226 }\r
2227\r
2228 *Data = 0;\r
2229\r
2230 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2231 //\r
2232 // If the number represented by String overflows according to the range\r
2233 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2234 // RETURN_UNSUPPORTED is returned.\r
2235 //\r
2236 if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) {\r
2237 *Data = MAX_UINTN;\r
2238 if (EndPointer != NULL) {\r
2239 *EndPointer = (CHAR8 *) String;\r
2240 }\r
2241 return RETURN_UNSUPPORTED;\r
2242 }\r
2243\r
2244 *Data = *Data * 10 + (*String - '0');\r
2245 String++;\r
2246 }\r
2247\r
2248 if (EndPointer != NULL) {\r
2249 *EndPointer = (CHAR8 *) String;\r
2250 }\r
2251 return RETURN_SUCCESS;\r
2252}\r
2253\r
2254/**\r
2255 Convert a Null-terminated Ascii decimal string to a value of type UINT64.\r
2256\r
2257 This function outputs a value of type UINT64 by interpreting the contents of\r
2258 the Ascii string specified by String as a decimal number. The format of the\r
2259 input Ascii string String is:\r
2260\r
2261 [spaces] [decimal digits].\r
2262\r
2263 The valid decimal digit character is in the range [0-9]. The function will\r
2264 ignore the pad space, which includes spaces or tab characters, before\r
2265 [decimal digits]. The running zero in the beginning of [decimal digits] will\r
2266 be ignored. Then, the function stops at the first character that is a not a\r
2267 valid decimal character or a Null-terminator, whichever one comes first.\r
2268\r
2269 If String is NULL, then ASSERT().\r
2270 If Data is NULL, then ASSERT().\r
2271 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
2272 PcdMaximumAsciiStringLength Ascii characters, not including the\r
2273 Null-terminator, then ASSERT().\r
2274\r
2275 If String has no valid decimal digits in the above format, then 0 is stored\r
2276 at the location pointed to by Data.\r
2277 If the number represented by String exceeds the range defined by UINT64, then\r
2278 MAX_UINT64 is stored at the location pointed to by Data.\r
2279\r
2280 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2281 is stored at the location pointed to by EndPointer. If String has no valid\r
2282 decimal digits right after the optional pad spaces, the value of String is\r
2283 stored at the location pointed to by EndPointer.\r
2284\r
2285 @param String Pointer to a Null-terminated Ascii string.\r
2286 @param EndPointer Pointer to character that stops scan.\r
2287 @param Data Pointer to the converted value.\r
2288\r
2289 @retval RETURN_SUCCESS Value is translated from String.\r
2290 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2291 If Data is NULL.\r
2292 If PcdMaximumAsciiStringLength is not zero,\r
2293 and String contains more than\r
2294 PcdMaximumAsciiStringLength Ascii\r
2295 characters, not including the\r
2296 Null-terminator.\r
2297 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2298 the range defined by UINT64.\r
2299\r
2300**/\r
2301RETURN_STATUS\r
2302EFIAPI\r
2303AsciiStrDecimalToUint64S (\r
2304 IN CONST CHAR8 *String,\r
2305 OUT CHAR8 **EndPointer, OPTIONAL\r
2306 OUT UINT64 *Data\r
2307 )\r
2308{\r
2309 //\r
2310 // 1. Neither String nor Data shall be a null pointer.\r
2311 //\r
2312 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2313 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2314\r
2315 //\r
2316 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2317 //\r
2318 if (ASCII_RSIZE_MAX != 0) {\r
2319 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2320 }\r
2321\r
2322 if (EndPointer != NULL) {\r
2323 *EndPointer = (CHAR8 *) String;\r
2324 }\r
2325\r
2326 //\r
2327 // Ignore the pad spaces (space or tab)\r
2328 //\r
2329 while ((*String == ' ') || (*String == '\t')) {\r
2330 String++;\r
2331 }\r
2332\r
2333 //\r
2334 // Ignore leading Zeros after the spaces\r
2335 //\r
2336 while (*String == '0') {\r
2337 String++;\r
2338 }\r
2339\r
2340 *Data = 0;\r
2341\r
2342 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
2343 //\r
2344 // If the number represented by String overflows according to the range\r
2345 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2346 // RETURN_UNSUPPORTED is returned.\r
2347 //\r
2348 if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) {\r
2349 *Data = MAX_UINT64;\r
2350 if (EndPointer != NULL) {\r
2351 *EndPointer = (CHAR8 *) String;\r
2352 }\r
2353 return RETURN_UNSUPPORTED;\r
2354 }\r
2355\r
2356 *Data = MultU64x32 (*Data, 10) + (*String - '0');\r
2357 String++;\r
2358 }\r
2359\r
2360 if (EndPointer != NULL) {\r
2361 *EndPointer = (CHAR8 *) String;\r
2362 }\r
2363 return RETURN_SUCCESS;\r
2364}\r
2365\r
2366/**\r
2367 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.\r
2368\r
2369 This function outputs a value of type UINTN by interpreting the contents of\r
2370 the Ascii string specified by String as a hexadecimal number. The format of\r
2371 the input Ascii string String is:\r
2372\r
2373 [spaces][zeros][x][hexadecimal digits].\r
2374\r
2375 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2376 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2377 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2378 function will ignore the pad space, which includes spaces or tab characters,\r
2379 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2380 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2381 the first valid hexadecimal digit. Then, the function stops at the first\r
2382 character that is a not a valid hexadecimal character or Null-terminator,\r
2383 whichever on comes first.\r
2384\r
2385 If String is NULL, then ASSERT().\r
2386 If Data is NULL, then ASSERT().\r
2387 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
2388 PcdMaximumAsciiStringLength Ascii characters, not including the\r
2389 Null-terminator, then ASSERT().\r
2390\r
2391 If String has no valid hexadecimal digits in the above format, then 0 is\r
2392 stored at the location pointed to by Data.\r
2393 If the number represented by String exceeds the range defined by UINTN, then\r
2394 MAX_UINTN is stored at the location pointed to by Data.\r
2395\r
2396 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2397 is stored at the location pointed to by EndPointer. If String has no valid\r
2398 hexadecimal digits right after the optional pad spaces, the value of String\r
2399 is stored at the location pointed to by EndPointer.\r
2400\r
2401 @param String Pointer to a Null-terminated Ascii string.\r
2402 @param EndPointer Pointer to character that stops scan.\r
2403 @param Data Pointer to the converted value.\r
2404\r
2405 @retval RETURN_SUCCESS Value is translated from String.\r
2406 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2407 If Data is NULL.\r
2408 If PcdMaximumAsciiStringLength is not zero,\r
2409 and String contains more than\r
2410 PcdMaximumAsciiStringLength Ascii\r
2411 characters, not including the\r
2412 Null-terminator.\r
2413 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2414 the range defined by UINTN.\r
2415\r
2416**/\r
2417RETURN_STATUS\r
2418EFIAPI\r
2419AsciiStrHexToUintnS (\r
2420 IN CONST CHAR8 *String,\r
2421 OUT CHAR8 **EndPointer, OPTIONAL\r
2422 OUT UINTN *Data\r
2423 )\r
2424{\r
2425 //\r
2426 // 1. Neither String nor Data shall be a null pointer.\r
2427 //\r
2428 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2429 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2430\r
2431 //\r
2432 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2433 //\r
2434 if (ASCII_RSIZE_MAX != 0) {\r
2435 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2436 }\r
2437\r
2438 if (EndPointer != NULL) {\r
2439 *EndPointer = (CHAR8 *) String;\r
2440 }\r
2441\r
2442 //\r
2443 // Ignore the pad spaces (space or tab)\r
2444 //\r
2445 while ((*String == ' ') || (*String == '\t')) {\r
2446 String++;\r
2447 }\r
2448\r
2449 //\r
2450 // Ignore leading Zeros after the spaces\r
2451 //\r
2452 while (*String == '0') {\r
2453 String++;\r
2454 }\r
2455\r
5dbfa01e 2456 if (AsciiCharToUpper (*String) == 'X') {\r
d8af3301
HW
2457 if (*(String - 1) != '0') {\r
2458 *Data = 0;\r
2459 return RETURN_SUCCESS;\r
2460 }\r
2461 //\r
2462 // Skip the 'X'\r
2463 //\r
2464 String++;\r
2465 }\r
2466\r
2467 *Data = 0;\r
2468\r
2469 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2470 //\r
2471 // If the number represented by String overflows according to the range\r
2472 // defined by UINTN, then MAX_UINTN is stored in *Data and\r
2473 // RETURN_UNSUPPORTED is returned.\r
2474 //\r
2475 if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) {\r
2476 *Data = MAX_UINTN;\r
2477 if (EndPointer != NULL) {\r
2478 *EndPointer = (CHAR8 *) String;\r
2479 }\r
2480 return RETURN_UNSUPPORTED;\r
2481 }\r
2482\r
2483 *Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String);\r
2484 String++;\r
2485 }\r
2486\r
2487 if (EndPointer != NULL) {\r
2488 *EndPointer = (CHAR8 *) String;\r
2489 }\r
2490 return RETURN_SUCCESS;\r
2491}\r
2492\r
2493/**\r
2494 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.\r
2495\r
2496 This function outputs a value of type UINT64 by interpreting the contents of\r
2497 the Ascii string specified by String as a hexadecimal number. The format of\r
2498 the input Ascii string String is:\r
2499\r
2500 [spaces][zeros][x][hexadecimal digits].\r
2501\r
2502 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
2503 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If\r
2504 "x" appears in the input string, it must be prefixed with at least one 0. The\r
2505 function will ignore the pad space, which includes spaces or tab characters,\r
2506 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or\r
2507 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or\r
2508 the first valid hexadecimal digit. Then, the function stops at the first\r
2509 character that is a not a valid hexadecimal character or Null-terminator,\r
2510 whichever on comes first.\r
2511\r
2512 If String is NULL, then ASSERT().\r
2513 If Data is NULL, then ASSERT().\r
2514 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
2515 PcdMaximumAsciiStringLength Ascii characters, not including the\r
2516 Null-terminator, then ASSERT().\r
2517\r
2518 If String has no valid hexadecimal digits in the above format, then 0 is\r
2519 stored at the location pointed to by Data.\r
2520 If the number represented by String exceeds the range defined by UINT64, then\r
2521 MAX_UINT64 is stored at the location pointed to by Data.\r
2522\r
2523 If EndPointer is not NULL, a pointer to the character that stopped the scan\r
2524 is stored at the location pointed to by EndPointer. If String has no valid\r
2525 hexadecimal digits right after the optional pad spaces, the value of String\r
2526 is stored at the location pointed to by EndPointer.\r
2527\r
2528 @param String Pointer to a Null-terminated Ascii string.\r
2529 @param EndPointer Pointer to character that stops scan.\r
2530 @param Data Pointer to the converted value.\r
2531\r
2532 @retval RETURN_SUCCESS Value is translated from String.\r
2533 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
2534 If Data is NULL.\r
2535 If PcdMaximumAsciiStringLength is not zero,\r
2536 and String contains more than\r
2537 PcdMaximumAsciiStringLength Ascii\r
2538 characters, not including the\r
2539 Null-terminator.\r
2540 @retval RETURN_UNSUPPORTED If the number represented by String exceeds\r
2541 the range defined by UINT64.\r
2542\r
2543**/\r
2544RETURN_STATUS\r
2545EFIAPI\r
2546AsciiStrHexToUint64S (\r
2547 IN CONST CHAR8 *String,\r
2548 OUT CHAR8 **EndPointer, OPTIONAL\r
2549 OUT UINT64 *Data\r
2550 )\r
2551{\r
2552 //\r
2553 // 1. Neither String nor Data shall be a null pointer.\r
2554 //\r
2555 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
2556 SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);\r
2557\r
2558 //\r
2559 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.\r
2560 //\r
2561 if (ASCII_RSIZE_MAX != 0) {\r
2562 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2563 }\r
2564\r
2565 if (EndPointer != NULL) {\r
2566 *EndPointer = (CHAR8 *) String;\r
2567 }\r
2568\r
2569 //\r
2570 // Ignore the pad spaces (space or tab)\r
2571 //\r
2572 while ((*String == ' ') || (*String == '\t')) {\r
2573 String++;\r
2574 }\r
2575\r
2576 //\r
2577 // Ignore leading Zeros after the spaces\r
2578 //\r
2579 while (*String == '0') {\r
2580 String++;\r
2581 }\r
2582\r
5dbfa01e 2583 if (AsciiCharToUpper (*String) == 'X') {\r
d8af3301
HW
2584 if (*(String - 1) != '0') {\r
2585 *Data = 0;\r
2586 return RETURN_SUCCESS;\r
2587 }\r
2588 //\r
2589 // Skip the 'X'\r
2590 //\r
2591 String++;\r
2592 }\r
2593\r
2594 *Data = 0;\r
2595\r
2596 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
2597 //\r
2598 // If the number represented by String overflows according to the range\r
2599 // defined by UINT64, then MAX_UINT64 is stored in *Data and\r
2600 // RETURN_UNSUPPORTED is returned.\r
2601 //\r
2602 if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) {\r
2603 *Data = MAX_UINT64;\r
2604 if (EndPointer != NULL) {\r
2605 *EndPointer = (CHAR8 *) String;\r
2606 }\r
2607 return RETURN_UNSUPPORTED;\r
2608 }\r
2609\r
2610 *Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String);\r
2611 String++;\r
2612 }\r
2613\r
2614 if (EndPointer != NULL) {\r
2615 *EndPointer = (CHAR8 *) String;\r
2616 }\r
c058d59f
JY
2617 return RETURN_SUCCESS;\r
2618}\r
3ab41b7a
JY
2619\r
2620/**\r
2621 Convert a Null-terminated Unicode string to a Null-terminated\r
2622 ASCII string.\r
2623\r
2624 This function is similar to AsciiStrCpyS.\r
2625\r
2626 This function converts the content of the Unicode string Source\r
2627 to the ASCII string Destination by copying the lower 8 bits of\r
2628 each Unicode character. The function terminates the ASCII string\r
2629 Destination by appending a Null-terminator character at the end.\r
2630\r
2631 The caller is responsible to make sure Destination points to a buffer with size\r
2632 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.\r
2633\r
2634 If any Unicode characters in Source contain non-zero value in\r
2635 the upper 8 bits, then ASSERT().\r
2636\r
2637 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
2638 If an error would be returned, then the function will also ASSERT().\r
2639\r
2640 If an error is returned, then the Destination is unmodified.\r
2641\r
2642 @param Source The pointer to a Null-terminated Unicode string.\r
2643 @param Destination The pointer to a Null-terminated ASCII string.\r
2644 @param DestMax The maximum number of Destination Ascii\r
2645 char, including terminating null char.\r
2646\r
2647 @retval RETURN_SUCCESS String is converted.\r
2648 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2649 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2650 If Source is NULL.\r
2651 If PcdMaximumAsciiStringLength is not zero,\r
2652 and DestMax is greater than\r
2653 PcdMaximumAsciiStringLength.\r
2654 If PcdMaximumUnicodeStringLength is not zero,\r
2655 and DestMax is greater than\r
2656 PcdMaximumUnicodeStringLength.\r
2657 If DestMax is 0.\r
2658 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2659\r
2660**/\r
2661RETURN_STATUS\r
2662EFIAPI\r
2663UnicodeStrToAsciiStrS (\r
2664 IN CONST CHAR16 *Source,\r
2665 OUT CHAR8 *Destination,\r
2666 IN UINTN DestMax\r
2667 )\r
2668{\r
2669 UINTN SourceLen;\r
2670\r
2671 ASSERT (((UINTN) Source & BIT0) == 0);\r
2672\r
2673 //\r
2674 // 1. Neither Destination nor Source shall be a null pointer.\r
2675 //\r
2676 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2677 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2678\r
2679 //\r
2680 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.\r
2681 //\r
2682 if (ASCII_RSIZE_MAX != 0) {\r
2683 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2684 }\r
2685 if (RSIZE_MAX != 0) {\r
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2687 }\r
2688\r
2689 //\r
2690 // 3. DestMax shall not equal zero.\r
2691 //\r
2692 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2693\r
2694 //\r
2695 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).\r
2696 //\r
2697 SourceLen = StrnLenS (Source, DestMax);\r
2698 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2699\r
2700 //\r
2701 // 5. Copying shall not take place between objects that overlap.\r
2702 //\r
2703 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
2704\r
2705 //\r
2706 // convert string\r
2707 //\r
2708 while (*Source != '\0') {\r
2709 //\r
2710 // If any Unicode characters in Source contain\r
2711 // non-zero value in the upper 8 bits, then ASSERT().\r
2712 //\r
2713 ASSERT (*Source < 0x100);\r
2714 *(Destination++) = (CHAR8) *(Source++);\r
2715 }\r
2716 *Destination = '\0';\r
2717\r
2718 return RETURN_SUCCESS;\r
2719}\r
2720\r
02263214
HW
2721/**\r
2722 Convert not more than Length successive characters from a Null-terminated\r
2723 Unicode string to a Null-terminated Ascii string. If no null char is copied\r
2724 from Source, then Destination[Length] is always set to null.\r
2725\r
2726 This function converts not more than Length successive characters from the\r
2727 Unicode string Source to the Ascii string Destination by copying the lower 8\r
2728 bits of each Unicode character. The function terminates the Ascii string\r
2729 Destination by appending a Null-terminator character at the end.\r
2730\r
2731 The caller is responsible to make sure Destination points to a buffer with\r
2732 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))\r
2733 in bytes.\r
2734\r
2735 If any Unicode characters in Source contain non-zero value in the upper 8\r
2736 bits, then ASSERT().\r
2737 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
2738 If an error would be returned, then the function will also ASSERT().\r
2739\r
2740 If an error is returned, then Destination and DestinationLength are\r
2741 unmodified.\r
2742\r
2743 @param Source The pointer to a Null-terminated Unicode string.\r
2744 @param Length The maximum number of Unicode characters to\r
2745 convert.\r
2746 @param Destination The pointer to a Null-terminated Ascii string.\r
2747 @param DestMax The maximum number of Destination Ascii char,\r
2748 including terminating null char.\r
2749 @param DestinationLength The number of Unicode characters converted.\r
2750\r
2751 @retval RETURN_SUCCESS String is converted.\r
2752 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2753 If Source is NULL.\r
2754 If DestinationLength is NULL.\r
2755 If PcdMaximumAsciiStringLength is not zero,\r
2756 and Length or DestMax is greater than\r
2757 PcdMaximumAsciiStringLength.\r
2758 If PcdMaximumUnicodeStringLength is not\r
2759 zero, and Length or DestMax is greater than\r
2760 PcdMaximumUnicodeStringLength.\r
2761 If DestMax is 0.\r
2762 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2763 MIN(StrLen(Source), Length).\r
2764 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2765\r
2766**/\r
2767RETURN_STATUS\r
2768EFIAPI\r
2769UnicodeStrnToAsciiStrS (\r
2770 IN CONST CHAR16 *Source,\r
2771 IN UINTN Length,\r
2772 OUT CHAR8 *Destination,\r
2773 IN UINTN DestMax,\r
2774 OUT UINTN *DestinationLength\r
2775 )\r
2776{\r
2777 UINTN SourceLen;\r
2778\r
2779 ASSERT (((UINTN) Source & BIT0) == 0);\r
2780\r
2781 //\r
2782 // 1. None of Destination, Source or DestinationLength shall be a null\r
2783 // pointer.\r
2784 //\r
2785 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2786 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2787 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
2788\r
2789 //\r
2790 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
2791 // RSIZE_MAX.\r
2792 //\r
2793 if (ASCII_RSIZE_MAX != 0) {\r
2794 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2795 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2796 }\r
2797 if (RSIZE_MAX != 0) {\r
2798 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2799 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2800 }\r
2801\r
2802 //\r
2803 // 3. DestMax shall not equal zero.\r
2804 //\r
2805 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2806\r
2807 //\r
2808 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
2809 // StrnLenS(Source, DestMax).\r
2810 //\r
2811 SourceLen = StrnLenS (Source, DestMax);\r
2812 if (Length >= DestMax) {\r
2813 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2814 }\r
2815\r
2816 //\r
2817 // 5. Copying shall not take place between objects that overlap.\r
2818 //\r
2819 if (SourceLen > Length) {\r
2820 SourceLen = Length;\r
2821 }\r
2822 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);\r
2823\r
2824 *DestinationLength = 0;\r
2825\r
2826 //\r
2827 // Convert string\r
2828 //\r
2829 while ((*Source != 0) && (SourceLen > 0)) {\r
2830 //\r
2831 // If any Unicode characters in Source contain non-zero value in the upper\r
2832 // 8 bits, then ASSERT().\r
2833 //\r
2834 ASSERT (*Source < 0x100);\r
2835 *(Destination++) = (CHAR8) *(Source++);\r
2836 SourceLen--;\r
2837 (*DestinationLength)++;\r
2838 }\r
2839 *Destination = 0;\r
2840\r
2841 return RETURN_SUCCESS;\r
2842}\r
3ab41b7a
JY
2843\r
2844/**\r
2845 Convert one Null-terminated ASCII string to a Null-terminated\r
2846 Unicode string.\r
2847\r
2848 This function is similar to StrCpyS.\r
2849\r
2850 This function converts the contents of the ASCII string Source to the Unicode\r
2851 string Destination. The function terminates the Unicode string Destination by\r
2852 appending a Null-terminator character at the end.\r
2853\r
2854 The caller is responsible to make sure Destination points to a buffer with size\r
2855 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
2856\r
2857 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
2858 If an error would be returned, then the function will also ASSERT().\r
2859\r
2860 If an error is returned, then the Destination is unmodified.\r
2861\r
2862 @param Source The pointer to a Null-terminated ASCII string.\r
2863 @param Destination The pointer to a Null-terminated Unicode string.\r
2864 @param DestMax The maximum number of Destination Unicode\r
2865 char, including terminating null char.\r
2866\r
2867 @retval RETURN_SUCCESS String is converted.\r
2868 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).\r
2869 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2870 If Source is NULL.\r
2871 If PcdMaximumUnicodeStringLength is not zero,\r
2872 and DestMax is greater than\r
2873 PcdMaximumUnicodeStringLength.\r
2874 If PcdMaximumAsciiStringLength is not zero,\r
2875 and DestMax is greater than\r
2876 PcdMaximumAsciiStringLength.\r
2877 If DestMax is 0.\r
2878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2879\r
2880**/\r
2881RETURN_STATUS\r
2882EFIAPI\r
2883AsciiStrToUnicodeStrS (\r
2884 IN CONST CHAR8 *Source,\r
2885 OUT CHAR16 *Destination,\r
2886 IN UINTN DestMax\r
2887 )\r
2888{\r
2889 UINTN SourceLen;\r
2890\r
2891 ASSERT (((UINTN) Destination & BIT0) == 0);\r
2892\r
2893 //\r
2894 // 1. Neither Destination nor Source shall be a null pointer.\r
2895 //\r
2896 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2897 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2898\r
2899 //\r
2900 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.\r
2901 //\r
2902 if (RSIZE_MAX != 0) {\r
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2904 }\r
2905 if (ASCII_RSIZE_MAX != 0) {\r
2906 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
2907 }\r
2908\r
2909 //\r
2910 // 3. DestMax shall not equal zero.\r
2911 //\r
2912 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
2913\r
2914 //\r
2915 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).\r
2916 //\r
2917 SourceLen = AsciiStrnLenS (Source, DestMax);\r
2918 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
2919\r
2920 //\r
2921 // 5. Copying shall not take place between objects that overlap.\r
2922 //\r
2923 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
2924\r
2925 //\r
2926 // Convert string\r
2927 //\r
2928 while (*Source != '\0') {\r
0dab5770 2929 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
3ab41b7a
JY
2930 }\r
2931 *Destination = '\0';\r
2932\r
2933 return RETURN_SUCCESS;\r
2934}\r
02263214
HW
2935\r
2936/**\r
2937 Convert not more than Length successive characters from a Null-terminated\r
2938 Ascii string to a Null-terminated Unicode string. If no null char is copied\r
2939 from Source, then Destination[Length] is always set to null.\r
2940\r
2941 This function converts not more than Length successive characters from the\r
2942 Ascii string Source to the Unicode string Destination. The function\r
2943 terminates the Unicode string Destination by appending a Null-terminator\r
2944 character at the end.\r
2945\r
2946 The caller is responsible to make sure Destination points to a buffer with\r
2947 size not smaller than\r
2948 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.\r
2949\r
2950 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
2951 If an error would be returned, then the function will also ASSERT().\r
2952\r
2953 If an error is returned, then Destination and DestinationLength are\r
2954 unmodified.\r
2955\r
2956 @param Source The pointer to a Null-terminated Ascii string.\r
2957 @param Length The maximum number of Ascii characters to convert.\r
2958 @param Destination The pointer to a Null-terminated Unicode string.\r
2959 @param DestMax The maximum number of Destination Unicode char,\r
2960 including terminating null char.\r
2961 @param DestinationLength The number of Ascii characters converted.\r
2962\r
2963 @retval RETURN_SUCCESS String is converted.\r
2964 @retval RETURN_INVALID_PARAMETER If Destination is NULL.\r
2965 If Source is NULL.\r
2966 If DestinationLength is NULL.\r
2967 If PcdMaximumUnicodeStringLength is not\r
2968 zero, and Length or DestMax is greater than\r
2969 PcdMaximumUnicodeStringLength.\r
2970 If PcdMaximumAsciiStringLength is not zero,\r
2971 and Length or DestMax is greater than\r
2972 PcdMaximumAsciiStringLength.\r
2973 If DestMax is 0.\r
2974 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than\r
2975 MIN(AsciiStrLen(Source), Length).\r
2976 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.\r
2977\r
2978**/\r
2979RETURN_STATUS\r
2980EFIAPI\r
2981AsciiStrnToUnicodeStrS (\r
2982 IN CONST CHAR8 *Source,\r
2983 IN UINTN Length,\r
2984 OUT CHAR16 *Destination,\r
2985 IN UINTN DestMax,\r
2986 OUT UINTN *DestinationLength\r
2987 )\r
2988{\r
2989 UINTN SourceLen;\r
2990\r
2991 ASSERT (((UINTN) Destination & BIT0) == 0);\r
2992\r
2993 //\r
2994 // 1. None of Destination, Source or DestinationLength shall be a null\r
2995 // pointer.\r
2996 //\r
2997 SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);\r
2998 SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);\r
2999 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength != NULL), RETURN_INVALID_PARAMETER);\r
3000\r
3001 //\r
3002 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or\r
3003 // RSIZE_MAX.\r
3004 //\r
3005 if (RSIZE_MAX != 0) {\r
3006 SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3007 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3008 }\r
3009 if (ASCII_RSIZE_MAX != 0) {\r
3010 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3011 SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3012 }\r
3013\r
3014 //\r
3015 // 3. DestMax shall not equal zero.\r
3016 //\r
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);\r
3018\r
3019 //\r
3020 // 4. If Length is not less than DestMax, then DestMax shall be greater than\r
3021 // AsciiStrnLenS(Source, DestMax).\r
3022 //\r
3023 SourceLen = AsciiStrnLenS (Source, DestMax);\r
3024 if (Length >= DestMax) {\r
3025 SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);\r
3026 }\r
3027\r
3028 //\r
3029 // 5. Copying shall not take place between objects that overlap.\r
3030 //\r
3031 if (SourceLen > Length) {\r
3032 SourceLen = Length;\r
3033 }\r
3034 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);\r
3035\r
3036 *DestinationLength = 0;\r
3037\r
3038 //\r
3039 // Convert string\r
3040 //\r
3041 while ((*Source != 0) && (SourceLen > 0)) {\r
0dab5770 3042 *(Destination++) = (CHAR16)(UINT8)*(Source++);\r
02263214
HW
3043 SourceLen--;\r
3044 (*DestinationLength)++;\r
3045 }\r
3046 *Destination = 0;\r
3047\r
3048 return RETURN_SUCCESS;\r
3049}\r
fb4dd857
RN
3050\r
3051/**\r
3052 Convert a Null-terminated ASCII string to IPv6 address and prefix length.\r
3053\r
3054 This function outputs a value of type IPv6_ADDRESS and may output a value\r
3055 of type UINT8 by interpreting the contents of the ASCII string specified\r
3056 by String. The format of the input ASCII string String is as follows:\r
3057\r
3058 X:X:X:X:X:X:X:X[/P]\r
3059\r
3060 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and\r
3061 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low\r
3062 memory address and high byte is stored in high memory address. P contains decimal\r
3063 digit characters in the range [0-9]. The running zero in the beginning of P will\r
3064 be ignored. /P is optional.\r
3065\r
3066 When /P is not in the String, the function stops at the first character that is\r
3067 not a valid hexadecimal digit character after eight X's are converted.\r
3068\r
3069 When /P is in the String, the function stops at the first character that is not\r
3070 a valid decimal digit character after P is converted.\r
3071\r
3072 "::" can be used to compress one or more groups of X when X contains only 0.\r
3073 The "::" can only appear once in the String.\r
3074\r
3075 If String is NULL, then ASSERT().\r
3076\r
3077 If Address is NULL, then ASSERT().\r
3078\r
3079 If EndPointer is not NULL and Address is translated from String, a pointer\r
3080 to the character that stopped the scan is stored at the location pointed to\r
3081 by EndPointer.\r
3082\r
3083 @param String Pointer to a Null-terminated ASCII string.\r
3084 @param EndPointer Pointer to character that stops scan.\r
3085 @param Address Pointer to the converted IPv6 address.\r
3086 @param PrefixLength Pointer to the converted IPv6 address prefix\r
3087 length. MAX_UINT8 is returned when /P is\r
3088 not in the String.\r
3089\r
3090 @retval RETURN_SUCCESS Address is translated from String.\r
3091 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3092 If Data is NULL.\r
3093 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal\r
3094 digit characters.\r
3095 If String contains "::" and number of X\r
3096 is not less than 8.\r
3097 If P starts with character that is not a\r
3098 valid decimal digit character.\r
3099 If the decimal number converted from P\r
3100 exceeds 128.\r
3101\r
3102**/\r
3103RETURN_STATUS\r
3104EFIAPI\r
3105AsciiStrToIpv6Address (\r
3106 IN CONST CHAR8 *String,\r
3107 OUT CHAR8 **EndPointer, OPTIONAL\r
3108 OUT IPv6_ADDRESS *Address,\r
3109 OUT UINT8 *PrefixLength OPTIONAL\r
3110 )\r
3111{\r
3112 RETURN_STATUS Status;\r
3113 UINTN AddressIndex;\r
3114 UINTN Uintn;\r
3115 IPv6_ADDRESS LocalAddress;\r
3116 UINT8 LocalPrefixLength;\r
3117 CONST CHAR8 *Pointer;\r
3118 CHAR8 *End;\r
3119 UINTN CompressStart;\r
3120 BOOLEAN ExpectPrefix;\r
3121\r
3122 LocalPrefixLength = MAX_UINT8;\r
3123 CompressStart = ARRAY_SIZE (Address->Addr);\r
3124 ExpectPrefix = FALSE;\r
3125\r
3126 //\r
3127 // None of String or Address shall be a null pointer.\r
3128 //\r
3129 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3130 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3131\r
3132 for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
3133 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3134 if (*Pointer != ':') {\r
3135 //\r
3136 // ":" or "/" should be followed by digit characters.\r
3137 //\r
3138 return RETURN_UNSUPPORTED;\r
3139 }\r
3140\r
3141 //\r
3142 // Meet second ":" after previous ":" or "/"\r
3143 // or meet first ":" in the beginning of String.\r
3144 //\r
3145 if (ExpectPrefix) {\r
3146 //\r
3147 // ":" shall not be after "/"\r
3148 //\r
3149 return RETURN_UNSUPPORTED;\r
3150 }\r
3151\r
3152 if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3153 //\r
3154 // "::" can only appear once.\r
3155 // "::" can only appear when address is not full length.\r
3156 //\r
3157 return RETURN_UNSUPPORTED;\r
3158 } else {\r
3159 //\r
3160 // Remember the start of zero compressing.\r
3161 //\r
3162 CompressStart = AddressIndex;\r
3163 Pointer++;\r
3164\r
3165 if (CompressStart == 0) {\r
3166 if (*Pointer != ':') {\r
3167 //\r
3168 // Single ":" shall not be in the beginning of String.\r
3169 //\r
3170 return RETURN_UNSUPPORTED;\r
3171 }\r
3172 Pointer++;\r
3173 }\r
3174 }\r
3175 }\r
3176\r
3177 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {\r
3178 if (*Pointer == '/') {\r
3179 //\r
3180 // Might be optional "/P" after "::".\r
3181 //\r
3182 if (CompressStart != AddressIndex) {\r
3183 return RETURN_UNSUPPORTED;\r
3184 }\r
3185 } else {\r
3186 break;\r
3187 }\r
3188 } else {\r
3189 if (!ExpectPrefix) {\r
3190 //\r
3191 // Get X.\r
3192 //\r
3193 Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);\r
3194 if (RETURN_ERROR (Status) || End - Pointer > 4) {\r
3195 //\r
3196 // Number of hexadecimal digit characters is no more than 4.\r
3197 //\r
3198 return RETURN_UNSUPPORTED;\r
3199 }\r
3200 Pointer = End;\r
3201 //\r
3202 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.\r
3203 //\r
5b0ce08a 3204 ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));\r
fb4dd857
RN
3205 LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);\r
3206 LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;\r
3207 AddressIndex += 2;\r
3208 } else {\r
3209 //\r
3210 // Get P, then exit the loop.\r
3211 //\r
3212 Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);\r
3213 if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {\r
3214 //\r
3215 // Prefix length should not exceed 128.\r
3216 //\r
3217 return RETURN_UNSUPPORTED;\r
3218 }\r
3219 LocalPrefixLength = (UINT8) Uintn;\r
3220 Pointer = End;\r
3221 break;\r
3222 }\r
3223 }\r
3224\r
3225 //\r
3226 // Skip ':' or "/"\r
3227 //\r
3228 if (*Pointer == '/') {\r
3229 ExpectPrefix = TRUE;\r
3230 } else if (*Pointer == ':') {\r
3231 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3232 //\r
3233 // Meet additional ":" after all 8 16-bit address\r
3234 //\r
3235 break;\r
3236 }\r
3237 } else {\r
3238 //\r
3239 // Meet other character that is not "/" or ":" after all 8 16-bit address\r
3240 //\r
3241 break;\r
3242 }\r
3243 Pointer++;\r
3244 }\r
3245\r
3246 if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||\r
3247 (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))\r
3248 ) {\r
3249 //\r
3250 // Full length of address shall not have compressing zeros.\r
3251 // Non-full length of address shall have compressing zeros.\r
3252 //\r
3253 return RETURN_UNSUPPORTED;\r
3254 }\r
3255 CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);\r
3256 ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);\r
5b0ce08a
RN
3257 if (AddressIndex > CompressStart) {\r
3258 CopyMem (\r
3259 &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],\r
3260 &LocalAddress.Addr[CompressStart],\r
3261 AddressIndex - CompressStart\r
973f8862
HW
3262 );\r
3263\r
5b0ce08a 3264 }\r
fb4dd857
RN
3265\r
3266 if (PrefixLength != NULL) {\r
3267 *PrefixLength = LocalPrefixLength;\r
3268 }\r
3269 if (EndPointer != NULL) {\r
3270 *EndPointer = (CHAR8 *) Pointer;\r
3271 }\r
3272\r
3273 return RETURN_SUCCESS;\r
3274}\r
3275\r
3276/**\r
3277 Convert a Null-terminated ASCII string to IPv4 address and prefix length.\r
3278\r
3279 This function outputs a value of type IPv4_ADDRESS and may output a value\r
3280 of type UINT8 by interpreting the contents of the ASCII string specified\r
3281 by String. The format of the input ASCII string String is as follows:\r
3282\r
3283 D.D.D.D[/P]\r
3284\r
3285 D and P are decimal digit characters in the range [0-9]. The running zero in\r
3286 the beginning of D and P will be ignored. /P is optional.\r
3287\r
3288 When /P is not in the String, the function stops at the first character that is\r
3289 not a valid decimal digit character after four D's are converted.\r
3290\r
3291 When /P is in the String, the function stops at the first character that is not\r
3292 a valid decimal digit character after P is converted.\r
3293\r
3294 If String is NULL, then ASSERT().\r
3295\r
3296 If Address is NULL, then ASSERT().\r
3297\r
3298 If EndPointer is not NULL and Address is translated from String, a pointer\r
3299 to the character that stopped the scan is stored at the location pointed to\r
3300 by EndPointer.\r
3301\r
3302 @param String Pointer to a Null-terminated ASCII string.\r
3303 @param EndPointer Pointer to character that stops scan.\r
3304 @param Address Pointer to the converted IPv4 address.\r
3305 @param PrefixLength Pointer to the converted IPv4 address prefix\r
3306 length. MAX_UINT8 is returned when /P is\r
3307 not in the String.\r
3308\r
3309 @retval RETURN_SUCCESS Address is translated from String.\r
3310 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3311 If Data is NULL.\r
3312 @retval RETURN_UNSUPPORTED If String is not in the correct format.\r
3313 If any decimal number converted from D\r
3314 exceeds 255.\r
3315 If the decimal number converted from P\r
3316 exceeds 32.\r
3317\r
3318**/\r
3319RETURN_STATUS\r
3320EFIAPI\r
3321AsciiStrToIpv4Address (\r
3322 IN CONST CHAR8 *String,\r
3323 OUT CHAR8 **EndPointer, OPTIONAL\r
3324 OUT IPv4_ADDRESS *Address,\r
3325 OUT UINT8 *PrefixLength OPTIONAL\r
3326 )\r
3327{\r
3328 RETURN_STATUS Status;\r
3329 UINTN AddressIndex;\r
3330 UINTN Uintn;\r
3331 IPv4_ADDRESS LocalAddress;\r
3332 UINT8 LocalPrefixLength;\r
3333 CHAR8 *Pointer;\r
3334\r
3335 LocalPrefixLength = MAX_UINT8;\r
3336\r
3337 //\r
3338 // None of String or Address shall be a null pointer.\r
3339 //\r
3340 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3341 SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);\r
3342\r
3343 for (Pointer = (CHAR8 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {\r
3344 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {\r
3345 //\r
3346 // D or P contains invalid characters.\r
3347 //\r
3348 break;\r
3349 }\r
3350\r
3351 //\r
3352 // Get D or P.\r
3353 //\r
3354 Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *) Pointer, &Pointer, &Uintn);\r
3355 if (RETURN_ERROR (Status)) {\r
3356 return RETURN_UNSUPPORTED;\r
3357 }\r
3358 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3359 //\r
3360 // It's P.\r
3361 //\r
3362 if (Uintn > 32) {\r
3363 return RETURN_UNSUPPORTED;\r
3364 }\r
3365 LocalPrefixLength = (UINT8) Uintn;\r
3366 } else {\r
3367 //\r
3368 // It's D.\r
3369 //\r
3370 if (Uintn > MAX_UINT8) {\r
3371 return RETURN_UNSUPPORTED;\r
3372 }\r
3373 LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;\r
3374 AddressIndex++;\r
3375 }\r
3376\r
3377 //\r
3378 // Check the '.' or '/', depending on the AddressIndex.\r
3379 //\r
3380 if (AddressIndex == ARRAY_SIZE (Address->Addr)) {\r
3381 if (*Pointer == '/') {\r
3382 //\r
3383 // '/P' is in the String.\r
3384 // Skip "/" and get P in next loop.\r
3385 //\r
3386 Pointer++;\r
3387 } else {\r
3388 //\r
3389 // '/P' is not in the String.\r
3390 //\r
3391 break;\r
3392 }\r
3393 } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3394 if (*Pointer == '.') {\r
3395 //\r
3396 // D should be followed by '.'\r
3397 //\r
3398 Pointer++;\r
3399 } else {\r
3400 return RETURN_UNSUPPORTED;\r
3401 }\r
3402 }\r
3403 }\r
3404\r
3405 if (AddressIndex < ARRAY_SIZE (Address->Addr)) {\r
3406 return RETURN_UNSUPPORTED;\r
3407 }\r
3408\r
3409 CopyMem (Address, &LocalAddress, sizeof (*Address));\r
3410 if (PrefixLength != NULL) {\r
3411 *PrefixLength = LocalPrefixLength;\r
3412 }\r
3413 if (EndPointer != NULL) {\r
3414 *EndPointer = Pointer;\r
3415 }\r
3416\r
3417 return RETURN_SUCCESS;\r
3418}\r
3419\r
3420/**\r
3421 Convert a Null-terminated ASCII GUID string to a value of type\r
3422 EFI_GUID.\r
3423\r
3424 This function outputs a GUID value by interpreting the contents of\r
3425 the ASCII string specified by String. The format of the input\r
3426 ASCII string String consists of 36 characters, as follows:\r
3427\r
3428 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\r
3429\r
3430 The pairs aa - pp are two characters in the range [0-9], [a-f] and\r
3431 [A-F], with each pair representing a single byte hexadecimal value.\r
3432\r
3433 The mapping between String and the EFI_GUID structure is as follows:\r
3434 aa Data1[24:31]\r
3435 bb Data1[16:23]\r
3436 cc Data1[8:15]\r
3437 dd Data1[0:7]\r
3438 ee Data2[8:15]\r
3439 ff Data2[0:7]\r
3440 gg Data3[8:15]\r
3441 hh Data3[0:7]\r
3442 ii Data4[0:7]\r
3443 jj Data4[8:15]\r
3444 kk Data4[16:23]\r
3445 ll Data4[24:31]\r
3446 mm Data4[32:39]\r
3447 nn Data4[40:47]\r
3448 oo Data4[48:55]\r
3449 pp Data4[56:63]\r
3450\r
3451 If String is NULL, then ASSERT().\r
3452 If Guid is NULL, then ASSERT().\r
3453\r
3454 @param String Pointer to a Null-terminated ASCII string.\r
3455 @param Guid Pointer to the converted GUID.\r
3456\r
3457 @retval RETURN_SUCCESS Guid is translated from String.\r
3458 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3459 If Data is NULL.\r
3460 @retval RETURN_UNSUPPORTED If String is not as the above format.\r
3461\r
3462**/\r
3463RETURN_STATUS\r
3464EFIAPI\r
3465AsciiStrToGuid (\r
3466 IN CONST CHAR8 *String,\r
3467 OUT GUID *Guid\r
3468 )\r
3469{\r
3470 RETURN_STATUS Status;\r
3471 GUID LocalGuid;\r
3472\r
3473 //\r
3474 // None of String or Guid shall be a null pointer.\r
3475 //\r
3476 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3477 SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);\r
3478\r
3479 //\r
3480 // Get aabbccdd in big-endian.\r
3481 //\r
3482 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));\r
3483 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != '-') {\r
3484 return RETURN_UNSUPPORTED;\r
3485 }\r
3486 //\r
3487 // Convert big-endian to little-endian.\r
3488 //\r
3489 LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);\r
3490 String += 2 * sizeof (LocalGuid.Data1) + 1;\r
3491\r
3492 //\r
3493 // Get eeff in big-endian.\r
3494 //\r
3495 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));\r
3496 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != '-') {\r
3497 return RETURN_UNSUPPORTED;\r
3498 }\r
3499 //\r
3500 // Convert big-endian to little-endian.\r
3501 //\r
3502 LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);\r
3503 String += 2 * sizeof (LocalGuid.Data2) + 1;\r
3504\r
3505 //\r
3506 // Get gghh in big-endian.\r
3507 //\r
3508 Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));\r
3509 if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != '-') {\r
3510 return RETURN_UNSUPPORTED;\r
3511 }\r
3512 //\r
3513 // Convert big-endian to little-endian.\r
3514 //\r
3515 LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);\r
3516 String += 2 * sizeof (LocalGuid.Data3) + 1;\r
3517\r
3518 //\r
3519 // Get iijj.\r
3520 //\r
3521 Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);\r
3522 if (RETURN_ERROR (Status) || String[2 * 2] != '-') {\r
3523 return RETURN_UNSUPPORTED;\r
3524 }\r
3525 String += 2 * 2 + 1;\r
3526\r
3527 //\r
3528 // Get kkllmmnnoopp.\r
3529 //\r
3530 Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);\r
3531 if (RETURN_ERROR (Status)) {\r
3532 return RETURN_UNSUPPORTED;\r
3533 }\r
3534\r
3535 CopyGuid (Guid, &LocalGuid);\r
3536 return RETURN_SUCCESS;\r
3537}\r
3538\r
3539/**\r
3540 Convert a Null-terminated ASCII hexadecimal string to a byte array.\r
3541\r
3542 This function outputs a byte array by interpreting the contents of\r
3543 the ASCII string specified by String in hexadecimal format. The format of\r
3544 the input ASCII string String is:\r
3545\r
3546 [XX]*\r
3547\r
3548 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].\r
3549 The function decodes every two hexadecimal digit characters as one byte. The\r
3550 decoding stops after Length of characters and outputs Buffer containing\r
3551 (Length / 2) bytes.\r
3552\r
3553 If String is NULL, then ASSERT().\r
3554\r
3555 If Buffer is NULL, then ASSERT().\r
3556\r
3557 If Length is not multiple of 2, then ASSERT().\r
3558\r
3559 If PcdMaximumAsciiStringLength is not zero and Length is greater than\r
3560 PcdMaximumAsciiStringLength, then ASSERT().\r
3561\r
3562 If MaxBufferSize is less than (Length / 2), then ASSERT().\r
3563\r
3564 @param String Pointer to a Null-terminated ASCII string.\r
3565 @param Length The number of ASCII characters to decode.\r
3566 @param Buffer Pointer to the converted bytes array.\r
3567 @param MaxBufferSize The maximum size of Buffer.\r
3568\r
3569 @retval RETURN_SUCCESS Buffer is translated from String.\r
3570 @retval RETURN_INVALID_PARAMETER If String is NULL.\r
3571 If Data is NULL.\r
3572 If Length is not multiple of 2.\r
3573 If PcdMaximumAsciiStringLength is not zero,\r
3574 and Length is greater than\r
3575 PcdMaximumAsciiStringLength.\r
3576 @retval RETURN_UNSUPPORTED If Length of characters from String contain\r
3577 a character that is not valid hexadecimal\r
3578 digit characters, or a Null-terminator.\r
3579 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).\r
3580**/\r
3581RETURN_STATUS\r
3582EFIAPI\r
3583AsciiStrHexToBytes (\r
3584 IN CONST CHAR8 *String,\r
3585 IN UINTN Length,\r
3586 OUT UINT8 *Buffer,\r
3587 IN UINTN MaxBufferSize\r
3588 )\r
3589{\r
3590 UINTN Index;\r
3591\r
3592 //\r
3593 // 1. None of String or Buffer shall be a null pointer.\r
3594 //\r
3595 SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);\r
3596 SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
3597\r
3598 //\r
3599 // 2. Length shall not be greater than ASCII_RSIZE_MAX.\r
3600 //\r
3601 if (ASCII_RSIZE_MAX != 0) {\r
3602 SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
3603 }\r
3604\r
3605 //\r
3606 // 3. Length shall not be odd.\r
3607 //\r
3608 SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);\r
3609\r
3610 //\r
3611 // 4. MaxBufferSize shall equal to or greater than Length / 2.\r
3612 //\r
3613 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);\r
3614\r
3615 //\r
3616 // 5. String shall not contains invalid hexadecimal digits.\r
3617 //\r
3618 for (Index = 0; Index < Length; Index++) {\r
3619 if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {\r
3620 break;\r
3621 }\r
3622 }\r
3623 if (Index != Length) {\r
3624 return RETURN_UNSUPPORTED;\r
3625 }\r
3626\r
3627 //\r
3628 // Convert the hex string to bytes.\r
3629 //\r
3630 for(Index = 0; Index < Length; Index++) {\r
3631\r
3632 //\r
3633 // For even characters, write the upper nibble for each buffer byte,\r
3634 // and for even characters, the lower nibble.\r
3635 //\r
3636 if ((Index & BIT0) == 0) {\r
3637 Buffer[Index / 2] = (UINT8) InternalAsciiHexCharToUintn (String[Index]) << 4;\r
3638 } else {\r
3639 Buffer[Index / 2] |= (UINT8) InternalAsciiHexCharToUintn (String[Index]);\r
3640 }\r
3641 }\r
3642 return RETURN_SUCCESS;\r
3643}\r
3644\r