Coverage Report

Created: 2024-10-17 06:29

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