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