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