public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib
@ 2017-02-22  4:50 Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 01/11] MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h Ruiyu Ni
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel

The patch set adds StrToGuid/StrHexToBytes/StrToIPv4Address
/StrToIPv6Address and the accordingly ASCII versioins to BaseLib.
It also changes all existing consumers to use the new APIs.

Ruiyu Ni (11):
  MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h
  MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure
  SignedCapsulePkg/IniParsing: Rename StrToGuid to avoid link failure
  MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
  MdePkg/BaseLib: Add AsciiStrToGuid/HexToBytes/ToIpv[4/6]Address
  MdePkg/UefiDevicePathLib: Use BaseLib string conversion services
  MdeModulePkg/CapsuleApp: Use StrToGuid in BaseLib
  SecurityPkg/SecureBootConfigDxe: Use StrToGuid in BaseLib
  ShellPkg/Debug1CommandLib: Use StrToGuid/StrHexToBytes in BaseLib
  SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in BaseLib
  MdeModulePkg/NetLib: Use StrToIpv4/6Address in BaseLib

 MdeModulePkg/Application/CapsuleApp/AppSupport.c   |  140 +--
 MdeModulePkg/Application/CapsuleApp/CapsuleApp.c   |   25 +-
 MdeModulePkg/Include/Library/NetLib.h              |    5 +-
 MdeModulePkg/Library/DxeNetLib/DxeNetLib.c         |  382 +-----
 MdePkg/Include/Base.h                              |   16 +-
 MdePkg/Include/Library/BaseLib.h                   |  455 ++++++++
 MdePkg/Include/Uefi/UefiBaseType.h                 |   10 +-
 MdePkg/Library/BaseLib/SafeString.c                | 1214 ++++++++++++++++++++
 .../Library/UefiDevicePathLib/DevicePathFromText.c |  213 +---
 .../SecureBootConfigDxe/SecureBootConfigImpl.c     |   11 +-
 .../SecureBootConfigDxe/SecureBootConfigImpl.h     |   22 +-
 .../SecureBootConfigDxe/SecureBootConfigMisc.c     |  141 +--
 .../Library/UefiShellDebug1CommandsLib/DmpStore.c  |    5 +-
 .../Library/UefiShellDebug1CommandsLib/SetVar.c    |   10 +-
 .../UefiShellDebug1CommandsLib.c                   |  119 +-
 .../UefiShellDebug1CommandsLib.h                   |   32 +-
 .../Library/IniParsingLib/IniParsingLib.c          |  143 +--
 17 files changed, 1751 insertions(+), 1192 deletions(-)

-- 
2.9.0.windows.1



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/11] MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 02/11] MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure Ruiyu Ni
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Since the following patch needs to add API converting string
to IP address in BaseLib, define the IP address as base types
in Base.h.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 MdePkg/Include/Base.h              | 16 +++++++++++++++-
 MdePkg/Include/Uefi/UefiBaseType.h | 10 +++-------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h
index 8f5b919..5b311f6 100644
--- a/MdePkg/Include/Base.h
+++ b/MdePkg/Include/Base.h
@@ -6,7 +6,7 @@
   environment. There are a set of base libraries in the Mde Package that can
   be used to implement base modules.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -265,6 +265,20 @@ typedef struct {
   UINT8   Data4[8];
 } GUID;
 
+///
+/// 4-byte buffer. An IPv4 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[4];
+} IPv4_ADDRESS;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[16];
+} IPv6_ADDRESS;
+
 //
 // 8-bytes unsigned value that represents a physical system address.
 //
diff --git a/MdePkg/Include/Uefi/UefiBaseType.h b/MdePkg/Include/Uefi/UefiBaseType.h
index 84e4dc6..728a047 100644
--- a/MdePkg/Include/Uefi/UefiBaseType.h
+++ b/MdePkg/Include/Uefi/UefiBaseType.h
@@ -1,7 +1,7 @@
 /** @file
   Defines data types and constants introduced in UEFI.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
 Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
 
 This program and the accompanying materials are licensed and made available under 
@@ -87,16 +87,12 @@ typedef struct {
 ///
 /// 4-byte buffer. An IPv4 internet protocol address.
 ///
-typedef struct {
-  UINT8 Addr[4];
-} EFI_IPv4_ADDRESS;
+typedef IPv4_ADDRESS EFI_IPv4_ADDRESS;
 
 ///
 /// 16-byte buffer. An IPv6 internet protocol address.
 ///
-typedef struct {
-  UINT8 Addr[16];
-} EFI_IPv6_ADDRESS;
+typedef IPv6_ADDRESS EFI_IPv6_ADDRESS;
 
 ///
 /// 32-byte buffer containing a network Media Access Control address.
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/11] MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 01/11] MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 03/11] SignedCapsulePkg/IniParsing: " Ruiyu Ni
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Since the next patch will add StrToGuid in BaseLib, renaming the
internal function StrToGuid to DevicePathLibStrToGuid to avoid
link failure.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
index 8a3a470..e2b06a2 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -1,7 +1,7 @@
 /** @file
   DevicePathFromText protocol as defined in the UEFI 2.0 specification.
 
-Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -397,7 +397,7 @@ StrToBuf (
 
 **/
 EFI_STATUS
-StrToGuid (
+DevicePathLibStrToGuid (
   IN  CHAR16   *Str,
   OUT EFI_GUID *Guid
   )
@@ -740,7 +740,7 @@ ConvertFromTextVendor (
                                      (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
                                      );
 
-  StrToGuid (GuidStr, &Vendor->Guid);
+  DevicePathLibStrToGuid (GuidStr, &Vendor->Guid);
   StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
@@ -1453,7 +1453,7 @@ DevPathFromTextInfiniband (
                                             );
 
   InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
-  StrToGuid (GuidStr, &PortGid);
+  DevicePathLibStrToGuid (GuidStr, &PortGid);
   CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
   Strtoi64 (SidStr, &InfiniBand->ServiceId);
   Strtoi64 (TidStr, &InfiniBand->TargetPortId);
@@ -2976,7 +2976,7 @@ DevPathFromTextHD (
     Hd->SignatureType = SIGNATURE_TYPE_GUID;
     Hd->MBRType       = 0x02;
 
-    StrToGuid (SignatureStr, &SignatureGuid);
+    DevicePathLibStrToGuid (SignatureStr, &SignatureGuid);
     CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
   } else {
     Hd->SignatureType = (UINT8) Strtoi (TypeStr);
@@ -3091,7 +3091,7 @@ DevPathFromTextMedia (
                                              (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
                                              );
 
-  StrToGuid (GuidStr, &Media->Protocol);
+  DevicePathLibStrToGuid (GuidStr, &Media->Protocol);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Media;
 }
@@ -3119,7 +3119,7 @@ DevPathFromTextFv (
                                            (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
                                            );
 
-  StrToGuid (GuidStr, &Fv->FvName);
+  DevicePathLibStrToGuid (GuidStr, &Fv->FvName);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
 }
@@ -3147,7 +3147,7 @@ DevPathFromTextFvFile (
                                                     (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
                                                     );
 
-  StrToGuid (GuidStr, &FvFile->FvFileName);
+  DevicePathLibStrToGuid (GuidStr, &FvFile->FvFileName);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
 }
@@ -3219,7 +3219,7 @@ DevPathFromTextRamDisk (
   Strtoi64 (EndingAddrStr, &EndingAddr);
   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
-  StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+  DevicePathLibStrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
 }
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/11] SignedCapsulePkg/IniParsing: Rename StrToGuid to avoid link failure
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 01/11] MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 02/11] MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address Ruiyu Ni
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jiewen Yao

Since the next patch will add AsciiStrToGuid in BaseLib, renaming
the internal function AsciiStrToGuid to IniAsciiStrToGuid to avoid
link failure.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
---
 SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
index 270380e..16e1349 100644
--- a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
+++ b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
@@ -25,7 +25,7 @@
   OpenIniFile(), PreProcessDataFile(), ProfileGetSection(), ProfileGetEntry()
   will receive untrusted input and do basic validation.
 
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions
@@ -933,7 +933,7 @@ AsciiStrToBuf (
 
 **/
 EFI_STATUS
-AsciiStrToGuid (
+IniAsciiStrToGuid (
   IN  CHAR8    *Str,
   OUT EFI_GUID *Guid
   )
@@ -1261,7 +1261,7 @@ GetGuidFromDataFile (
   if (!IsValidGuid(Value, AsciiStrLen(Value))) {
     return EFI_NOT_FOUND;
   }
-  Status = AsciiStrToGuid(Value, Guid);
+  Status = IniAsciiStrToGuid(Value, Guid);
   if (EFI_ERROR (Status)) {
     return EFI_NOT_FOUND;
   }
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (2 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 03/11] SignedCapsulePkg/IniParsing: " Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  6:02   ` Yao, Jiewen
  2017-02-22  4:50 ` [PATCH 05/11] MdePkg/BaseLib: Add AsciiStrToGuid/HexToBytes/ToIpv[4/6]Address Ruiyu Ni
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Jiewen Yao, Siyuan Fu

The patch adds 4 APIs to convert Unicode string to GUID, bytes
buffer, IP v4 address and IP v6 address.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
---
 MdePkg/Include/Library/BaseLib.h    | 241 ++++++++++++++
 MdePkg/Library/BaseLib/SafeString.c | 623 ++++++++++++++++++++++++++++++++++++
 2 files changed, 864 insertions(+)

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index d71ccb7..8aac4c8 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -1536,6 +1536,247 @@ StrHexToUint64 (
   IN      CONST CHAR16             *String
   );
 
+/**
+  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                    zero, and String contains more than
+                                    PcdMaximumUnicodeStringLength Unicode
+                                    characters, not including the
+                                    Null-terminator.
+                                   If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv6Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                    zero, and String contains more than
+                                    PcdMaximumUnicodeStringLength Unicode
+                                    characters, not including the
+                                    Null-terminator.
+                                   If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv4Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+#define GUID_STRING_LENGTH  36
+
+/**
+  Convert a Null-terminated Unicode GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the Unicode string specified by String. The format of the input
+  Unicode string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToGuid (
+  IN  CONST CHAR16       *String,
+  OUT GUID               *Guid
+  );
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the Unicode string specified by String in hexadecimal format. The format of
+  the input Unicode string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumStringLength is not zero and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Length                   The number of Unicode characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+StrHexToBytes (
+  IN  CONST CHAR16       *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  );
+
 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
 
 /**
diff --git a/MdePkg/Library/BaseLib/SafeString.c b/MdePkg/Library/BaseLib/SafeString.c
index 315059e..ede1c99 100644
--- a/MdePkg/Library/BaseLib/SafeString.c
+++ b/MdePkg/Library/BaseLib/SafeString.c
@@ -1074,6 +1074,629 @@ StrHexToUint64S (
 }
 
 /**
+  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                    zero, and String contains more than
+                                    PcdMaximumUnicodeStringLength Unicode
+                                    characters, not including the
+                                    Null-terminator.
+                                   If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv6Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  IPv6_ADDRESS           LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CONST CHAR16           *Pointer;
+  CHAR16                 *End;
+  UINTN                  CompressStart;
+  BOOLEAN                ExpectPrefix;
+
+  LocalPrefixLength = MAX_UINT8;
+  CompressStart     = ARRAY_SIZE (Address->Addr);
+  ExpectPrefix      = FALSE;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer != L':') {
+        //
+        // ":" or "/" should be followed by digit characters.
+        //
+        return RETURN_INVALID_PARAMETER;
+      }
+
+      //
+      // Meet second ":" after previous ":" or "/"
+      // or meet first ":" in the beginning of String.
+      //
+      if (ExpectPrefix) {
+        //
+        // ":" shall not be after "/"
+        //
+        return RETURN_INVALID_PARAMETER;
+      }
+
+      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // "::" can only appear once.
+        // "::" can only appear when address is not full length.
+        //
+        return RETURN_INVALID_PARAMETER;
+      } else {
+        //
+        // Remember the start of zero compressing.
+        //
+        CompressStart = AddressIndex;
+        Pointer++;
+
+        if (CompressStart == 0) {
+          if (*Pointer != L':') {
+            //
+            // Single ":" shall not be in the beginning of String.
+            //
+            return RETURN_INVALID_PARAMETER;
+          }
+          Pointer++;
+        }
+      }
+    }
+
+    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer == L'/') {
+        //
+        // Might be optional "/P" after "::".
+        //
+        if (CompressStart != AddressIndex) {
+          return RETURN_INVALID_PARAMETER;
+        }
+      } else {
+        break;
+      }
+    } else {
+      if (!ExpectPrefix) {
+        //
+        // Get X.
+        //
+        Status = StrHexToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End - Pointer > 4) {
+          //
+          // Number of hexadecimal digit characters is no more than 4.
+          //
+          return RETURN_INVALID_PARAMETER;
+        }
+        Pointer = End;
+        //
+        // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
+        //
+        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
+        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
+        AddressIndex += 2;
+      } else {
+        //
+        // Get P, then exit the loop.
+        //
+        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
+          //
+          // Prefix length should not exceed 128.
+          //
+          return RETURN_INVALID_PARAMETER;
+        }
+        LocalPrefixLength = (UINT8) Uintn;
+        Pointer = End;
+        break;
+      }
+    }
+
+    //
+    // Skip ':' or "/"
+    //
+    if (*Pointer == L'/') {
+      ExpectPrefix = TRUE;
+    } else if (*Pointer == L':') {
+      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // Meet additional ":" after all 8 16-bit address
+        //
+        break;
+      }
+    } else {
+      //
+      // Meet other character that is not "/" or ":" after all 8 16-bit address
+      //
+      break;
+    }
+    Pointer++;
+  }
+
+  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
+    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
+      ) {
+    //
+    // Full length of address shall not have compressing zeros.
+    // Non-full length of address shall have compressing zeros.
+    //
+    return RETURN_INVALID_PARAMETER;
+  }
+  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
+  ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
+  CopyMem (
+    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
+    &LocalAddress.Addr[CompressStart],
+    AddressIndex - CompressStart
+    );
+
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR16 *) Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                    zero, and String contains more than
+                                    PcdMaximumUnicodeStringLength Unicode
+                                    characters, not including the
+                                    Null-terminator.
+                                   If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv4Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  IPv4_ADDRESS           LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CHAR16                 *Pointer;
+
+  LocalPrefixLength = MAX_UINT8;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
+      //
+      // D or P contains invalid characters.
+      //
+      break;
+    }
+
+    //
+    // Get D or P.
+    //
+    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer, &Uintn);
+    if (RETURN_ERROR (Status)) {
+      return RETURN_INVALID_PARAMETER;
+    }
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      //
+      // It's P.
+      //
+      if (Uintn > 32) {
+        return RETURN_INVALID_PARAMETER;
+      }
+      LocalPrefixLength = (UINT8) Uintn;
+    } else {
+      //
+      // It's D.
+      //
+      if (Uintn > MAX_UINT8) {
+        return RETURN_INVALID_PARAMETER;
+      }
+      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
+      AddressIndex++;
+    }
+
+    //
+    // Check the '.' or '/', depending on the AddressIndex.
+    //
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == L'/') {
+        //
+        // '/P' is in the String.
+        // Skip "/" and get P in next loop.
+        //
+        Pointer++;
+      } else {
+        //
+        // '/P' is not in the String.
+        //
+        break;
+      }
+    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == L'.') {
+        //
+        // D should be followed by '.'
+        //
+        Pointer++;
+      } else {
+        return RETURN_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyMem (Address, &LocalAddress, sizeof (*Address));
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the Unicode string specified by String. The format of the input
+  Unicode string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToGuid (
+  IN  CONST CHAR16       *String,
+  OUT GUID               *Guid
+  )
+{
+  RETURN_STATUS          Status;
+  GUID                   LocalGuid;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // Get aabbccdd in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
+  String += 2 * sizeof (LocalGuid.Data1) + 1;
+
+  //
+  // Get eeff in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
+  String += 2 * sizeof (LocalGuid.Data2) + 1;
+
+  //
+  // Get gghh in big-endian.
+  //
+  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
+  String += 2 * sizeof (LocalGuid.Data3) + 1;
+
+  //
+  // Get iijj.
+  //
+  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
+  if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  String += 2 * 2 + 1;
+
+  //
+  // Get kkllmmnnoopp.
+  //
+  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
+  if (RETURN_ERROR (Status)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyGuid (Guid, &LocalGuid);
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the Unicode string specified by String in hexadecimal format. The format of
+  the input Unicode string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumStringLength is not zero and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Length                   The number of Unicode characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+StrHexToBytes (
+  IN  CONST CHAR16       *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  )
+{
+  UINTN                  Index;
+
+  ASSERT (((UINTN) String & BIT0) == 0);
+
+  //
+  // 1. None of String or Buffer shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. Length shall not be greater than RSIZE_MAX.
+  //
+  if (RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  //
+  // 3. Length shall not be odd.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
+
+  //
+  // 4. MaxBufferSize shall equal to or greater than Length / 2.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
+
+  //
+  // 5. String shall not contains invalid hexadecimal digits.
+  //
+  for (Index = 0; Index < Length; Index++) {
+    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
+      break;
+    }
+  }
+  if (Index != Length) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  //
+  // Convert the hex string to bytes.
+  //
+  for(Index = 0; Index < Length; Index++) {
+
+    //
+    // For even characters, write the upper nibble for each buffer byte,
+    // and for even characters, the lower nibble.
+    //
+    if ((Index & BIT0) == 0) {
+      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
+    } else {
+      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
+    }
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
   Returns the length of a Null-terminated Ascii string.
 
   This function is similar as strlen_s defined in C11.
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/11] MdePkg/BaseLib: Add AsciiStrToGuid/HexToBytes/ToIpv[4/6]Address
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (3 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 06/11] MdePkg/UefiDevicePathLib: Use BaseLib string conversion services Ruiyu Ni
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Jiewen Yao, Siyuan Fu

The patch adds 4 APIs to convert ASCII string to GUID, bytes
buffer, IP v4 address and IP v6 address.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
---
 MdePkg/Include/Library/BaseLib.h    | 214 +++++++++++++
 MdePkg/Library/BaseLib/SafeString.c | 591 ++++++++++++++++++++++++++++++++++++
 2 files changed, 805 insertions(+)

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 8aac4c8..2f3614d 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -2428,6 +2428,220 @@ AsciiStrHexToUint64 (
   IN      CONST CHAR8                *String
   );
 
+/**
+  Convert a Null-terminated ASCII string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv6Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated ASCII string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv4Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated ASCII GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the ASCII string specified by String. The format of the input
+  ASCII string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToGuid (
+  IN  CONST CHAR8        *String,
+  OUT GUID               *Guid
+  );
+
+/**
+  Convert a Null-terminated ASCII hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the ASCII string specified by String in hexadecimal format. The format of
+  the input ASCII string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Length                   The number of ASCII characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrHexToBytes (
+  IN  CONST CHAR8        *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  );
+
 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
 
 /**
diff --git a/MdePkg/Library/BaseLib/SafeString.c b/MdePkg/Library/BaseLib/SafeString.c
index ede1c99..720f3f6 100644
--- a/MdePkg/Library/BaseLib/SafeString.c
+++ b/MdePkg/Library/BaseLib/SafeString.c
@@ -3060,3 +3060,594 @@ AsciiStrnToUnicodeStrS (
 
   return RETURN_SUCCESS;
 }
+
+/**
+  Convert a Null-terminated ASCII string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv6Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  IPv6_ADDRESS           LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CONST CHAR8            *Pointer;
+  CHAR8                  *End;
+  UINTN                  CompressStart;
+  BOOLEAN                ExpectPrefix;
+
+  LocalPrefixLength = MAX_UINT8;
+  CompressStart     = ARRAY_SIZE (Address->Addr);
+  ExpectPrefix      = FALSE;
+
+  //
+  // None of String or Address shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer != ':') {
+        //
+        // ":" or "/" should be followed by digit characters.
+        //
+        return RETURN_INVALID_PARAMETER;
+      }
+
+      //
+      // Meet second ":" after previous ":" or "/"
+      // or meet first ":" in the beginning of String.
+      //
+      if (ExpectPrefix) {
+        //
+        // ":" shall not be after "/"
+        //
+        return RETURN_INVALID_PARAMETER;
+      }
+
+      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // "::" can only appear once.
+        // "::" can only appear when address is not full length.
+        //
+        return RETURN_INVALID_PARAMETER;
+      } else {
+        //
+        // Remember the start of zero compressing.
+        //
+        CompressStart = AddressIndex;
+        Pointer++;
+
+        if (CompressStart == 0) {
+          if (*Pointer != ':') {
+            //
+            // Single ":" shall not be in the beginning of String.
+            //
+            return RETURN_INVALID_PARAMETER;
+          }
+          Pointer++;
+        }
+      }
+    }
+
+    if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer)) {
+      if (*Pointer == '/') {
+        //
+        // Might be optional "/P" after "::".
+        //
+        if (CompressStart != AddressIndex) {
+          return RETURN_INVALID_PARAMETER;
+        }
+      } else {
+        break;
+      }
+    } else {
+      if (!ExpectPrefix) {
+        //
+        // Get X.
+        //
+        Status = AsciiStrHexToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End - Pointer > 4) {
+          //
+          // Number of hexadecimal digit characters is no more than 4.
+          //
+          return RETURN_INVALID_PARAMETER;
+        }
+        Pointer = End;
+        //
+        // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
+        //
+        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
+        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
+        AddressIndex += 2;
+      } else {
+        //
+        // Get P, then exit the loop.
+        //
+        Status = AsciiStrDecimalToUintnS (Pointer, &End, &Uintn);
+        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
+          //
+          // Prefix length should not exceed 128.
+          //
+          return RETURN_INVALID_PARAMETER;
+        }
+        LocalPrefixLength = (UINT8) Uintn;
+        Pointer = End;
+        break;
+      }
+    }
+
+    //
+    // Skip ':' or "/"
+    //
+    if (*Pointer == '/') {
+      ExpectPrefix = TRUE;
+    } else if (*Pointer == ':') {
+      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+        //
+        // Meet additional ":" after all 8 16-bit address
+        //
+        break;
+      }
+    } else {
+      //
+      // Meet other character that is not "/" or ":" after all 8 16-bit address
+      //
+      break;
+    }
+    Pointer++;
+  }
+
+  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
+    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
+      ) {
+    //
+    // Full length of address shall not have compressing zeros.
+    // Non-full length of address shall have compressing zeros.
+    //
+    return RETURN_INVALID_PARAMETER;
+  }
+  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
+  ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) - AddressIndex);
+  CopyMem (
+    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
+    &LocalAddress.Addr[CompressStart],
+    AddressIndex - CompressStart
+    );
+
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = (CHAR8 *) Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated ASCII string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv4Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  )
+{
+  RETURN_STATUS          Status;
+  UINTN                  AddressIndex;
+  UINTN                  Uintn;
+  IPv4_ADDRESS           LocalAddress;
+  UINT8                  LocalPrefixLength;
+  CHAR8                  *Pointer;
+
+  LocalPrefixLength = MAX_UINT8;
+
+  //
+  // None of String or Address shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
+
+  for (Pointer = (CHAR8 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
+    if (!InternalAsciiIsDecimalDigitCharacter (*Pointer)) {
+      //
+      // D or P contains invalid characters.
+      //
+      break;
+    }
+
+    //
+    // Get D or P.
+    //
+    Status = AsciiStrDecimalToUintnS ((CONST CHAR8 *) Pointer, &Pointer, &Uintn);
+    if (RETURN_ERROR (Status)) {
+      return RETURN_INVALID_PARAMETER;
+    }
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      //
+      // It's P.
+      //
+      if (Uintn > 32) {
+        return RETURN_INVALID_PARAMETER;
+      }
+      LocalPrefixLength = (UINT8) Uintn;
+    } else {
+      //
+      // It's D.
+      //
+      if (Uintn > MAX_UINT8) {
+        return RETURN_INVALID_PARAMETER;
+      }
+      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
+      AddressIndex++;
+    }
+
+    //
+    // Check the '.' or '/', depending on the AddressIndex.
+    //
+    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == '/') {
+        //
+        // '/P' is in the String.
+        // Skip "/" and get P in next loop.
+        //
+        Pointer++;
+      } else {
+        //
+        // '/P' is not in the String.
+        //
+        break;
+      }
+    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+      if (*Pointer == '.') {
+        //
+        // D should be followed by '.'
+        //
+        Pointer++;
+      } else {
+        return RETURN_INVALID_PARAMETER;
+      }
+    }
+  }
+
+  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyMem (Address, &LocalAddress, sizeof (*Address));
+  if (PrefixLength != NULL) {
+    *PrefixLength = LocalPrefixLength;
+  }
+  if (EndPointer != NULL) {
+    *EndPointer = Pointer;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated ASCII GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the ASCII string specified by String. The format of the input
+  ASCII string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToGuid (
+  IN  CONST CHAR8        *String,
+  OUT GUID               *Guid
+  )
+{
+  RETURN_STATUS          Status;
+  GUID                   LocalGuid;
+
+  //
+  // None of String or Guid shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // Get aabbccdd in big-endian.
+  //
+  Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != '-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
+  String += 2 * sizeof (LocalGuid.Data1) + 1;
+
+  //
+  // Get eeff in big-endian.
+  //
+  Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != '-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
+  String += 2 * sizeof (LocalGuid.Data2) + 1;
+
+  //
+  // Get gghh in big-endian.
+  //
+  Status = AsciiStrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
+  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != '-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  //
+  // Convert big-endian to little-endian.
+  //
+  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
+  String += 2 * sizeof (LocalGuid.Data3) + 1;
+
+  //
+  // Get iijj.
+  //
+  Status = AsciiStrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
+  if (RETURN_ERROR (Status) || String[2 * 2] != '-') {
+    return RETURN_INVALID_PARAMETER;
+  }
+  String += 2 * 2 + 1;
+
+  //
+  // Get kkllmmnnoopp.
+  //
+  Status = AsciiStrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
+  if (RETURN_ERROR (Status)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  CopyGuid (Guid, &LocalGuid);
+  return RETURN_SUCCESS;
+}
+
+/**
+  Convert a Null-terminated ASCII hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the ASCII string specified by String in hexadecimal format. The format of
+  the input ASCII string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Length                   The number of ASCII characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrHexToBytes (
+  IN  CONST CHAR8        *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  )
+{
+  UINTN                  Index;
+
+  //
+  // 1. None of String or Buffer shall be a null pointer.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
+  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
+
+  //
+  // 2. Length shall not be greater than ASCII_RSIZE_MAX.
+  //
+  if (ASCII_RSIZE_MAX != 0) {
+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
+  }
+
+  //
+  // 3. Length shall not be odd.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
+
+  //
+  // 4. MaxBufferSize shall equal to or greater than Length / 2.
+  //
+  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
+
+  //
+  // 5. String shall not contains invalid hexadecimal digits.
+  //
+  for (Index = 0; Index < Length; Index++) {
+    if (!InternalAsciiIsHexaDecimalDigitCharacter (String[Index])) {
+      break;
+    }
+  }
+  if (Index != Length) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  //
+  // Convert the hex string to bytes.
+  //
+  for(Index = 0; Index < Length; Index++) {
+
+    //
+    // For even characters, write the upper nibble for each buffer byte,
+    // and for even characters, the lower nibble.
+    //
+    if ((Index & BIT0) == 0) {
+      Buffer[Index / 2]  = (UINT8) InternalAsciiHexCharToUintn (String[Index]) << 4;
+    } else {
+      Buffer[Index / 2] |= (UINT8) InternalAsciiHexCharToUintn (String[Index]);
+    }
+  }
+  return RETURN_SUCCESS;
+}
+
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/11] MdePkg/UefiDevicePathLib: Use BaseLib string conversion services
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (4 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 05/11] MdePkg/BaseLib: Add AsciiStrToGuid/HexToBytes/ToIpv[4/6]Address Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 07/11] MdeModulePkg/CapsuleApp: Use StrToGuid in BaseLib Ruiyu Ni
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao

Update UefiDevicePathLib to use StrToGuid/StrHexToBytes
/StrToIpv4Address/StrToIpv6Address provided by BaseLib.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 .../Library/UefiDevicePathLib/DevicePathFromText.c | 221 ++-------------------
 1 file changed, 17 insertions(+), 204 deletions(-)

diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
index e2b06a2..ae38859 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -326,187 +326,6 @@ Strtoi64 (
 }
 
 /**
-  Converts a list of string to a specified buffer.
-
-  @param Buf             The output buffer that contains the string.
-  @param BufferLength    The length of the buffer
-  @param Str             The input string that contains the hex number
-
-  @retval EFI_SUCCESS    The string was successfully converted to the buffer.
-
-**/
-EFI_STATUS
-StrToBuf (
-  OUT UINT8    *Buf,
-  IN  UINTN    BufferLength,
-  IN  CHAR16   *Str
-  )
-{
-  UINTN       Index;
-  UINTN       StrLength;
-  UINT8       Digit;
-  UINT8       Byte;
-
-  Digit = 0;
-
-  //
-  // Two hex char make up one byte
-  //
-  StrLength = BufferLength * sizeof (CHAR16);
-
-  for(Index = 0; Index < StrLength; Index++, Str++) {
-
-    if ((*Str >= L'a') && (*Str <= L'f')) {
-      Digit = (UINT8) (*Str - L'a' + 0x0A);
-    } else if ((*Str >= L'A') && (*Str <= L'F')) {
-      Digit = (UINT8) (*Str - L'A' + 0x0A);
-    } else if ((*Str >= L'0') && (*Str <= L'9')) {
-      Digit = (UINT8) (*Str - L'0');
-    } else {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    //
-    // For odd characters, write the upper nibble for each buffer byte,
-    // and for even characters, the lower nibble.
-    //
-    if ((Index & 1) == 0) {
-      Byte = (UINT8) (Digit << 4);
-    } else {
-      Byte = Buf[Index / 2];
-      Byte &= 0xF0;
-      Byte = (UINT8) (Byte | Digit);
-    }
-
-    Buf[Index / 2] = Byte;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Converts a string to GUID value.
-  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-
-  @param Str              The registry format GUID string that contains the GUID value.
-  @param Guid             A pointer to the converted GUID value.
-
-  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.
-  @retval EFI_UNSUPPORTED The input string is not in registry format.
-  @return others          Some error occurred when converting part of GUID value.
-
-**/
-EFI_STATUS
-DevicePathLibStrToGuid (
-  IN  CHAR16   *Str,
-  OUT EFI_GUID *Guid
-  )
-{
-  //
-  // Get the first UINT32 data
-  //
-  Guid->Data1 = (UINT32) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-  
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-  
-  //
-  // Get the second UINT16 data
-  //
-  Guid->Data2 = (UINT16) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-  
-  //
-  // Get the third UINT16 data
-  //
-  Guid->Data3 = (UINT16) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the following 8 bytes data
-  //  
-  StrToBuf (&Guid->Data4[0], 2, Str);
-  //
-  // Skip 2 byte hex chars
-  //
-  Str += 2 * 2;
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-  StrToBuf (&Guid->Data4[2], 6, Str);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Converts a string to IPv4 address
-
-  @param Str             A string representation of IPv4 address.
-  @param IPv4Addr        A pointer to the converted IPv4 address.
-
-**/
-VOID
-StrToIPv4Addr (
-  IN OUT CHAR16           **Str,
-  OUT    EFI_IPv4_ADDRESS *IPv4Addr
-  )
-{
-  UINTN  Index;
-
-  for (Index = 0; Index < 4; Index++) {
-    IPv4Addr->Addr[Index] = (UINT8) Strtoi (SplitStr (Str, L'.'));
-  }
-}
-
-/**
-  Converts a string to IPv4 address
-
-  @param Str             A string representation of IPv6 address.
-  @param IPv6Addr        A pointer to the converted IPv6 address.
-
-**/
-VOID
-StrToIPv6Addr (
-  IN OUT CHAR16           **Str,
-  OUT    EFI_IPv6_ADDRESS *IPv6Addr
-  )
-{
-  UINTN  Index;
-  UINT16 Data;
-
-  for (Index = 0; Index < 8; Index++) {
-    Data = (UINT16) StrHexToUintn (SplitStr (Str, L':'));
-    IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
-    IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
-  }
-}
-
-/**
   Converts a Unicode string to ASCII string.
 
   @param Str             The equivalent Unicode string
@@ -567,9 +386,7 @@ DevPathFromTextGenericPath (
            (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
            );
 
-  if (DataLength != 0) {
-    StrToBuf ((UINT8 *) (Node + 1), DataLength, DataStr);
-  }
+  StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
   return Node;
 }
 
@@ -740,8 +557,8 @@ ConvertFromTextVendor (
                                      (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
                                      );
 
-  DevicePathLibStrToGuid (GuidStr, &Vendor->Guid);
-  StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
+  StrToGuid (GuidStr, &Vendor->Guid);
+  StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
 }
@@ -1438,7 +1255,6 @@ DevPathFromTextInfiniband (
   CHAR16                  *SidStr;
   CHAR16                  *TidStr;
   CHAR16                  *DidStr;
-  EFI_GUID                PortGid;
   INFINIBAND_DEVICE_PATH  *InfiniBand;
 
   FlagsStr   = GetNextParamStr (&TextDeviceNode);
@@ -1453,8 +1269,7 @@ DevPathFromTextInfiniband (
                                             );
 
   InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
-  DevicePathLibStrToGuid (GuidStr, &PortGid);
-  CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
+  StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
   Strtoi64 (SidStr, &InfiniBand->ServiceId);
   Strtoi64 (TidStr, &InfiniBand->TargetPortId);
   Strtoi64 (DidStr, &InfiniBand->DeviceId);
@@ -1985,7 +1800,7 @@ DevPathFromTextMAC (
   MACDevPath->IfType   = (UINT8) Strtoi (IfTypeStr);
 
   Length = sizeof (EFI_MAC_ADDRESS);
-  StrToBuf (&MACDevPath->MacAddress.Addr[0], Length, AddressStr);
+  StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
 }
@@ -2049,7 +1864,7 @@ DevPathFromTextIPv4 (
                                                  (UINT16) sizeof (IPv4_DEVICE_PATH)
                                                  );
 
-  StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);
+  StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
   IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
   if (StrCmp (TypeStr, L"Static") == 0) {
     IPv4->StaticIpAddress = TRUE;
@@ -2057,10 +1872,10 @@ DevPathFromTextIPv4 (
     IPv4->StaticIpAddress = FALSE;
   }
 
-  StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);
+  StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
-    StrToIPv4Addr (&GatewayIPStr,  &IPv4->GatewayIpAddress);
-    StrToIPv4Addr (&SubnetMaskStr, &IPv4->SubnetMask);
+    StrToIpv4Address (GatewayIPStr,  NULL, &IPv4->GatewayIpAddress, NULL);
+    StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask,       NULL);
   } else {
     ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
     ZeroMem (&IPv4->SubnetMask,    sizeof (IPv4->SubnetMask));
@@ -2105,7 +1920,7 @@ DevPathFromTextIPv6 (
                                                  (UINT16) sizeof (IPv6_DEVICE_PATH)
                                                  );
 
-  StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);
+  StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
   IPv6->Protocol        = (UINT16) NetworkProtocolFromText (ProtocolStr);
   if (StrCmp (TypeStr, L"Static") == 0) {
     IPv6->IpAddressOrigin = 0;
@@ -2115,9 +1930,9 @@ DevPathFromTextIPv6 (
     IPv6->IpAddressOrigin = 2;
   }
 
-  StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);
+  StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
   if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
-    StrToIPv6Addr (&GatewayIPStr, &IPv6->GatewayIpAddress);
+    StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
     IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
   } else {
     ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
@@ -2947,7 +2762,6 @@ DevPathFromTextHD (
   CHAR16                *StartStr;
   CHAR16                *SizeStr;
   UINT32                Signature32;
-  EFI_GUID              SignatureGuid;
   HARDDRIVE_DEVICE_PATH *Hd;
 
   PartitionStr        = GetNextParamStr (&TextDeviceNode);
@@ -2976,8 +2790,7 @@ DevPathFromTextHD (
     Hd->SignatureType = SIGNATURE_TYPE_GUID;
     Hd->MBRType       = 0x02;
 
-    DevicePathLibStrToGuid (SignatureStr, &SignatureGuid);
-    CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
+    StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
   } else {
     Hd->SignatureType = (UINT8) Strtoi (TypeStr);
   }
@@ -3091,7 +2904,7 @@ DevPathFromTextMedia (
                                              (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
                                              );
 
-  DevicePathLibStrToGuid (GuidStr, &Media->Protocol);
+  StrToGuid (GuidStr, &Media->Protocol);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Media;
 }
@@ -3119,7 +2932,7 @@ DevPathFromTextFv (
                                            (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
                                            );
 
-  DevicePathLibStrToGuid (GuidStr, &Fv->FvName);
+  StrToGuid (GuidStr, &Fv->FvName);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
 }
@@ -3147,7 +2960,7 @@ DevPathFromTextFvFile (
                                                     (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
                                                     );
 
-  DevicePathLibStrToGuid (GuidStr, &FvFile->FvFileName);
+  StrToGuid (GuidStr, &FvFile->FvFileName);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
 }
@@ -3219,7 +3032,7 @@ DevPathFromTextRamDisk (
   Strtoi64 (EndingAddrStr, &EndingAddr);
   WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
   RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
-  DevicePathLibStrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+  StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
 
   return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
 }
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/11] MdeModulePkg/CapsuleApp: Use StrToGuid in BaseLib
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (5 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 06/11] MdePkg/UefiDevicePathLib: Use BaseLib string conversion services Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 08/11] SecurityPkg/SecureBootConfigDxe: " Ruiyu Ni
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jiewen Yao

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
---
 MdeModulePkg/Application/CapsuleApp/AppSupport.c | 140 +----------------------
 MdeModulePkg/Application/CapsuleApp/CapsuleApp.c |  25 +---
 2 files changed, 4 insertions(+), 161 deletions(-)

diff --git a/MdeModulePkg/Application/CapsuleApp/AppSupport.c b/MdeModulePkg/Application/CapsuleApp/AppSupport.c
index edc5f29..e39ab20 100644
--- a/MdeModulePkg/Application/CapsuleApp/AppSupport.c
+++ b/MdeModulePkg/Application/CapsuleApp/AppSupport.c
@@ -1,7 +1,7 @@
 /** @file
   A shell application that triggers capsule update process.
 
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -64,144 +64,6 @@ GetArg (
 }
 
 /**
-  Converts a list of string to a specified buffer.
-
-  @param[out] Buf             The output buffer that contains the string.
-  @param[in]  BufferLength    The length of the buffer
-  @param[in]  Str             The input string that contains the hex number
-
-  @retval EFI_SUCCESS    The string was successfully converted to the buffer.
-
-**/
-EFI_STATUS
-InternalStrToBuf (
-  OUT UINT8    *Buf,
-  IN  UINTN    BufferLength,
-  IN  CHAR16   *Str
-  )
-{
-  UINTN       Index;
-  UINTN       StrLength;
-  UINT8       Digit;
-  UINT8       Byte;
-
-  Digit = 0;
-
-  //
-  // Two hex char make up one byte
-  //
-  StrLength = BufferLength * sizeof (CHAR16);
-
-  for(Index = 0; Index < StrLength; Index++, Str++) {
-
-    if ((*Str >= L'a') && (*Str <= L'f')) {
-      Digit = (UINT8) (*Str - L'a' + 0x0A);
-    } else if ((*Str >= L'A') && (*Str <= L'F')) {
-      Digit = (UINT8) (*Str - L'A' + 0x0A);
-    } else if ((*Str >= L'0') && (*Str <= L'9')) {
-      Digit = (UINT8) (*Str - L'0');
-    } else {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    //
-    // For odd characters, write the upper nibble for each buffer byte,
-    // and for even characters, the lower nibble.
-    //
-    if ((Index & 1) == 0) {
-      Byte = (UINT8) (Digit << 4);
-    } else {
-      Byte = Buf[Index / 2];
-      Byte &= 0xF0;
-      Byte = (UINT8) (Byte | Digit);
-    }
-
-    Buf[Index / 2] = Byte;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Converts a string to GUID value.
-  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-
-  @param[in]  Str              The registry format GUID string that contains the GUID value.
-  @param[out] Guid             A pointer to the converted GUID value.
-
-  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.
-  @retval EFI_UNSUPPORTED The input string is not in registry format.
-  @return others          Some error occurred when converting part of GUID value.
-
-**/
-EFI_STATUS
-InternalStrToGuid (
-  IN  CHAR16   *Str,
-  OUT EFI_GUID *Guid
-  )
-{
-  //
-  // Get the first UINT32 data
-  //
-  Guid->Data1 = (UINT32) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the second UINT16 data
-  //
-  Guid->Data2 = (UINT16) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the third UINT16 data
-  //
-  Guid->Data3 = (UINT16) StrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the following 8 bytes data
-  //
-  InternalStrToBuf (&Guid->Data4[0], 2, Str);
-  //
-  // Skip 2 byte hex chars
-  //
-  Str += 2 * 2;
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-  InternalStrToBuf (&Guid->Data4[2], 6, Str);
-
-  return EFI_SUCCESS;
-}
-
-/**
   Return File System Volume containing this shell application.
 
   @return File System Volume containing this shell application.
diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
index 5b8c147..eea40b7 100644
--- a/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
+++ b/MdeModulePkg/Application/CapsuleApp/CapsuleApp.c
@@ -1,7 +1,7 @@
 /** @file
   A shell application that triggers capsule update process.
 
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -143,24 +143,6 @@ WriteFileFromBuffer (
   );
 
 /**
-  Converts a string to GUID value.
-  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-
-  @param[in]  Str              The registry format GUID string that contains the GUID value.
-  @param[out] Guid             A pointer to the converted GUID value.
-
-  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.
-  @retval EFI_UNSUPPORTED The input string is not in registry format.
-  @return others          Some error occurred when converting part of GUID value.
-
-**/
-EFI_STATUS
-InternalStrToGuid (
-  IN  CHAR16   *Str,
-  OUT EFI_GUID *Guid
-  );
-
-/**
 
   This function parse application ARG.
 
@@ -782,10 +764,9 @@ UefiMain (
         //
         // FMP->GetImage()
         //
-        Status = InternalStrToGuid(Argv[3], &ImageTypeId);
-        if (EFI_ERROR(Status)) {
+        if (RETURN_ERROR (StrToGuid (Argv[3], &ImageTypeId)) || (Argv[3][GUID_STRING_LENGTH] != L'\0')) {
           Print (L"Invalid ImageTypeId - %s\n", Argv[3]);
-          return Status;
+          return EFI_INVALID_PARAMETER;
         }
         ImageIndex = StrDecimalToUintn(Argv[4]);
         if (StrCmp(Argv[5], L"-O") == 0) {
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/11] SecurityPkg/SecureBootConfigDxe: Use StrToGuid in BaseLib
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (6 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 07/11] MdeModulePkg/CapsuleApp: Use StrToGuid in BaseLib Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 09/11] ShellPkg/Debug1CommandLib: Use StrToGuid/StrHexToBytes " Ruiyu Ni
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jiewen Yao

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
---
 .../SecureBootConfigDxe/SecureBootConfigImpl.c     |  11 +-
 .../SecureBootConfigDxe/SecureBootConfigImpl.h     |  22 +---
 .../SecureBootConfigDxe/SecureBootConfigMisc.c     | 141 +--------------------
 3 files changed, 6 insertions(+), 168 deletions(-)

diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 0d96185..9b7d0c1 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -1,7 +1,7 @@
 /** @file
   HII Config Access protocol implementation of SecureBoot configuration module.
 
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -3636,12 +3636,9 @@ SecureBootCallback (
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBX:
     case KEY_SECURE_BOOT_SIGNATURE_GUID_DBT:
       ASSERT (Private->SignatureGUID != NULL);
-      Status = StringToGuid (
-                 IfrNvData->SignatureGuid,
-                 StrLen (IfrNvData->SignatureGuid),
-                 Private->SignatureGUID
-                 );
-      if (EFI_ERROR (Status)) {
+      if (RETURN_ERROR (StrToGuid (IfrNvData->SignatureGuid, Private->SignatureGUID)) ||
+          (IfrNvData->SignatureGuid[GUID_STRING_LENGTH] != L'\0')) {
+        Status = EFI_INVALID_PARAMETER;
         break;
       }
 
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
index 5055a9e..aa58c44 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
@@ -2,7 +2,7 @@
   The header file of HII Config Access protocol implementation of SecureBoot
   configuration module.
 
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -479,26 +479,6 @@ Int2OctStr (
   IN     UINTN             OSSizeInBytes
   );
 
-
-/**
-  Convert a String to Guid Value.
-
-  @param[in]   Str        Specifies the String to be converted.
-  @param[in]   StrLen     Number of Unicode Characters of String (exclusive \0)
-  @param[out]  Guid       Return the result Guid value.
-
-  @retval    EFI_SUCCESS           The operation is finished successfully.
-  @retval    EFI_NOT_FOUND         Invalid string.
-
-**/
-EFI_STATUS
-StringToGuid (
-  IN   CHAR16           *Str,
-  IN   UINTN            StrLen,
-  OUT  EFI_GUID         *Guid
-  );
-
-
 /**
   Worker function that prints an EFI_GUID into specified Buffer.
 
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigMisc.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigMisc.c
index a83504e..038707c 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigMisc.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigMisc.c
@@ -1,7 +1,7 @@
 /** @file
   Helper functions for SecureBoot configuration module.
 
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
@@ -152,145 +152,6 @@ Int2OctStr (
   return EFI_SUCCESS;
 }
 
-
-
-/**
-  Convert a String to Guid Value.
-
-  @param[in]   Str        Specifies the String to be converted.
-  @param[in]   StrLen     Number of Unicode Characters of String (exclusive \0)
-  @param[out]  Guid       Return the result Guid value.
-
-  @retval    EFI_SUCCESS           The operation is finished successfully.
-  @retval    EFI_NOT_FOUND         Invalid string.
-
-**/
-EFI_STATUS
-StringToGuid (
-  IN   CHAR16           *Str, 
-  IN   UINTN            StrLen, 
-  OUT  EFI_GUID         *Guid
-  )
-{
-  CHAR16             *PtrBuffer;
-  CHAR16             *PtrPosition;
-  UINT16             *Buffer;
-  UINTN              Data;
-  UINTN              Index;
-  UINT16             Digits[3];
-
-  Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
-  if (Buffer == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  StrCpyS (Buffer, (StrLen + 1), Str);
-
-  //
-  // Data1
-  //
-  PtrBuffer       = Buffer;
-  PtrPosition     = PtrBuffer; 
-  while (*PtrBuffer != L'\0') {
-    if (*PtrBuffer == L'-') {
-      break;
-    }
-    PtrBuffer++;
-  }
-  if (*PtrBuffer == L'\0') {
-    FreePool (Buffer);
-    return EFI_NOT_FOUND;
-  }
-
-  *PtrBuffer      = L'\0';
-  Data            = StrHexToUintn (PtrPosition);
-  Guid->Data1     = (UINT32)Data;
-
-  //
-  // Data2
-  //
-  PtrBuffer++;
-  PtrPosition     = PtrBuffer;
-  while (*PtrBuffer != L'\0') {
-    if (*PtrBuffer == L'-') {
-      break;
-    }
-    PtrBuffer++;
-  }
-  if (*PtrBuffer == L'\0') {
-    FreePool (Buffer);
-    return EFI_NOT_FOUND;
-  }
-  *PtrBuffer      = L'\0';
-  Data            = StrHexToUintn (PtrPosition);
-  Guid->Data2     = (UINT16)Data;
-
-  //
-  // Data3
-  //
-  PtrBuffer++;
-  PtrPosition     = PtrBuffer;
-  while (*PtrBuffer != L'\0') {
-    if (*PtrBuffer == L'-') {
-      break;
-    }
-    PtrBuffer++;
-  }
-  if (*PtrBuffer == L'\0') {
-    FreePool (Buffer);
-    return EFI_NOT_FOUND;
-  }
-  *PtrBuffer      = L'\0';
-  Data            = StrHexToUintn (PtrPosition);
-  Guid->Data3     = (UINT16)Data;
-
-  //
-  // Data4[0..1]
-  //
-  for ( Index = 0 ; Index < 2 ; Index++) {
-    PtrBuffer++;
-    if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
-      FreePool (Buffer);
-      return EFI_NOT_FOUND;
-    }
-    Digits[0]     = *PtrBuffer;
-    PtrBuffer++;
-    Digits[1]     = *PtrBuffer;
-    Digits[2]     = L'\0';
-    Data          = StrHexToUintn (Digits);
-    Guid->Data4[Index] = (UINT8)Data;
-  }
-
-  //
-  // skip the '-'
-  //
-  PtrBuffer++;
-  if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
-    return EFI_NOT_FOUND;
-  }
-
-  //
-  // Data4[2..7]
-  //
-  for ( ; Index < 8; Index++) {
-    PtrBuffer++;
-    if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
-      FreePool (Buffer);
-      return EFI_NOT_FOUND;
-    }
-    Digits[0]     = *PtrBuffer;
-    PtrBuffer++;
-    Digits[1]     = *PtrBuffer;
-    Digits[2]     = L'\0';
-    Data          = StrHexToUintn (Digits);
-    Guid->Data4[Index] = (UINT8)Data;
-  }
-
-  FreePool (Buffer);
-  
-  return EFI_SUCCESS;
-}
-
 /**
   Worker function that prints an EFI_GUID into specified Buffer.
 
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/11] ShellPkg/Debug1CommandLib: Use StrToGuid/StrHexToBytes in BaseLib
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (7 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 08/11] SecurityPkg/SecureBootConfigDxe: " Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid " Ruiyu Ni
  2017-02-22  4:50 ` [PATCH 11/11] MdeModulePkg/NetLib: Use StrToIpv4/6Address " Ruiyu Ni
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jaben Carsey

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jaben Carsey <jaben.carsey@intel.com>
---
 .../Library/UefiShellDebug1CommandsLib/DmpStore.c  |   5 +-
 .../Library/UefiShellDebug1CommandsLib/SetVar.c    |  10 +-
 .../UefiShellDebug1CommandsLib.c                   | 119 +--------------------
 .../UefiShellDebug1CommandsLib.h                   |  32 +-----
 4 files changed, 7 insertions(+), 159 deletions(-)

diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
index bb2c0b9..e5b91ef 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
@@ -2,7 +2,7 @@
   Main file for DmpStore shell Debug1 function.
    
   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
-  Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -728,8 +728,7 @@ ShellCommandRunDmpStore (
       if (!ShellCommandLineGetFlag(Package, L"-all")) {
         GuidStr = ShellCommandLineGetValue(Package, L"-guid");
         if (GuidStr != NULL) {
-          Status = ConvertStringToGuid(GuidStr, &GuidData);
-          if (EFI_ERROR(Status)) {
+          if (RETURN_ERROR (StrToGuid (GuidStr, &GuidData)) || (GuidStr[GUID_STRING_LENGTH] != L'\0')) {
             ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"dmpstore", GuidStr);  
             ShellStatus = SHELL_INVALID_PARAMETER;
           }
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
index d98a346..7bd7b0f 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
@@ -2,7 +2,7 @@
   Main file for SetVar shell Debug1 function.
 
   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -120,8 +120,7 @@ ShellCommandRunSetVar (
         CopyGuid(&Guid, &gEfiGlobalVariableGuid);
       } else {
         StringGuid = ShellCommandLineGetValue(Package, L"-guid");
-        Status = ConvertStringToGuid(StringGuid, &Guid);
-        if (EFI_ERROR(Status)) {
+        if (RETURN_ERROR (StrToGuid (StringGuid, &Guid)) || (StringGuid[GUID_STRING_LENGTH] != L'\0')) {
           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"setvar", StringGuid);  
           ShellStatus = SHELL_INVALID_PARAMETER;
         }
@@ -207,10 +206,7 @@ ShellCommandRunSetVar (
             if (Buffer == NULL) {
               Status = EFI_OUT_OF_RESOURCES;
             } else {
-              for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {
-                ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);
-                ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));
-              }
+              StrHexToBytes (Data, StrLen (Data), Buffer, StrLen (Data) / 2);
               Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);
             }
             if (EFI_ERROR(Status)) {
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
index 6ebf002..8e2141b 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.c
@@ -1,7 +1,7 @@
 /** @file
   Main file for NULL named library for debug1 profile shell command functions.
 
-  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -172,123 +172,6 @@ GetSystemConfigurationTable (
 }
 
 /**
-  Convert a Unicode character to numerical value.
-
-  This internal function only deal with Unicode character
-  which maps to a valid hexadecimal ASII character, i.e.
-  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
-  Unicode character, the value returned does not make sense.
-
-  @param  Char  The character to convert.
-
-  @return The numerical value converted.
-
-**/
-UINTN
-HexCharToUintn (
-  IN      CHAR16                    Char
-  )
-{
-  if (Char >= L'0' && Char <= L'9') {
-    return Char - L'0';
-  }
-
-  return (UINTN) (10 + CharToUpper (Char) - L'A');
-}
-
-/**
-  Convert a string representation of a guid to a Guid value.
-
-  @param[in] StringGuid    The pointer to the string of a guid.
-  @param[in, out] Guid     The pointer to the GUID structure to populate.
-
-  @retval EFI_INVALID_PARAMETER   A parameter was invalid.
-  @retval EFI_SUCCESS             The conversion was successful.
-**/
-EFI_STATUS
-ConvertStringToGuid (
-  IN CONST CHAR16 *StringGuid,
-  IN OUT EFI_GUID *Guid
-  )
-{
-  CHAR16  *TempCopy;
-  CHAR16  *TempSpot;
-  CHAR16  *Walker;
-  UINT64  TempVal;
-  EFI_STATUS Status;
-
-  if (StringGuid == NULL) {
-    return (EFI_INVALID_PARAMETER);
-  } else if (StrLen(StringGuid) != 36) {
-    return (EFI_INVALID_PARAMETER);
-  } 
-  TempCopy = NULL;
-  TempCopy = StrnCatGrow(&TempCopy, NULL, StringGuid, 0);
-  if (TempCopy == NULL) {
-    return (EFI_OUT_OF_RESOURCES);
-  }
-  Walker   = TempCopy;
-  TempSpot = StrStr(Walker, L"-");
-  if (TempSpot != NULL) {
-    *TempSpot = CHAR_NULL;
-  }
-  Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
-  if (EFI_ERROR(Status)) {
-    FreePool(TempCopy);
-    return (Status);
-  }
-  Guid->Data1 = (UINT32)TempVal;
-  Walker += 9;
-  TempSpot = StrStr(Walker, L"-");
-  if (TempSpot != NULL) {
-    *TempSpot = CHAR_NULL;
-  }
-  Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
-  if (EFI_ERROR(Status)) {
-    FreePool(TempCopy);
-    return (Status);
-  }
-  Guid->Data2 = (UINT16)TempVal;
-  Walker += 5;
-  TempSpot = StrStr(Walker, L"-");
-  if (TempSpot != NULL) {
-    *TempSpot = CHAR_NULL;
-  }
-  Status = ShellConvertStringToUint64(Walker, &TempVal, TRUE, FALSE);
-  if (EFI_ERROR(Status)) {
-    FreePool(TempCopy);
-    return (Status);
-  }
-  Guid->Data3 = (UINT16)TempVal;
-  Walker += 5;
-  Guid->Data4[0] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[0] = (UINT8)(Guid->Data4[0]+ (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[1] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[1] = (UINT8)(Guid->Data4[1] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 3;
-  Guid->Data4[2] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[2] = (UINT8)(Guid->Data4[2] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[3] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[3] = (UINT8)(Guid->Data4[3] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[4] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[4] = (UINT8)(Guid->Data4[4] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[5] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[5] = (UINT8)(Guid->Data4[5] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[6] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[6] = (UINT8)(Guid->Data4[6] + (UINT8)HexCharToUintn(Walker[1]));
-  Walker += 2;
-  Guid->Data4[7] = (UINT8)(HexCharToUintn(Walker[0]) * 16);
-  Guid->Data4[7] = (UINT8)(Guid->Data4[7] + (UINT8)HexCharToUintn(Walker[1]));
-  FreePool(TempCopy);
-  return (EFI_SUCCESS);
-}
-
-/**
   Clear the line at the specified Row.
   
   @param[in] Row                The row number to be cleared ( start from 1 )
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h
index 52ea56a..80a8476 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.h
@@ -1,7 +1,7 @@
 /** @file
   Main file for NULL named library for Profile1 shell command functions.
 
-  Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
@@ -77,36 +77,6 @@ GetSystemConfigurationTable (
   );
 
 /**
-  Convert a string representation of a GUID to the GUID value.
-
-  @param[in]  StringGuid   The pointer to the string containing a GUID printed.
-  @param[in, out] Guid     The pointer to the buffer to get the GUID value.
-**/
-EFI_STATUS
-ConvertStringToGuid (
-  IN CONST CHAR16 *StringGuid,
-  IN OUT EFI_GUID *Guid
-  );
-
-/**
-  Convert a Unicode character to numerical value.
-
-  This internal function only deal with Unicode character
-  which maps to a valid hexadecimal ASII character, i.e.
-  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
-  Unicode character, the value returned does not make sense.
-
-  @param  Char  The character to convert.
-
-  @return The numerical value converted.
-
-**/
-UINTN
-HexCharToUintn (
-  IN      CHAR16                    Char
-  );
-
-/**
   Function for 'setsize' command.
 
   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in BaseLib
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (8 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 09/11] ShellPkg/Debug1CommandLib: Use StrToGuid/StrHexToBytes " Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  2017-02-22  5:28   ` Yao, Jiewen
  2017-02-22  4:50 ` [PATCH 11/11] MdeModulePkg/NetLib: Use StrToIpv4/6Address " Ruiyu Ni
  10 siblings, 1 reply; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Jiewen Yao

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
---
 .../Library/IniParsingLib/IniParsingLib.c          | 141 +--------------------
 1 file changed, 1 insertion(+), 140 deletions(-)

diff --git a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
index 16e1349..e9c2cc5 100644
--- a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
+++ b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
@@ -862,144 +862,6 @@ UpdateGetProfileString (
 }
 
 /**
-  Converts a list of string to a specified buffer.
-
-  @param[out] Buf             The output buffer that contains the string.
-  @param[in]  BufferLength    The length of the buffer
-  @param[in]  Str             The input string that contains the hex number
-
-  @retval EFI_SUCCESS    The string was successfully converted to the buffer.
-
-**/
-EFI_STATUS
-AsciiStrToBuf (
-  OUT UINT8    *Buf,
-  IN  UINTN    BufferLength,
-  IN  CHAR8    *Str
-  )
-{
-  UINTN       Index;
-  UINTN       StrLength;
-  UINT8       Digit;
-  UINT8       Byte;
-
-  Digit = 0;
-
-  //
-  // Two hex char make up one byte
-  //
-  StrLength = BufferLength * 2;
-
-  for(Index = 0; Index < StrLength; Index++, Str++) {
-
-    if ((*Str >= 'a') && (*Str <= 'f')) {
-      Digit = (UINT8) (*Str - 'a' + 0x0A);
-    } else if ((*Str >= 'A') && (*Str <= 'F')) {
-      Digit = (UINT8) (*Str - 'A' + 0x0A);
-    } else if ((*Str >= '0') && (*Str <= '9')) {
-      Digit = (UINT8) (*Str - '0');
-    } else {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    //
-    // For odd characters, write the upper nibble for each buffer byte,
-    // and for even characters, the lower nibble.
-    //
-    if ((Index & 1) == 0) {
-      Byte = (UINT8) (Digit << 4);
-    } else {
-      Byte = Buf[Index / 2];
-      Byte &= 0xF0;
-      Byte = (UINT8) (Byte | Digit);
-    }
-
-    Buf[Index / 2] = Byte;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Converts a string to GUID value.
-  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-
-  @param[in]  Str              The registry format GUID string that contains the GUID value.
-  @param[out] Guid             A pointer to the converted GUID value.
-
-  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.
-  @retval EFI_UNSUPPORTED The input string is not in registry format.
-  @return others          Some error occurred when converting part of GUID value.
-
-**/
-EFI_STATUS
-IniAsciiStrToGuid (
-  IN  CHAR8    *Str,
-  OUT EFI_GUID *Guid
-  )
-{
-  //
-  // Get the first UINT32 data
-  //
-  Guid->Data1 = (UINT32) AsciiStrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the second UINT16 data
-  //
-  Guid->Data2 = (UINT16) AsciiStrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the third UINT16 data
-  //
-  Guid->Data3 = (UINT16) AsciiStrHexToUint64  (Str);
-  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
-    Str ++;
-  }
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // Get the following 8 bytes data
-  //
-  AsciiStrToBuf (&Guid->Data4[0], 2, Str);
-  //
-  // Skip 2 byte hex chars
-  //
-  Str += 2 * 2;
-
-  if (IS_HYPHEN (*Str)) {
-    Str++;
-  } else {
-    return EFI_UNSUPPORTED;
-  }
-  AsciiStrToBuf (&Guid->Data4[2], 6, Str);
-
-  return EFI_SUCCESS;
-}
-
-/**
   Pre process config data buffer into Section entry list and Comment entry list.
 
   @param[in]      DataBuffer      Config raw file buffer.
@@ -1261,8 +1123,7 @@ GetGuidFromDataFile (
   if (!IsValidGuid(Value, AsciiStrLen(Value))) {
     return EFI_NOT_FOUND;
   }
-  Status = IniAsciiStrToGuid(Value, Guid);
-  if (EFI_ERROR (Status)) {
+  if (RETURN_ERROR (AsciiStrToGuid (Value, Guid))) {
     return EFI_NOT_FOUND;
   }
   return EFI_SUCCESS;
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/11] MdeModulePkg/NetLib: Use StrToIpv4/6Address in BaseLib
  2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
                   ` (9 preceding siblings ...)
  2017-02-22  4:50 ` [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid " Ruiyu Ni
@ 2017-02-22  4:50 ` Ruiyu Ni
  10 siblings, 0 replies; 17+ messages in thread
From: Ruiyu Ni @ 2017-02-22  4:50 UTC (permalink / raw)
  To: edk2-devel; +Cc: Siyuan Fu

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
---
 MdeModulePkg/Include/Library/NetLib.h      |   5 +-
 MdeModulePkg/Library/DxeNetLib/DxeNetLib.c | 382 +++--------------------------
 2 files changed, 32 insertions(+), 355 deletions(-)

diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index 09ead09..6773ed5 100644
--- a/MdeModulePkg/Include/Library/NetLib.h
+++ b/MdeModulePkg/Include/Library/NetLib.h
@@ -2,7 +2,7 @@
   This library is only intended to be used by UEFI network stack modules.
   It provides basic functions for the UEFI network stack.
 
-Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at<BR>
@@ -1391,7 +1391,6 @@ NetLibAsciiStrToIp6 (
 
   @retval EFI_SUCCESS            Converted to an IPv4 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is mal-formatted or Ip4Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Failed to perform the operation due to lack of resources.
 
 **/
 EFI_STATUS
@@ -1410,7 +1409,6 @@ NetLibStrToIp4 (
 
   @retval EFI_SUCCESS            Converted to an IPv6 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is malformatted or Ip6Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Failed to perform the operation due to a lack of resources.
 
 **/
 EFI_STATUS
@@ -1431,7 +1429,6 @@ NetLibStrToIp6 (
 
   @retval EFI_SUCCESS            Converted to an  IPv6 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is malformatted, or Ip6Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Failed to perform the operation due to a lack of resources.
 
 **/
 EFI_STATUS
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index 0a7117c..37b89f5 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -1,7 +1,7 @@
 /** @file
   Network library.
 
-Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
@@ -2709,63 +2709,15 @@ NetLibAsciiStrToIp4 (
   OUT      EFI_IPv4_ADDRESS      *Ip4Address
   )
 {
-  UINT8                          Index;
-  CHAR8                          *Ip4Str;
-  CHAR8                          *TempStr;
-  UINTN                          NodeVal;
+  RETURN_STATUS                  Status;
+  CHAR8                          *EndPointer;
 
-  if ((String == NULL) || (Ip4Address == NULL)) {
+  Status = AsciiStrToIpv4Address (String, &EndPointer, Ip4Address, NULL);
+  if (RETURN_ERROR (Status) || (*EndPointer != '\0')) {
     return EFI_INVALID_PARAMETER;
+  } else {
+    return EFI_SUCCESS;
   }
-
-  Ip4Str = (CHAR8 *) String;
-
-  for (Index = 0; Index < 4; Index++) {
-    TempStr = Ip4Str;
-
-    while ((*Ip4Str != '\0') && (*Ip4Str != '.')) {
-      if (Index != 3 && !NET_IS_DIGIT (*Ip4Str)) {
-        return EFI_INVALID_PARAMETER;
-      }
-      
-      //
-      // Allow the IPv4 with prefix case, e.g. 192.168.10.10/24 
-      //
-      if (Index == 3 && !NET_IS_DIGIT (*Ip4Str) && *Ip4Str != '/') {
-        return EFI_INVALID_PARAMETER;
-      }
-      
-      Ip4Str++;
-    }
-
-    //
-    // The IPv4 address is X.X.X.X
-    //
-    if (*Ip4Str == '.') {
-      if (Index == 3) {
-        return EFI_INVALID_PARAMETER;
-      }
-    } else {
-      if (Index != 3) {
-        return EFI_INVALID_PARAMETER;
-      }
-    }
-
-    //
-    // Convert the string to IPv4 address. AsciiStrDecimalToUintn stops at the
-    // first character that is not a valid decimal character, '.' or '\0' here.
-    //
-    NodeVal = AsciiStrDecimalToUintn (TempStr);
-    if (NodeVal > 0xFF) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    Ip4Address->Addr[Index] = (UINT8) NodeVal;
-
-    Ip4Str++;
-  }
-
-  return EFI_SUCCESS;
 }
 
 
@@ -2787,193 +2739,15 @@ NetLibAsciiStrToIp6 (
   OUT      EFI_IPv6_ADDRESS      *Ip6Address
   )
 {
-  UINT8                          Index;
-  CHAR8                          *Ip6Str;
-  CHAR8                          *TempStr;
-  CHAR8                          *TempStr2;
-  UINT8                          NodeCnt;
-  UINT8                          TailNodeCnt;
-  UINT8                          AllowedCnt;
-  UINTN                          NodeVal;
-  BOOLEAN                        Short;
-  BOOLEAN                        Update;
-  BOOLEAN                        LeadZero;
-  UINT8                          LeadZeroCnt;
-  UINT8                          Cnt;
-
-  if ((String == NULL) || (Ip6Address == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Ip6Str      = (CHAR8 *) String;
-  AllowedCnt  = 6;
-  LeadZeroCnt = 0;
-
-  //
-  // An IPv6 address leading with : looks strange.
-  //
-  if (*Ip6Str == ':') {
-    if (*(Ip6Str + 1) != ':') {
-      return EFI_INVALID_PARAMETER;
-    } else {
-      AllowedCnt = 7;
-    }
-  }
+  RETURN_STATUS                  Status;
+  CHAR8                          *EndPointer;
 
-  ZeroMem (Ip6Address, sizeof (EFI_IPv6_ADDRESS));
-
-  NodeCnt     = 0;
-  TailNodeCnt = 0;
-  Short       = FALSE;
-  Update      = FALSE;
-  LeadZero    = FALSE;
-
-  for (Index = 0; Index < 15; Index = (UINT8) (Index + 2)) {
-    TempStr = Ip6Str;
-
-    while ((*Ip6Str != '\0') && (*Ip6Str != ':')) {
-      if (Index != 14 && !NET_IS_HEX (*Ip6Str)) {
-        return EFI_INVALID_PARAMETER;
-      }
-      
-      //
-      // Allow the IPv6 with prefix case, e.g. 2000:aaaa::10/24 
-      //
-      if (Index == 14 && !NET_IS_HEX (*Ip6Str) && *Ip6Str != '/') {
-        return EFI_INVALID_PARAMETER;
-      }
-      
-      Ip6Str++;
-    }
-
-    if ((*Ip6Str == '\0') && (Index != 14)) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    if (*Ip6Str == ':') {
-      if (*(Ip6Str + 1) == ':') {
-        if ((NodeCnt > 6) || 
-            ((*(Ip6Str + 2) != '\0') && (AsciiStrHexToUintn (Ip6Str + 2) == 0))) {
-          //
-          // ::0 looks strange. report error to user.
-          //
-          return EFI_INVALID_PARAMETER;
-        }
-        if ((NodeCnt == 6) && (*(Ip6Str + 2) != '\0') && 
-            (AsciiStrHexToUintn (Ip6Str + 2) != 0)) {
-          return EFI_INVALID_PARAMETER;
-        }
-
-        //
-        // Skip the abbreviation part of IPv6 address.
-        //
-        TempStr2 = Ip6Str + 2;
-        while ((*TempStr2 != '\0')) {
-          if (*TempStr2 == ':') {
-            if (*(TempStr2 + 1) == ':') {
-              //
-              // :: can only appear once in IPv6 address.
-              //
-              return EFI_INVALID_PARAMETER;
-            }
-
-            TailNodeCnt++;
-            if (TailNodeCnt >= (AllowedCnt - NodeCnt)) {
-              //
-              // :: indicates one or more groups of 16 bits of zeros.
-              //
-              return EFI_INVALID_PARAMETER;
-            }
-          }
-
-          TempStr2++;
-        }
-
-        Short  = TRUE;
-        Update = TRUE;
-
-        Ip6Str = Ip6Str + 2;
-      } else {
-        if (*(Ip6Str + 1) == '\0') {
-          return EFI_INVALID_PARAMETER;
-        }
-        Ip6Str++;
-        NodeCnt++;
-        if ((Short && (NodeCnt > 6)) || (!Short && (NodeCnt > 7))) {
-          //
-          // There are more than 8 groups of 16 bits of zeros.
-          //
-          return EFI_INVALID_PARAMETER;
-        }
-      }
-    }
-
-    //
-    // Convert the string to IPv6 address. AsciiStrHexToUintn stops at the first
-    // character that is not a valid hexadecimal character, ':' or '\0' here.
-    //
-    NodeVal = AsciiStrHexToUintn (TempStr);
-    if ((NodeVal > 0xFFFF) || (Index > 14)) {
-      return EFI_INVALID_PARAMETER;
-    }
-    if (NodeVal != 0) {
-      if ((*TempStr  == '0') && 
-          ((*(TempStr + 2) == ':') || (*(TempStr + 3) == ':') || 
-          (*(TempStr + 2) == '\0') || (*(TempStr + 3) == '\0'))) {
-        return EFI_INVALID_PARAMETER;
-      }
-      if ((*TempStr  == '0') && (*(TempStr + 4) != '\0') && 
-          (*(TempStr + 4) != ':')) { 
-        return EFI_INVALID_PARAMETER;
-      }
-    } else {
-      if (((*TempStr  == '0') && (*(TempStr + 1) == '0') && 
-          ((*(TempStr + 2) == ':') || (*(TempStr + 2) == '\0'))) ||
-          ((*TempStr  == '0') && (*(TempStr + 1) == '0') && (*(TempStr + 2) == '0') && 
-          ((*(TempStr + 3) == ':') || (*(TempStr + 3) == '\0')))) {
-        return EFI_INVALID_PARAMETER;
-      }
-    }
-
-    Cnt = 0;
-    while ((TempStr[Cnt] != ':') && (TempStr[Cnt] != '\0')) {
-      Cnt++; 
-    }
-    if (LeadZeroCnt == 0) {
-      if ((Cnt == 4) && (*TempStr  == '0')) {
-        LeadZero = TRUE;
-        LeadZeroCnt++;
-      }
-      if ((Cnt != 0) && (Cnt < 4)) {
-        LeadZero = FALSE;
-        LeadZeroCnt++;
-      }
-    } else {
-      if ((Cnt == 4) && (*TempStr  == '0') && !LeadZero) {
-        return EFI_INVALID_PARAMETER;
-      }
-      if ((Cnt != 0) && (Cnt < 4) && LeadZero) {
-        return EFI_INVALID_PARAMETER;
-      }
-    } 
-
-    Ip6Address->Addr[Index] = (UINT8) (NodeVal >> 8);
-    Ip6Address->Addr[Index + 1] = (UINT8) (NodeVal & 0xFF);
-
-    //
-    // Skip the groups of zeros by ::
-    //
-    if (Short && Update) {
-      Index  = (UINT8) (16 - (TailNodeCnt + 2) * 2);
-      Update = FALSE;
-    }
-  }
-
-  if ((!Short && Index != 16) || (*Ip6Str != '\0')) {
+  Status = AsciiStrToIpv6Address (String, &EndPointer, Ip6Address, NULL);
+  if (RETURN_ERROR (Status) || (*EndPointer != '\0')) {
     return EFI_INVALID_PARAMETER;
+  } else {
+    return EFI_SUCCESS;
   }
-
-  return EFI_SUCCESS;
 }
 
 
@@ -2985,7 +2759,6 @@ NetLibAsciiStrToIp6 (
 
   @retval EFI_SUCCESS            Convert to IPv4 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is mal-formated or Ip4Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Fail to perform the operation due to lack of resource.
 
 **/
 EFI_STATUS
@@ -2995,27 +2768,15 @@ NetLibStrToIp4 (
   OUT      EFI_IPv4_ADDRESS      *Ip4Address
   )
 {
-  CHAR8                          *Ip4Str;
-  UINTN                          StringSize;
-  EFI_STATUS                     Status;
+  RETURN_STATUS                  Status;
+  CHAR16                         *EndPointer;
 
-  if ((String == NULL) || (Ip4Address == NULL)) {
+  Status = StrToIpv4Address (String, &EndPointer, Ip4Address, NULL);
+  if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {
     return EFI_INVALID_PARAMETER;
+  } else {
+    return EFI_SUCCESS;
   }
-
-  StringSize = StrLen (String) + 1;
-  Ip4Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));
-  if (Ip4Str == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  UnicodeStrToAsciiStrS (String, Ip4Str, StringSize);
-
-  Status = NetLibAsciiStrToIp4 (Ip4Str, Ip4Address);
-
-  FreePool (Ip4Str);
-
-  return Status;
 }
 
 
@@ -3028,7 +2789,6 @@ NetLibStrToIp4 (
 
   @retval EFI_SUCCESS            Convert to IPv6 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is mal-formated or Ip6Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Fail to perform the operation due to lack of resource.
 
 **/
 EFI_STATUS
@@ -3038,27 +2798,15 @@ NetLibStrToIp6 (
   OUT      EFI_IPv6_ADDRESS      *Ip6Address
   )
 {
-  CHAR8                          *Ip6Str;
-  UINTN                          StringSize;
-  EFI_STATUS                     Status;
+  RETURN_STATUS                  Status;
+  CHAR16                         *EndPointer;
 
-  if ((String == NULL) || (Ip6Address == NULL)) {
+  Status = StrToIpv6Address (String, &EndPointer, Ip6Address, NULL);
+  if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {
     return EFI_INVALID_PARAMETER;
+  } else {
+    return EFI_SUCCESS;
   }
-
-  StringSize = StrLen (String) + 1;
-  Ip6Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));
-  if (Ip6Str == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  UnicodeStrToAsciiStrS (String, Ip6Str, StringSize);
-
-  Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address);
-
-  FreePool (Ip6Str);
-
-  return Status;
 }
 
 /**
@@ -3072,7 +2820,6 @@ NetLibStrToIp6 (
 
   @retval EFI_SUCCESS            Convert to IPv6 address successfully.
   @retval EFI_INVALID_PARAMETER  The string is mal-formated or Ip6Address is NULL.
-  @retval EFI_OUT_OF_RESOURCES   Fail to perform the operation due to lack of resource.
 
 **/
 EFI_STATUS
@@ -3083,82 +2830,15 @@ NetLibStrToIp6andPrefix (
   OUT      UINT8                 *PrefixLength
   )
 {
-  CHAR8                          *Ip6Str;
-  UINTN                          StringSize;
-  CHAR8                          *PrefixStr;
-  CHAR8                          *TempStr;
-  EFI_STATUS                     Status;
-  UINT8                          Length;
-
-  if ((String == NULL) || (Ip6Address == NULL) || (PrefixLength == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  StringSize = StrLen (String) + 1;
-  Ip6Str = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));
-  if (Ip6Str == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  UnicodeStrToAsciiStrS (String, Ip6Str, StringSize);
-
-  //
-  // Get the sub string describing prefix length.
-  //
-  TempStr = Ip6Str;
-  while (*TempStr != '\0' && (*TempStr != '/')) {
-    TempStr++;
-  }
+  RETURN_STATUS                  Status;
+  CHAR16                         *EndPointer;
 
-  if (*TempStr == '/') {
-    PrefixStr = TempStr + 1;
+  Status = StrToIpv6Address (String, &EndPointer, Ip6Address, PrefixLength);
+  if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) {
+    return EFI_INVALID_PARAMETER;
   } else {
-    PrefixStr = NULL;
-  }
-
-  //
-  // Get the sub string describing IPv6 address and convert it.
-  //
-  *TempStr = '\0';
-
-  Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address);
-  if (EFI_ERROR (Status)) {
-    goto Exit;
-  }
-
-  //
-  // If input string doesn't indicate the prefix length, return 0xff.
-  //
-  Length = 0xFF;
-
-  //
-  // Convert the string to prefix length
-  //
-  if (PrefixStr != NULL) {
-
-    Status = EFI_INVALID_PARAMETER;
-    Length = 0;
-    while (*PrefixStr != '\0') {
-      if (NET_IS_DIGIT (*PrefixStr)) {
-        Length = (UINT8) (Length * 10 + (*PrefixStr - '0'));
-        if (Length > IP6_PREFIX_MAX) {
-          goto Exit;
-        }
-      } else {
-        goto Exit;
-      }
-
-      PrefixStr++;
-    }
+    return EFI_SUCCESS;
   }
-
-  *PrefixLength = Length;
-  Status        = EFI_SUCCESS;
-
-Exit:
-
-  FreePool (Ip6Str);
-  return Status;
 }
 
 /**
-- 
2.9.0.windows.1



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in BaseLib
  2017-02-22  4:50 ` [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid " Ruiyu Ni
@ 2017-02-22  5:28   ` Yao, Jiewen
  2017-02-22  7:40     ` Ni, Ruiyu
  0 siblings, 1 reply; 17+ messages in thread
From: Yao, Jiewen @ 2017-02-22  5:28 UTC (permalink / raw)
  To: Ni, Ruiyu, edk2-devel@lists.01.org

Hi
I do not suggest we use below check.

  if (RETURN_ERROR (AsciiStrToGuid (Value, Guid))) {

I suggest we use below style, because it may help source level debug to see what Status is returned.

  Status = AsciiStrToGuid (Value, Guid);
  if (EFI_ERROR (Status)) {

The suggestion is applied to all patches, such as CapsuleApp


Thank you
Yao Jiewen

> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, February 22, 2017 12:51 PM
> To: edk2-devel@lists.01.org
> Cc: Yao, Jiewen <jiewen.yao@intel.com>
> Subject: [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in
> BaseLib
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> ---
>  .../Library/IniParsingLib/IniParsingLib.c          | 141 +--------------------
>  1 file changed, 1 insertion(+), 140 deletions(-)
>
> diff --git a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> index 16e1349..e9c2cc5 100644
> --- a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> +++ b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> @@ -862,144 +862,6 @@ UpdateGetProfileString (
>  }
>
>  /**
> -  Converts a list of string to a specified buffer.
> -
> -  @param[out] Buf             The output buffer that contains the string.
> -  @param[in]  BufferLength    The length of the buffer
> -  @param[in]  Str             The input string that contains the hex number
> -
> -  @retval EFI_SUCCESS    The string was successfully converted to the buffer.
> -
> -**/
> -EFI_STATUS
> -AsciiStrToBuf (
> -  OUT UINT8    *Buf,
> -  IN  UINTN    BufferLength,
> -  IN  CHAR8    *Str
> -  )
> -{
> -  UINTN       Index;
> -  UINTN       StrLength;
> -  UINT8       Digit;
> -  UINT8       Byte;
> -
> -  Digit = 0;
> -
> -  //
> -  // Two hex char make up one byte
> -  //
> -  StrLength = BufferLength * 2;
> -
> -  for(Index = 0; Index < StrLength; Index++, Str++) {
> -
> -    if ((*Str >= 'a') && (*Str <= 'f')) {
> -      Digit = (UINT8) (*Str - 'a' + 0x0A);
> -    } else if ((*Str >= 'A') && (*Str <= 'F')) {
> -      Digit = (UINT8) (*Str - 'A' + 0x0A);
> -    } else if ((*Str >= '0') && (*Str <= '9')) {
> -      Digit = (UINT8) (*Str - '0');
> -    } else {
> -      return EFI_INVALID_PARAMETER;
> -    }
> -
> -    //
> -    // For odd characters, write the upper nibble for each buffer byte,
> -    // and for even characters, the lower nibble.
> -    //
> -    if ((Index & 1) == 0) {
> -      Byte = (UINT8) (Digit << 4);
> -    } else {
> -      Byte = Buf[Index / 2];
> -      Byte &= 0xF0;
> -      Byte = (UINT8) (Byte | Digit);
> -    }
> -
> -    Buf[Index / 2] = Byte;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Converts a string to GUID value.
> -  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
> -
> -  @param[in]  Str              The registry format GUID string that contains
> the GUID value.
> -  @param[out] Guid             A pointer to the converted GUID value.
> -
> -  @retval EFI_SUCCESS     The GUID string was successfully converted to the
> GUID value.
> -  @retval EFI_UNSUPPORTED The input string is not in registry format.
> -  @return others          Some error occurred when converting part of
> GUID value.
> -
> -**/
> -EFI_STATUS
> -IniAsciiStrToGuid (
> -  IN  CHAR8    *Str,
> -  OUT EFI_GUID *Guid
> -  )
> -{
> -  //
> -  // Get the first UINT32 data
> -  //
> -  Guid->Data1 = (UINT32) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the second UINT16 data
> -  //
> -  Guid->Data2 = (UINT16) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the third UINT16 data
> -  //
> -  Guid->Data3 = (UINT16) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the following 8 bytes data
> -  //
> -  AsciiStrToBuf (&Guid->Data4[0], 2, Str);
> -  //
> -  // Skip 2 byte hex chars
> -  //
> -  Str += 2 * 2;
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -  AsciiStrToBuf (&Guid->Data4[2], 6, Str);
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
>    Pre process config data buffer into Section entry list and Comment entry list.
>
>    @param[in]      DataBuffer      Config raw file buffer.
> @@ -1261,8 +1123,7 @@ GetGuidFromDataFile (
>    if (!IsValidGuid(Value, AsciiStrLen(Value))) {
>      return EFI_NOT_FOUND;
>    }
> -  Status = IniAsciiStrToGuid(Value, Guid);
> -  if (EFI_ERROR (Status)) {
> +  if (RETURN_ERROR (AsciiStrToGuid (Value, Guid))) {
>      return EFI_NOT_FOUND;
>    }
>    return EFI_SUCCESS;
> --
> 2.9.0.windows.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
  2017-02-22  4:50 ` [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address Ruiyu Ni
@ 2017-02-22  6:02   ` Yao, Jiewen
  2017-02-22  7:58     ` Ni, Ruiyu
  0 siblings, 1 reply; 17+ messages in thread
From: Yao, Jiewen @ 2017-02-22  6:02 UTC (permalink / raw)
  To: Ni, Ruiyu, edk2-devel@lists.01.org; +Cc: Gao, Liming, Fu, Siyuan

Thanks.

I suggest we clearly say: This function does not support the leading pad space , which includes spaces or tab characters, before the first valid char.

For example, "    1.2.3.4" is considered as invalid IPv4 address.
And I suggest we return EFI_UNSUPPORTED.

The comment is applied to add [Ascii]StrToGuid/IpV4/IpV6.

Thank you
Yao Jiewen

> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, February 22, 2017 12:51 PM
> To: edk2-devel@lists.01.org
> Cc: Gao, Liming <liming.gao@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>;
> Fu, Siyuan <siyuan.fu@intel.com>
> Subject: [PATCH 04/11] MdePkg/BaseLib: Add
> StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
> 
> The patch adds 4 APIs to convert Unicode string to GUID, bytes
> buffer, IP v4 address and IP v6 address.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Siyuan Fu <siyuan.fu@intel.com>
> ---
>  MdePkg/Include/Library/BaseLib.h    | 241 ++++++++++++++
>  MdePkg/Library/BaseLib/SafeString.c | 623
> ++++++++++++++++++++++++++++++++++++
>  2 files changed, 864 insertions(+)
> 
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index d71ccb7..8aac4c8 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -1536,6 +1536,247 @@ StrHexToUint64 (
>    IN      CONST CHAR16             *String
>    );
> 
> +/**
> +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> +
> +  This function outputs a value of type IPv6_ADDRESS and may output a value
> +  of type UINT8 by interpreting the contents of the Unicode string specified
> +  by String. The format of the input Unicode string String is as follows:
> +
> +                  X:X:X:X:X:X:X:X[/P]
> +
> +  X contains one to four hexadecimal digit characters in the range [0-9], [a-f]
> and
> +  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in
> low
> +  memory address and high byte is stored in high memory address. P contains
> decimal
> +  digit characters in the range [0-9]. The running zero in the beginning of P will
> +  be ignored. /P is optional.
> +
> +  When /P is not in the String, the function stops at the first character that is
> +  not a valid hexadecimal digit character after eight X's are converted.
> +
> +  When /P is in the String, the function stops at the first character that is not
> +  a valid decimal digit character after P is converted.
> +
> +  "::" can be used to compress one or more groups of X when X contains only 0.
> +  The "::" can only appear once in the String.
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Address is NULL, then ASSERT().
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If PcdMaximumUnicodeStringLength is not zero, and String contains more
> than
> +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> +  Null-terminator, then ASSERT().
> +
> +  If EndPointer is not NULL and Address is translated from String, a pointer
> +  to the character that stopped the scan is stored at the location pointed to
> +  by EndPointer.
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  EndPointer               Pointer to character that stops scan.
> +  @param  Address                  Pointer to the converted IPv6
> address.
> +  @param  PrefixLength             Pointer to the converted IPv6 address
> prefix
> +                                   length. MAX_UINT8 is returned when
> /P is
> +                                   not in the String.
> +
> +  @retval RETURN_SUCCESS           Address is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If PcdMaximumUnicodeStringLength is
> not
> +                                    zero, and String contains more than
> +                                    PcdMaximumUnicodeStringLength
> Unicode
> +                                    characters, not including the
> +                                    Null-terminator.
> +                                   If X contains more than four
> hexadecimal
> +                                    digit characters.
> +                                   If String contains "::" and number of X
> +                                    is not less than 8.
> +                                   If P starts with character that is not a
> +                                    valid decimal digit character.
> +                                   If the decimal number converted from
> P
> +                                    exceeds 128.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToIpv6Address (
> +  IN  CONST CHAR16       *String,
> +  OUT CHAR16             **EndPointer, OPTIONAL
> +  OUT IPv6_ADDRESS       *Address,
> +  OUT UINT8              *PrefixLength OPTIONAL
> +  );
> +
> +/**
> +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> +
> +  This function outputs a value of type IPv4_ADDRESS and may output a value
> +  of type UINT8 by interpreting the contents of the Unicode string specified
> +  by String. The format of the input Unicode string String is as follows:
> +
> +                  D.D.D.D[/P]
> +
> +  D and P are decimal digit characters in the range [0-9]. The running zero in
> +  the beginning of D and P will be ignored. /P is optional.
> +
> +  When /P is not in the String, the function stops at the first character that is
> +  not a valid decimal digit character after four D's are converted.
> +
> +  When /P is in the String, the function stops at the first character that is not
> +  a valid decimal digit character after P is converted.
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Address is NULL, then ASSERT().
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If PcdMaximumUnicodeStringLength is not zero, and String contains more
> than
> +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> +  Null-terminator, then ASSERT().
> +
> +  If EndPointer is not NULL and Address is translated from String, a pointer
> +  to the character that stopped the scan is stored at the location pointed to
> +  by EndPointer.
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  EndPointer               Pointer to character that stops scan.
> +  @param  Address                  Pointer to the converted IPv4
> address.
> +  @param  PrefixLength             Pointer to the converted IPv4 address
> prefix
> +                                   length. MAX_UINT8 is returned when
> /P is
> +                                   not in the String.
> +
> +  @retval RETURN_SUCCESS           Address is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If PcdMaximumUnicodeStringLength is
> not
> +                                    zero, and String contains more than
> +                                    PcdMaximumUnicodeStringLength
> Unicode
> +                                    characters, not including the
> +                                    Null-terminator.
> +                                   If String is not in the correct format.
> +                                   If any decimal number converted from
> D
> +                                    exceeds 255.
> +                                   If the decimal number converted from
> P
> +                                    exceeds 32.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToIpv4Address (
> +  IN  CONST CHAR16       *String,
> +  OUT CHAR16             **EndPointer, OPTIONAL
> +  OUT IPv4_ADDRESS       *Address,
> +  OUT UINT8              *PrefixLength OPTIONAL
> +  );
> +
> +#define GUID_STRING_LENGTH  36
> +
> +/**
> +  Convert a Null-terminated Unicode GUID string to a value of type
> +  EFI_GUID.
> +
> +  This function outputs a GUID value by interpreting the contents of
> +  the Unicode string specified by String. The format of the input
> +  Unicode string String consists of 36 characters, as follows:
> +
> +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> +
> +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> +  [A-F], with each pair representing a single byte hexadecimal value.
> +
> +  The mapping between String and the EFI_GUID structure is as follows:
> +                  aa          Data1[24:31]
> +                  bb          Data1[16:23]
> +                  cc          Data1[8:15]
> +                  dd          Data1[0:7]
> +                  ee          Data2[8:15]
> +                  ff          Data2[0:7]
> +                  gg          Data3[8:15]
> +                  hh          Data3[0:7]
> +                  ii          Data4[0:7]
> +                  jj          Data4[8:15]
> +                  kk          Data4[16:23]
> +                  ll          Data4[24:31]
> +                  mm          Data4[32:39]
> +                  nn          Data4[40:47]
> +                  oo          Data4[48:55]
> +                  pp          Data4[56:63]
> +
> +  If String is NULL, then ASSERT().
> +  If Guid is NULL, then ASSERT().
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  Guid                     Pointer to the converted GUID.
> +
> +  @retval RETURN_SUCCESS           Guid is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If String is not as the above format.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToGuid (
> +  IN  CONST CHAR16       *String,
> +  OUT GUID               *Guid
> +  );
> +
> +/**
> +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> +
> +  This function outputs a byte array by interpreting the contents of
> +  the Unicode string specified by String in hexadecimal format. The format of
> +  the input Unicode string String is:
> +
> +                  [XX]*
> +
> +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> +  The function decodes every two hexadecimal digit characters as one byte.
> The
> +  decoding stops after Length of characters and outputs Buffer containing
> +  (Length / 2) bytes.
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Buffer is NULL, then ASSERT().
> +
> +  If Length is not multiple of 2, then ASSERT().
> +
> +  If PcdMaximumStringLength is not zero and Length is greater than
> +  PcdMaximumAsciiStringLength, then ASSERT().
> +
> +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  Length                   The number of Unicode characters to
> decode.
> +  @param  Buffer                   Pointer to the converted bytes array.
> +  @param  MaxBufferSize            The maximum size of Buffer.
> +
> +  @retval RETURN_SUCCESS           Buffer is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If Length is not multiple of 2.
> +                                   If PcdMaximumStringLength is not
> zero,
> +                                    and Length is greater than
> +                                    PcdMaximumAsciiStringLength.
> +                                   If Length of characters from String
> contain
> +                                    a character that is not valid
> hexadecimal
> +                                    digit characters, or a Null-terminator.
> +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> (Length / 2).
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrHexToBytes (
> +  IN  CONST CHAR16       *String,
> +  IN  UINTN              Length,
> +  OUT UINT8              *Buffer,
> +  IN  UINTN              MaxBufferSize
> +  );
> +
>  #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
> 
>  /**
> diff --git a/MdePkg/Library/BaseLib/SafeString.c
> b/MdePkg/Library/BaseLib/SafeString.c
> index 315059e..ede1c99 100644
> --- a/MdePkg/Library/BaseLib/SafeString.c
> +++ b/MdePkg/Library/BaseLib/SafeString.c
> @@ -1074,6 +1074,629 @@ StrHexToUint64S (
>  }
> 
>  /**
> +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> +
> +  This function outputs a value of type IPv6_ADDRESS and may output a value
> +  of type UINT8 by interpreting the contents of the Unicode string specified
> +  by String. The format of the input Unicode string String is as follows:
> +
> +                  X:X:X:X:X:X:X:X[/P]
> +
> +  X contains one to four hexadecimal digit characters in the range [0-9], [a-f]
> and
> +  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in
> low
> +  memory address and high byte is stored in high memory address. P contains
> decimal
> +  digit characters in the range [0-9]. The running zero in the beginning of P will
> +  be ignored. /P is optional.
> +
> +  When /P is not in the String, the function stops at the first character that is
> +  not a valid hexadecimal digit character after eight X's are converted.
> +
> +  When /P is in the String, the function stops at the first character that is not
> +  a valid decimal digit character after P is converted.
> +
> +  "::" can be used to compress one or more groups of X when X contains only 0.
> +  The "::" can only appear once in the String.
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Address is NULL, then ASSERT().
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If PcdMaximumUnicodeStringLength is not zero, and String contains more
> than
> +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> +  Null-terminator, then ASSERT().
> +
> +  If EndPointer is not NULL and Address is translated from String, a pointer
> +  to the character that stopped the scan is stored at the location pointed to
> +  by EndPointer.
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  EndPointer               Pointer to character that stops scan.
> +  @param  Address                  Pointer to the converted IPv6
> address.
> +  @param  PrefixLength             Pointer to the converted IPv6 address
> prefix
> +                                   length. MAX_UINT8 is returned when
> /P is
> +                                   not in the String.
> +
> +  @retval RETURN_SUCCESS           Address is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If PcdMaximumUnicodeStringLength is
> not
> +                                    zero, and String contains more than
> +                                    PcdMaximumUnicodeStringLength
> Unicode
> +                                    characters, not including the
> +                                    Null-terminator.
> +                                   If X contains more than four
> hexadecimal
> +                                    digit characters.
> +                                   If String contains "::" and number of X
> +                                    is not less than 8.
> +                                   If P starts with character that is not a
> +                                    valid decimal digit character.
> +                                   If the decimal number converted from
> P
> +                                    exceeds 128.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToIpv6Address (
> +  IN  CONST CHAR16       *String,
> +  OUT CHAR16             **EndPointer, OPTIONAL
> +  OUT IPv6_ADDRESS       *Address,
> +  OUT UINT8              *PrefixLength OPTIONAL
> +  )
> +{
> +  RETURN_STATUS          Status;
> +  UINTN                  AddressIndex;
> +  UINTN                  Uintn;
> +  IPv6_ADDRESS           LocalAddress;
> +  UINT8                  LocalPrefixLength;
> +  CONST CHAR16           *Pointer;
> +  CHAR16                 *End;
> +  UINTN                  CompressStart;
> +  BOOLEAN                ExpectPrefix;
> +
> +  LocalPrefixLength = MAX_UINT8;
> +  CompressStart     = ARRAY_SIZE (Address->Addr);
> +  ExpectPrefix      = FALSE;
> +
> +  ASSERT (((UINTN) String & BIT0) == 0);
> +
> +  //
> +  // 1. None of String or Guid shall be a null pointer.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> RETURN_INVALID_PARAMETER);
> +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> RETURN_INVALID_PARAMETER);
> +
> +  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE
> (Address->Addr) + 1;) {
> +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> +      if (*Pointer != L':') {
> +        //
> +        // ":" or "/" should be followed by digit characters.
> +        //
> +        return RETURN_INVALID_PARAMETER;
> +      }
> +
> +      //
> +      // Meet second ":" after previous ":" or "/"
> +      // or meet first ":" in the beginning of String.
> +      //
> +      if (ExpectPrefix) {
> +        //
> +        // ":" shall not be after "/"
> +        //
> +        return RETURN_INVALID_PARAMETER;
> +      }
> +
> +      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex ==
> ARRAY_SIZE (Address->Addr)) {
> +        //
> +        // "::" can only appear once.
> +        // "::" can only appear when address is not full length.
> +        //
> +        return RETURN_INVALID_PARAMETER;
> +      } else {
> +        //
> +        // Remember the start of zero compressing.
> +        //
> +        CompressStart = AddressIndex;
> +        Pointer++;
> +
> +        if (CompressStart == 0) {
> +          if (*Pointer != L':') {
> +            //
> +            // Single ":" shall not be in the beginning of String.
> +            //
> +            return RETURN_INVALID_PARAMETER;
> +          }
> +          Pointer++;
> +        }
> +      }
> +    }
> +
> +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> +      if (*Pointer == L'/') {
> +        //
> +        // Might be optional "/P" after "::".
> +        //
> +        if (CompressStart != AddressIndex) {
> +          return RETURN_INVALID_PARAMETER;
> +        }
> +      } else {
> +        break;
> +      }
> +    } else {
> +      if (!ExpectPrefix) {
> +        //
> +        // Get X.
> +        //
> +        Status = StrHexToUintnS (Pointer, &End, &Uintn);
> +        if (RETURN_ERROR (Status) || End - Pointer > 4) {
> +          //
> +          // Number of hexadecimal digit characters is no more than 4.
> +          //
> +          return RETURN_INVALID_PARAMETER;
> +        }
> +        Pointer = End;
> +        //
> +        // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit
> characters is no more than 4.
> +        //
> +        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
> +        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
> +        AddressIndex += 2;
> +      } else {
> +        //
> +        // Get P, then exit the loop.
> +        //
> +        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
> +        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
> +          //
> +          // Prefix length should not exceed 128.
> +          //
> +          return RETURN_INVALID_PARAMETER;
> +        }
> +        LocalPrefixLength = (UINT8) Uintn;
> +        Pointer = End;
> +        break;
> +      }
> +    }
> +
> +    //
> +    // Skip ':' or "/"
> +    //
> +    if (*Pointer == L'/') {
> +      ExpectPrefix = TRUE;
> +    } else if (*Pointer == L':') {
> +      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> +        //
> +        // Meet additional ":" after all 8 16-bit address
> +        //
> +        break;
> +      }
> +    } else {
> +      //
> +      // Meet other character that is not "/" or ":" after all 8 16-bit address
> +      //
> +      break;
> +    }
> +    Pointer++;
> +  }
> +
> +  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart !=
> ARRAY_SIZE (Address->Addr)) ||
> +    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart ==
> ARRAY_SIZE (Address->Addr))
> +      ) {
> +    //
> +    // Full length of address shall not have compressing zeros.
> +    // Non-full length of address shall have compressing zeros.
> +    //
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
> +  ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) -
> AddressIndex);
> +  CopyMem (
> +    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) -
> AddressIndex],
> +    &LocalAddress.Addr[CompressStart],
> +    AddressIndex - CompressStart
> +    );
> +
> +  if (PrefixLength != NULL) {
> +    *PrefixLength = LocalPrefixLength;
> +  }
> +  if (EndPointer != NULL) {
> +    *EndPointer = (CHAR16 *) Pointer;
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> +
> +  This function outputs a value of type IPv4_ADDRESS and may output a value
> +  of type UINT8 by interpreting the contents of the Unicode string specified
> +  by String. The format of the input Unicode string String is as follows:
> +
> +                  D.D.D.D[/P]
> +
> +  D and P are decimal digit characters in the range [0-9]. The running zero in
> +  the beginning of D and P will be ignored. /P is optional.
> +
> +  When /P is not in the String, the function stops at the first character that is
> +  not a valid decimal digit character after four D's are converted.
> +
> +  When /P is in the String, the function stops at the first character that is not
> +  a valid decimal digit character after P is converted.
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Address is NULL, then ASSERT().
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If PcdMaximumUnicodeStringLength is not zero, and String contains more
> than
> +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> +  Null-terminator, then ASSERT().
> +
> +  If EndPointer is not NULL and Address is translated from String, a pointer
> +  to the character that stopped the scan is stored at the location pointed to
> +  by EndPointer.
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  EndPointer               Pointer to character that stops scan.
> +  @param  Address                  Pointer to the converted IPv4
> address.
> +  @param  PrefixLength             Pointer to the converted IPv4 address
> prefix
> +                                   length. MAX_UINT8 is returned when
> /P is
> +                                   not in the String.
> +
> +  @retval RETURN_SUCCESS           Address is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If PcdMaximumUnicodeStringLength is
> not
> +                                    zero, and String contains more than
> +                                    PcdMaximumUnicodeStringLength
> Unicode
> +                                    characters, not including the
> +                                    Null-terminator.
> +                                   If String is not in the correct format.
> +                                   If any decimal number converted from
> D
> +                                    exceeds 255.
> +                                   If the decimal number converted from
> P
> +                                    exceeds 32.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToIpv4Address (
> +  IN  CONST CHAR16       *String,
> +  OUT CHAR16             **EndPointer, OPTIONAL
> +  OUT IPv4_ADDRESS       *Address,
> +  OUT UINT8              *PrefixLength OPTIONAL
> +  )
> +{
> +  RETURN_STATUS          Status;
> +  UINTN                  AddressIndex;
> +  UINTN                  Uintn;
> +  IPv4_ADDRESS           LocalAddress;
> +  UINT8                  LocalPrefixLength;
> +  CHAR16                 *Pointer;
> +
> +  LocalPrefixLength = MAX_UINT8;
> +
> +  ASSERT (((UINTN) String & BIT0) == 0);
> +
> +  //
> +  // 1. None of String or Guid shall be a null pointer.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> RETURN_INVALID_PARAMETER);
> +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> RETURN_INVALID_PARAMETER);
> +
> +  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex <
> ARRAY_SIZE (Address->Addr) + 1;) {
> +    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
> +      //
> +      // D or P contains invalid characters.
> +      //
> +      break;
> +    }
> +
> +    //
> +    // Get D or P.
> +    //
> +    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer,
> &Uintn);
> +    if (RETURN_ERROR (Status)) {
> +      return RETURN_INVALID_PARAMETER;
> +    }
> +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> +      //
> +      // It's P.
> +      //
> +      if (Uintn > 32) {
> +        return RETURN_INVALID_PARAMETER;
> +      }
> +      LocalPrefixLength = (UINT8) Uintn;
> +    } else {
> +      //
> +      // It's D.
> +      //
> +      if (Uintn > MAX_UINT8) {
> +        return RETURN_INVALID_PARAMETER;
> +      }
> +      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
> +      AddressIndex++;
> +    }
> +
> +    //
> +    // Check the '.' or '/', depending on the AddressIndex.
> +    //
> +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> +      if (*Pointer == L'/') {
> +        //
> +        // '/P' is in the String.
> +        // Skip "/" and get P in next loop.
> +        //
> +        Pointer++;
> +      } else {
> +        //
> +        // '/P' is not in the String.
> +        //
> +        break;
> +      }
> +    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> +      if (*Pointer == L'.') {
> +        //
> +        // D should be followed by '.'
> +        //
> +        Pointer++;
> +      } else {
> +        return RETURN_INVALID_PARAMETER;
> +      }
> +    }
> +  }
> +
> +  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  CopyMem (Address, &LocalAddress, sizeof (*Address));
> +  if (PrefixLength != NULL) {
> +    *PrefixLength = LocalPrefixLength;
> +  }
> +  if (EndPointer != NULL) {
> +    *EndPointer = Pointer;
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Convert a Null-terminated Unicode GUID string to a value of type
> +  EFI_GUID.
> +
> +  This function outputs a GUID value by interpreting the contents of
> +  the Unicode string specified by String. The format of the input
> +  Unicode string String consists of 36 characters, as follows:
> +
> +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> +
> +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> +  [A-F], with each pair representing a single byte hexadecimal value.
> +
> +  The mapping between String and the EFI_GUID structure is as follows:
> +                  aa          Data1[24:31]
> +                  bb          Data1[16:23]
> +                  cc          Data1[8:15]
> +                  dd          Data1[0:7]
> +                  ee          Data2[8:15]
> +                  ff          Data2[0:7]
> +                  gg          Data3[8:15]
> +                  hh          Data3[0:7]
> +                  ii          Data4[0:7]
> +                  jj          Data4[8:15]
> +                  kk          Data4[16:23]
> +                  ll          Data4[24:31]
> +                  mm          Data4[32:39]
> +                  nn          Data4[40:47]
> +                  oo          Data4[48:55]
> +                  pp          Data4[56:63]
> +
> +  If String is NULL, then ASSERT().
> +  If Guid is NULL, then ASSERT().
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  Guid                     Pointer to the converted GUID.
> +
> +  @retval RETURN_SUCCESS           Guid is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If String is not as the above format.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrToGuid (
> +  IN  CONST CHAR16       *String,
> +  OUT GUID               *Guid
> +  )
> +{
> +  RETURN_STATUS          Status;
> +  GUID                   LocalGuid;
> +
> +  ASSERT (((UINTN) String & BIT0) == 0);
> +
> +  //
> +  // 1. None of String or Guid shall be a null pointer.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> RETURN_INVALID_PARAMETER);
> +  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL),
> RETURN_INVALID_PARAMETER);
> +
> +  //
> +  // Get aabbccdd in big-endian.
> +  //
> +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *)
> &LocalGuid.Data1, sizeof (LocalGuid.Data1));
> +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +  //
> +  // Convert big-endian to little-endian.
> +  //
> +  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
> +  String += 2 * sizeof (LocalGuid.Data1) + 1;
> +
> +  //
> +  // Get eeff in big-endian.
> +  //
> +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *)
> &LocalGuid.Data2, sizeof (LocalGuid.Data2));
> +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +  //
> +  // Convert big-endian to little-endian.
> +  //
> +  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
> +  String += 2 * sizeof (LocalGuid.Data2) + 1;
> +
> +  //
> +  // Get gghh in big-endian.
> +  //
> +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *)
> &LocalGuid.Data3, sizeof (LocalGuid.Data3));
> +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +  //
> +  // Convert big-endian to little-endian.
> +  //
> +  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
> +  String += 2 * sizeof (LocalGuid.Data3) + 1;
> +
> +  //
> +  // Get iijj.
> +  //
> +  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
> +  if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +  String += 2 * 2 + 1;
> +
> +  //
> +  // Get kkllmmnnoopp.
> +  //
> +  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
> +  if (RETURN_ERROR (Status)) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  CopyGuid (Guid, &LocalGuid);
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> +
> +  This function outputs a byte array by interpreting the contents of
> +  the Unicode string specified by String in hexadecimal format. The format of
> +  the input Unicode string String is:
> +
> +                  [XX]*
> +
> +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> +  The function decodes every two hexadecimal digit characters as one byte.
> The
> +  decoding stops after Length of characters and outputs Buffer containing
> +  (Length / 2) bytes.
> +
> +  If String is not aligned in a 16-bit boundary, then ASSERT().
> +
> +  If String is NULL, then ASSERT().
> +
> +  If Buffer is NULL, then ASSERT().
> +
> +  If Length is not multiple of 2, then ASSERT().
> +
> +  If PcdMaximumStringLength is not zero and Length is greater than
> +  PcdMaximumAsciiStringLength, then ASSERT().
> +
> +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> +
> +  @param  String                   Pointer to a Null-terminated Unicode
> string.
> +  @param  Length                   The number of Unicode characters to
> decode.
> +  @param  Buffer                   Pointer to the converted bytes array.
> +  @param  MaxBufferSize            The maximum size of Buffer.
> +
> +  @retval RETURN_SUCCESS           Buffer is translated from String.
> +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> +                                   If Data is NULL.
> +                                   If Length is not multiple of 2.
> +                                   If PcdMaximumStringLength is not
> zero,
> +                                    and Length is greater than
> +                                    PcdMaximumAsciiStringLength.
> +                                   If Length of characters from String
> contain
> +                                    a character that is not valid
> hexadecimal
> +                                    digit characters, or a Null-terminator.
> +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> (Length / 2).
> +**/
> +RETURN_STATUS
> +EFIAPI
> +StrHexToBytes (
> +  IN  CONST CHAR16       *String,
> +  IN  UINTN              Length,
> +  OUT UINT8              *Buffer,
> +  IN  UINTN              MaxBufferSize
> +  )
> +{
> +  UINTN                  Index;
> +
> +  ASSERT (((UINTN) String & BIT0) == 0);
> +
> +  //
> +  // 1. None of String or Buffer shall be a null pointer.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> RETURN_INVALID_PARAMETER);
> +  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL),
> RETURN_INVALID_PARAMETER);
> +
> +  //
> +  // 2. Length shall not be greater than RSIZE_MAX.
> +  //
> +  if (RSIZE_MAX != 0) {
> +    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX),
> RETURN_INVALID_PARAMETER);
> +  }
> +
> +  //
> +  // 3. Length shall not be odd.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0),
> RETURN_INVALID_PARAMETER);
> +
> +  //
> +  // 4. MaxBufferSize shall equal to or greater than Length / 2.
> +  //
> +  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2),
> RETURN_BUFFER_TOO_SMALL);
> +
> +  //
> +  // 5. String shall not contains invalid hexadecimal digits.
> +  //
> +  for (Index = 0; Index < Length; Index++) {
> +    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
> +      break;
> +    }
> +  }
> +  if (Index != Length) {
> +    return RETURN_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Convert the hex string to bytes.
> +  //
> +  for(Index = 0; Index < Length; Index++) {
> +
> +    //
> +    // For even characters, write the upper nibble for each buffer byte,
> +    // and for even characters, the lower nibble.
> +    //
> +    if ((Index & BIT0) == 0) {
> +      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn (String[Index]) <<
> 4;
> +    } else {
> +      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
> +    }
> +  }
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
>    Returns the length of a Null-terminated Ascii string.
> 
>    This function is similar as strlen_s defined in C11.
> --
> 2.9.0.windows.1



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in BaseLib
  2017-02-22  5:28   ` Yao, Jiewen
@ 2017-02-22  7:40     ` Ni, Ruiyu
  0 siblings, 0 replies; 17+ messages in thread
From: Ni, Ruiyu @ 2017-02-22  7:40 UTC (permalink / raw)
  To: Yao, Jiewen, edk2-devel@lists.01.org

Can we use EFI_STATUS variable to receive RETURN_STATUS type of value?

Thanks/Ray

From: Yao, Jiewen
Sent: Wednesday, February 22, 2017 1:28 PM
To: Ni, Ruiyu <ruiyu.ni@intel.com>; edk2-devel@lists.01.org
Subject: RE: [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in BaseLib

Hi
I do not suggest we use below check.

  if (RETURN_ERROR (AsciiStrToGuid (Value, Guid))) {

I suggest we use below style, because it may help source level debug to see what Status is returned.

  Status = AsciiStrToGuid (Value, Guid);
  if (EFI_ERROR (Status)) {

The suggestion is applied to all patches, such as CapsuleApp


Thank you
Yao Jiewen

> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, February 22, 2017 12:51 PM
> To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> Subject: [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid in
> BaseLib
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> Cc: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> ---
>  .../Library/IniParsingLib/IniParsingLib.c          | 141 +--------------------
>  1 file changed, 1 insertion(+), 140 deletions(-)
>
> diff --git a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> index 16e1349..e9c2cc5 100644
> --- a/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> +++ b/SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.c
> @@ -862,144 +862,6 @@ UpdateGetProfileString (
>  }
>
>  /**
> -  Converts a list of string to a specified buffer.
> -
> -  @param[out] Buf             The output buffer that contains the string.
> -  @param[in]  BufferLength    The length of the buffer
> -  @param[in]  Str             The input string that contains the hex number
> -
> -  @retval EFI_SUCCESS    The string was successfully converted to the buffer.
> -
> -**/
> -EFI_STATUS
> -AsciiStrToBuf (
> -  OUT UINT8    *Buf,
> -  IN  UINTN    BufferLength,
> -  IN  CHAR8    *Str
> -  )
> -{
> -  UINTN       Index;
> -  UINTN       StrLength;
> -  UINT8       Digit;
> -  UINT8       Byte;
> -
> -  Digit = 0;
> -
> -  //
> -  // Two hex char make up one byte
> -  //
> -  StrLength = BufferLength * 2;
> -
> -  for(Index = 0; Index < StrLength; Index++, Str++) {
> -
> -    if ((*Str >= 'a') && (*Str <= 'f')) {
> -      Digit = (UINT8) (*Str - 'a' + 0x0A);
> -    } else if ((*Str >= 'A') && (*Str <= 'F')) {
> -      Digit = (UINT8) (*Str - 'A' + 0x0A);
> -    } else if ((*Str >= '0') && (*Str <= '9')) {
> -      Digit = (UINT8) (*Str - '0');
> -    } else {
> -      return EFI_INVALID_PARAMETER;
> -    }
> -
> -    //
> -    // For odd characters, write the upper nibble for each buffer byte,
> -    // and for even characters, the lower nibble.
> -    //
> -    if ((Index & 1) == 0) {
> -      Byte = (UINT8) (Digit << 4);
> -    } else {
> -      Byte = Buf[Index / 2];
> -      Byte &= 0xF0;
> -      Byte = (UINT8) (Byte | Digit);
> -    }
> -
> -    Buf[Index / 2] = Byte;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Converts a string to GUID value.
> -  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
> -
> -  @param[in]  Str              The registry format GUID string that contains
> the GUID value.
> -  @param[out] Guid             A pointer to the converted GUID value.
> -
> -  @retval EFI_SUCCESS     The GUID string was successfully converted to the
> GUID value.
> -  @retval EFI_UNSUPPORTED The input string is not in registry format.
> -  @return others          Some error occurred when converting part of
> GUID value.
> -
> -**/
> -EFI_STATUS
> -IniAsciiStrToGuid (
> -  IN  CHAR8    *Str,
> -  OUT EFI_GUID *Guid
> -  )
> -{
> -  //
> -  // Get the first UINT32 data
> -  //
> -  Guid->Data1 = (UINT32) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the second UINT16 data
> -  //
> -  Guid->Data2 = (UINT16) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the third UINT16 data
> -  //
> -  Guid->Data3 = (UINT16) AsciiStrHexToUint64  (Str);
> -  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
> -    Str ++;
> -  }
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  //
> -  // Get the following 8 bytes data
> -  //
> -  AsciiStrToBuf (&Guid->Data4[0], 2, Str);
> -  //
> -  // Skip 2 byte hex chars
> -  //
> -  Str += 2 * 2;
> -
> -  if (IS_HYPHEN (*Str)) {
> -    Str++;
> -  } else {
> -    return EFI_UNSUPPORTED;
> -  }
> -  AsciiStrToBuf (&Guid->Data4[2], 6, Str);
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
>    Pre process config data buffer into Section entry list and Comment entry list.
>
>    @param[in]      DataBuffer      Config raw file buffer.
> @@ -1261,8 +1123,7 @@ GetGuidFromDataFile (
>    if (!IsValidGuid(Value, AsciiStrLen(Value))) {
>      return EFI_NOT_FOUND;
>    }
> -  Status = IniAsciiStrToGuid(Value, Guid);
> -  if (EFI_ERROR (Status)) {
> +  if (RETURN_ERROR (AsciiStrToGuid (Value, Guid))) {
>      return EFI_NOT_FOUND;
>    }
>    return EFI_SUCCESS;
> --
> 2.9.0.windows.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
  2017-02-22  6:02   ` Yao, Jiewen
@ 2017-02-22  7:58     ` Ni, Ruiyu
  2017-02-22  8:14       ` Yao, Jiewen
  0 siblings, 1 reply; 17+ messages in thread
From: Ni, Ruiyu @ 2017-02-22  7:58 UTC (permalink / raw)
  To: Yao, Jiewen, edk2-devel@lists.01.org; +Cc: Gao, Liming, Fu, Siyuan

Jiewen,
If we returns Unsupported for "   1.2.3.4".
What shall we return for "    1.2.3"?
If we need to return Invalid Parameter for "   1.2.3", the implementation has to check whether it's a valid IP address after spaces, or an invalid IP address.

Can you just return Invalid Parameter for all cases?

Thanks/Ray

> -----Original Message-----
> From: Yao, Jiewen
> Sent: Wednesday, February 22, 2017 2:02 PM
> To: Ni, Ruiyu <ruiyu.ni@intel.com>; edk2-devel@lists.01.org
> Cc: Gao, Liming <liming.gao@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> Subject: RE: [PATCH 04/11] MdePkg/BaseLib: Add
> StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
> 
> Thanks.
> 
> I suggest we clearly say: This function does not support the leading pad space ,
> which includes spaces or tab characters, before the first valid char.
> 
> For example, "    1.2.3.4" is considered as invalid IPv4 address.
> And I suggest we return EFI_UNSUPPORTED.
> 
> The comment is applied to add [Ascii]StrToGuid/IpV4/IpV6.
> 
> Thank you
> Yao Jiewen
> 
> > -----Original Message-----
> > From: Ni, Ruiyu
> > Sent: Wednesday, February 22, 2017 12:51 PM
> > To: edk2-devel@lists.01.org
> > Cc: Gao, Liming <liming.gao@intel.com>; Yao, Jiewen
> > <jiewen.yao@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > Subject: [PATCH 04/11] MdePkg/BaseLib: Add
> > StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
> >
> > The patch adds 4 APIs to convert Unicode string to GUID, bytes buffer,
> > IP v4 address and IP v6 address.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Siyuan Fu <siyuan.fu@intel.com>
> > ---
> >  MdePkg/Include/Library/BaseLib.h    | 241 ++++++++++++++
> >  MdePkg/Library/BaseLib/SafeString.c | 623
> > ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 864 insertions(+)
> >
> > diff --git a/MdePkg/Include/Library/BaseLib.h
> > b/MdePkg/Include/Library/BaseLib.h
> > index d71ccb7..8aac4c8 100644
> > --- a/MdePkg/Include/Library/BaseLib.h
> > +++ b/MdePkg/Include/Library/BaseLib.h
> > @@ -1536,6 +1536,247 @@ StrHexToUint64 (
> >    IN      CONST CHAR16             *String
> >    );
> >
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> > +
> > +  This function outputs a value of type IPv6_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  X:X:X:X:X:X:X:X[/P]
> > +
> > +  X contains one to four hexadecimal digit characters in the range
> > + [0-9], [a-f]
> > and
> > +  [A-F]. X is converted to a value of type UINT16, whose low byte is
> > + stored in
> > low
> > +  memory address and high byte is stored in high memory address. P
> > + contains
> > decimal
> > +  digit characters in the range [0-9]. The running zero in the
> > + beginning of P will  be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid hexadecimal digit character after eight X's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  "::" can be used to compress one or more groups of X when X contains only
> 0.
> > +  The "::" can only appear once in the String.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv6
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv6 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If X contains more than four
> > hexadecimal
> > +                                    digit characters.
> > +                                   If String contains "::" and number of X
> > +                                    is not less than 8.
> > +                                   If P starts with character that is not a
> > +                                    valid decimal digit character.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 128.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv6Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv6_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  );
> > +
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> > +
> > +  This function outputs a value of type IPv4_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  D.D.D.D[/P]
> > +
> > +  D and P are decimal digit characters in the range [0-9]. The
> > + running zero in  the beginning of D and P will be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid decimal digit character after four D's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv4
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv4 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If String is not in the correct format.
> > +                                   If any decimal number converted
> > + from
> > D
> > +                                    exceeds 255.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 32.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv4Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv4_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  );
> > +
> > +#define GUID_STRING_LENGTH  36
> > +
> > +/**
> > +  Convert a Null-terminated Unicode GUID string to a value of type
> > +  EFI_GUID.
> > +
> > +  This function outputs a GUID value by interpreting the contents of
> > + the Unicode string specified by String. The format of the input
> > + Unicode string String consists of 36 characters, as follows:
> > +
> > +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> > +
> > +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> > + [A-F], with each pair representing a single byte hexadecimal value.
> > +
> > +  The mapping between String and the EFI_GUID structure is as follows:
> > +                  aa          Data1[24:31]
> > +                  bb          Data1[16:23]
> > +                  cc          Data1[8:15]
> > +                  dd          Data1[0:7]
> > +                  ee          Data2[8:15]
> > +                  ff          Data2[0:7]
> > +                  gg          Data3[8:15]
> > +                  hh          Data3[0:7]
> > +                  ii          Data4[0:7]
> > +                  jj          Data4[8:15]
> > +                  kk          Data4[16:23]
> > +                  ll          Data4[24:31]
> > +                  mm          Data4[32:39]
> > +                  nn          Data4[40:47]
> > +                  oo          Data4[48:55]
> > +                  pp          Data4[56:63]
> > +
> > +  If String is NULL, then ASSERT().
> > +  If Guid is NULL, then ASSERT().
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Guid                     Pointer to the converted GUID.
> > +
> > +  @retval RETURN_SUCCESS           Guid is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If String is not as the above format.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToGuid (
> > +  IN  CONST CHAR16       *String,
> > +  OUT GUID               *Guid
> > +  );
> > +
> > +/**
> > +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> > +
> > +  This function outputs a byte array by interpreting the contents of
> > + the Unicode string specified by String in hexadecimal format. The
> > + format of  the input Unicode string String is:
> > +
> > +                  [XX]*
> > +
> > +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> > +  The function decodes every two hexadecimal digit characters as one byte.
> > The
> > +  decoding stops after Length of characters and outputs Buffer
> > + containing  (Length / 2) bytes.
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Buffer is NULL, then ASSERT().
> > +
> > +  If Length is not multiple of 2, then ASSERT().
> > +
> > +  If PcdMaximumStringLength is not zero and Length is greater than
> > + PcdMaximumAsciiStringLength, then ASSERT().
> > +
> > +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Length                   The number of Unicode characters to
> > decode.
> > +  @param  Buffer                   Pointer to the converted bytes array.
> > +  @param  MaxBufferSize            The maximum size of Buffer.
> > +
> > +  @retval RETURN_SUCCESS           Buffer is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If Length is not multiple of 2.
> > +                                   If PcdMaximumStringLength is not
> > zero,
> > +                                    and Length is greater than
> > +                                    PcdMaximumAsciiStringLength.
> > +                                   If Length of characters from
> > + String
> > contain
> > +                                    a character that is not valid
> > hexadecimal
> > +                                    digit characters, or a Null-terminator.
> > +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> > (Length / 2).
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrHexToBytes (
> > +  IN  CONST CHAR16       *String,
> > +  IN  UINTN              Length,
> > +  OUT UINT8              *Buffer,
> > +  IN  UINTN              MaxBufferSize
> > +  );
> > +
> >  #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
> >
> >  /**
> > diff --git a/MdePkg/Library/BaseLib/SafeString.c
> > b/MdePkg/Library/BaseLib/SafeString.c
> > index 315059e..ede1c99 100644
> > --- a/MdePkg/Library/BaseLib/SafeString.c
> > +++ b/MdePkg/Library/BaseLib/SafeString.c
> > @@ -1074,6 +1074,629 @@ StrHexToUint64S (  }
> >
> >  /**
> > +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> > +
> > +  This function outputs a value of type IPv6_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  X:X:X:X:X:X:X:X[/P]
> > +
> > +  X contains one to four hexadecimal digit characters in the range
> > + [0-9], [a-f]
> > and
> > +  [A-F]. X is converted to a value of type UINT16, whose low byte is
> > + stored in
> > low
> > +  memory address and high byte is stored in high memory address. P
> > + contains
> > decimal
> > +  digit characters in the range [0-9]. The running zero in the
> > + beginning of P will  be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid hexadecimal digit character after eight X's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  "::" can be used to compress one or more groups of X when X contains only
> 0.
> > +  The "::" can only appear once in the String.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv6
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv6 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If X contains more than four
> > hexadecimal
> > +                                    digit characters.
> > +                                   If String contains "::" and number of X
> > +                                    is not less than 8.
> > +                                   If P starts with character that is not a
> > +                                    valid decimal digit character.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 128.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv6Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv6_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  UINTN                  AddressIndex;
> > +  UINTN                  Uintn;
> > +  IPv6_ADDRESS           LocalAddress;
> > +  UINT8                  LocalPrefixLength;
> > +  CONST CHAR16           *Pointer;
> > +  CHAR16                 *End;
> > +  UINTN                  CompressStart;
> > +  BOOLEAN                ExpectPrefix;
> > +
> > +  LocalPrefixLength = MAX_UINT8;
> > +  CompressStart     = ARRAY_SIZE (Address->Addr);
> > +  ExpectPrefix      = FALSE;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE
> > (Address->Addr) + 1;) {
> > +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> > +      if (*Pointer != L':') {
> > +        //
> > +        // ":" or "/" should be followed by digit characters.
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +
> > +      //
> > +      // Meet second ":" after previous ":" or "/"
> > +      // or meet first ":" in the beginning of String.
> > +      //
> > +      if (ExpectPrefix) {
> > +        //
> > +        // ":" shall not be after "/"
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +
> > +      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex
> > + ==
> > ARRAY_SIZE (Address->Addr)) {
> > +        //
> > +        // "::" can only appear once.
> > +        // "::" can only appear when address is not full length.
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      } else {
> > +        //
> > +        // Remember the start of zero compressing.
> > +        //
> > +        CompressStart = AddressIndex;
> > +        Pointer++;
> > +
> > +        if (CompressStart == 0) {
> > +          if (*Pointer != L':') {
> > +            //
> > +            // Single ":" shall not be in the beginning of String.
> > +            //
> > +            return RETURN_INVALID_PARAMETER;
> > +          }
> > +          Pointer++;
> > +        }
> > +      }
> > +    }
> > +
> > +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> > +      if (*Pointer == L'/') {
> > +        //
> > +        // Might be optional "/P" after "::".
> > +        //
> > +        if (CompressStart != AddressIndex) {
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +      } else {
> > +        break;
> > +      }
> > +    } else {
> > +      if (!ExpectPrefix) {
> > +        //
> > +        // Get X.
> > +        //
> > +        Status = StrHexToUintnS (Pointer, &End, &Uintn);
> > +        if (RETURN_ERROR (Status) || End - Pointer > 4) {
> > +          //
> > +          // Number of hexadecimal digit characters is no more than 4.
> > +          //
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +        Pointer = End;
> > +        //
> > +        // Uintn won't exceed MAX_UINT16 if number of hexadecimal
> > + digit
> > characters is no more than 4.
> > +        //
> > +        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
> > +        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
> > +        AddressIndex += 2;
> > +      } else {
> > +        //
> > +        // Get P, then exit the loop.
> > +        //
> > +        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
> > +        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
> > +          //
> > +          // Prefix length should not exceed 128.
> > +          //
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +        LocalPrefixLength = (UINT8) Uintn;
> > +        Pointer = End;
> > +        break;
> > +      }
> > +    }
> > +
> > +    //
> > +    // Skip ':' or "/"
> > +    //
> > +    if (*Pointer == L'/') {
> > +      ExpectPrefix = TRUE;
> > +    } else if (*Pointer == L':') {
> > +      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +        //
> > +        // Meet additional ":" after all 8 16-bit address
> > +        //
> > +        break;
> > +      }
> > +    } else {
> > +      //
> > +      // Meet other character that is not "/" or ":" after all 8 16-bit address
> > +      //
> > +      break;
> > +    }
> > +    Pointer++;
> > +  }
> > +
> > +  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart !=
> > ARRAY_SIZE (Address->Addr)) ||
> > +    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart ==
> > ARRAY_SIZE (Address->Addr))
> > +      ) {
> > +    //
> > +    // Full length of address shall not have compressing zeros.
> > +    // Non-full length of address shall have compressing zeros.
> > +    //
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
> > + ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) -
> > AddressIndex);
> > +  CopyMem (
> > +    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) -
> > AddressIndex],
> > +    &LocalAddress.Addr[CompressStart],
> > +    AddressIndex - CompressStart
> > +    );
> > +
> > +  if (PrefixLength != NULL) {
> > +    *PrefixLength = LocalPrefixLength;  }  if (EndPointer != NULL) {
> > +    *EndPointer = (CHAR16 *) Pointer;  }
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> > +
> > +  This function outputs a value of type IPv4_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  D.D.D.D[/P]
> > +
> > +  D and P are decimal digit characters in the range [0-9]. The
> > + running zero in  the beginning of D and P will be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid decimal digit character after four D's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv4
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv4 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If String is not in the correct format.
> > +                                   If any decimal number converted
> > + from
> > D
> > +                                    exceeds 255.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 32.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv4Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv4_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  UINTN                  AddressIndex;
> > +  UINTN                  Uintn;
> > +  IPv4_ADDRESS           LocalAddress;
> > +  UINT8                  LocalPrefixLength;
> > +  CHAR16                 *Pointer;
> > +
> > +  LocalPrefixLength = MAX_UINT8;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex <
> > ARRAY_SIZE (Address->Addr) + 1;) {
> > +    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
> > +      //
> > +      // D or P contains invalid characters.
> > +      //
> > +      break;
> > +    }
> > +
> > +    //
> > +    // Get D or P.
> > +    //
> > +    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer,
> > &Uintn);
> > +    if (RETURN_ERROR (Status)) {
> > +      return RETURN_INVALID_PARAMETER;
> > +    }
> > +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +      //
> > +      // It's P.
> > +      //
> > +      if (Uintn > 32) {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +      LocalPrefixLength = (UINT8) Uintn;
> > +    } else {
> > +      //
> > +      // It's D.
> > +      //
> > +      if (Uintn > MAX_UINT8) {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
> > +      AddressIndex++;
> > +    }
> > +
> > +    //
> > +    // Check the '.' or '/', depending on the AddressIndex.
> > +    //
> > +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +      if (*Pointer == L'/') {
> > +        //
> > +        // '/P' is in the String.
> > +        // Skip "/" and get P in next loop.
> > +        //
> > +        Pointer++;
> > +      } else {
> > +        //
> > +        // '/P' is not in the String.
> > +        //
> > +        break;
> > +      }
> > +    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> > +      if (*Pointer == L'.') {
> > +        //
> > +        // D should be followed by '.'
> > +        //
> > +        Pointer++;
> > +      } else {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +    }
> > +  }
> > +
> > +  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  CopyMem (Address, &LocalAddress, sizeof (*Address));  if
> > + (PrefixLength != NULL) {
> > +    *PrefixLength = LocalPrefixLength;  }  if (EndPointer != NULL) {
> > +    *EndPointer = Pointer;
> > +  }
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode GUID string to a value of type
> > +  EFI_GUID.
> > +
> > +  This function outputs a GUID value by interpreting the contents of
> > + the Unicode string specified by String. The format of the input
> > + Unicode string String consists of 36 characters, as follows:
> > +
> > +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> > +
> > +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> > + [A-F], with each pair representing a single byte hexadecimal value.
> > +
> > +  The mapping between String and the EFI_GUID structure is as follows:
> > +                  aa          Data1[24:31]
> > +                  bb          Data1[16:23]
> > +                  cc          Data1[8:15]
> > +                  dd          Data1[0:7]
> > +                  ee          Data2[8:15]
> > +                  ff          Data2[0:7]
> > +                  gg          Data3[8:15]
> > +                  hh          Data3[0:7]
> > +                  ii          Data4[0:7]
> > +                  jj          Data4[8:15]
> > +                  kk          Data4[16:23]
> > +                  ll          Data4[24:31]
> > +                  mm          Data4[32:39]
> > +                  nn          Data4[40:47]
> > +                  oo          Data4[48:55]
> > +                  pp          Data4[56:63]
> > +
> > +  If String is NULL, then ASSERT().
> > +  If Guid is NULL, then ASSERT().
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Guid                     Pointer to the converted GUID.
> > +
> > +  @retval RETURN_SUCCESS           Guid is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If String is not as the above format.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToGuid (
> > +  IN  CONST CHAR16       *String,
> > +  OUT GUID               *Guid
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  GUID                   LocalGuid;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // Get aabbccdd in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1),
> > + (UINT8 *)
> > &LocalGuid.Data1, sizeof (LocalGuid.Data1));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);  String += 2 *
> > + sizeof (LocalGuid.Data1) + 1;
> > +
> > +  //
> > +  // Get eeff in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2),
> > + (UINT8 *)
> > &LocalGuid.Data2, sizeof (LocalGuid.Data2));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);  String += 2 *
> > + sizeof (LocalGuid.Data2) + 1;
> > +
> > +  //
> > +  // Get gghh in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3),
> > + (UINT8 *)
> > &LocalGuid.Data3, sizeof (LocalGuid.Data3));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);  String += 2 *
> > + sizeof (LocalGuid.Data3) + 1;
> > +
> > +  //
> > +  // Get iijj.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);  if
> > + (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  String += 2 * 2 + 1;
> > +
> > +  //
> > +  // Get kkllmmnnoopp.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);  if
> > + (RETURN_ERROR (Status)) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  CopyGuid (Guid, &LocalGuid);
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> > +
> > +  This function outputs a byte array by interpreting the contents of
> > + the Unicode string specified by String in hexadecimal format. The
> > + format of  the input Unicode string String is:
> > +
> > +                  [XX]*
> > +
> > +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> > +  The function decodes every two hexadecimal digit characters as one byte.
> > The
> > +  decoding stops after Length of characters and outputs Buffer
> > + containing  (Length / 2) bytes.
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Buffer is NULL, then ASSERT().
> > +
> > +  If Length is not multiple of 2, then ASSERT().
> > +
> > +  If PcdMaximumStringLength is not zero and Length is greater than
> > + PcdMaximumAsciiStringLength, then ASSERT().
> > +
> > +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Length                   The number of Unicode characters to
> > decode.
> > +  @param  Buffer                   Pointer to the converted bytes array.
> > +  @param  MaxBufferSize            The maximum size of Buffer.
> > +
> > +  @retval RETURN_SUCCESS           Buffer is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If Length is not multiple of 2.
> > +                                   If PcdMaximumStringLength is not
> > zero,
> > +                                    and Length is greater than
> > +                                    PcdMaximumAsciiStringLength.
> > +                                   If Length of characters from
> > + String
> > contain
> > +                                    a character that is not valid
> > hexadecimal
> > +                                    digit characters, or a Null-terminator.
> > +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> > (Length / 2).
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrHexToBytes (
> > +  IN  CONST CHAR16       *String,
> > +  IN  UINTN              Length,
> > +  OUT UINT8              *Buffer,
> > +  IN  UINTN              MaxBufferSize
> > +  )
> > +{
> > +  UINTN                  Index;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Buffer shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // 2. Length shall not be greater than RSIZE_MAX.
> > +  //
> > +  if (RSIZE_MAX != 0) {
> > +    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX),
> > RETURN_INVALID_PARAMETER);
> > +  }
> > +
> > +  //
> > +  // 3. Length shall not be odd.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // 4. MaxBufferSize shall equal to or greater than Length / 2.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2),
> > RETURN_BUFFER_TOO_SMALL);
> > +
> > +  //
> > +  // 5. String shall not contains invalid hexadecimal digits.
> > +  //
> > +  for (Index = 0; Index < Length; Index++) {
> > +    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
> > +      break;
> > +    }
> > +  }
> > +  if (Index != Length) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // Convert the hex string to bytes.
> > +  //
> > +  for(Index = 0; Index < Length; Index++) {
> > +
> > +    //
> > +    // For even characters, write the upper nibble for each buffer byte,
> > +    // and for even characters, the lower nibble.
> > +    //
> > +    if ((Index & BIT0) == 0) {
> > +      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn
> > + (String[Index]) <<
> > 4;
> > +    } else {
> > +      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
> > +    }
> > +  }
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> >    Returns the length of a Null-terminated Ascii string.
> >
> >    This function is similar as strlen_s defined in C11.
> > --
> > 2.9.0.windows.1



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
  2017-02-22  7:58     ` Ni, Ruiyu
@ 2017-02-22  8:14       ` Yao, Jiewen
  0 siblings, 0 replies; 17+ messages in thread
From: Yao, Jiewen @ 2017-02-22  8:14 UTC (permalink / raw)
  To: Ni, Ruiyu, edk2-devel@lists.01.org; +Cc: Gao, Liming, Fu, Siyuan

I think we should return better return status code.
If we return all cases with invalid parameter, the caller cannot know what is wrong.

Below is my thought:
I would return INVALID_PARAMETER if the something is wrong with the input string,
and return UNSUPPORTED if the format is not expected.


StrToIpv6Address()

+  @retval RETURN_INVALID_PARAMETER If String is NULL.

+                                   If Data is NULL.

+                                   If PcdMaximumUnicodeStringLength is not

+                                    zero, and String contains more than

+                                    PcdMaximumUnicodeStringLength Unicode

+                                    characters, not including the

+                                    Null-terminator.



+  @retval RETURN_UNSUPPORTED

+                                   If X contains more than four hexadecimal

+                                    digit characters.

+                                   If String contains "::" and number of X

+                                    is not less than 8.

+                                   If P starts with character that is not a

+                                    valid decimal digit character.

+                                   If the decimal number converted from P

+                                    exceeds 128.

StrToIpv4Address ()

+  @retval RETURN_INVALID_PARAMETER If String is NULL.

+                                   If Data is NULL.

+                                   If PcdMaximumUnicodeStringLength is not

+                                    zero, and String contains more than

+                                    PcdMaximumUnicodeStringLength Unicode

+                                    characters, not including the

+                                    Null-terminator.



+  @retval RETURN_UNSUPPORTED

+                                   If String is not in the correct format.

+                                   If any decimal number converted from D

+                                    exceeds 255.

+                                   If the decimal number converted from P

+                                    exceeds 32.

StrToGuid()

+  @retval RETURN_INVALID_PARAMETER If String is NULL.

+                                   If Data is NULL.

+  @retval RETURN_UNSUPPORTED

+                                   If String is not as the above format.



From: Ni, Ruiyu
Sent: Wednesday, February 22, 2017 3:58 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; edk2-devel@lists.01.org
Cc: Gao, Liming <liming.gao@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
Subject: RE: [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address

Jiewen,
If we returns Unsupported for "   1.2.3.4".
What shall we return for "    1.2.3"?
If we need to return Invalid Parameter for "   1.2.3", the implementation has to check whether it's a valid IP address after spaces, or an invalid IP address.

Can you just return Invalid Parameter for all cases?

Thanks/Ray

> -----Original Message-----
> From: Yao, Jiewen
> Sent: Wednesday, February 22, 2017 2:02 PM
> To: Ni, Ruiyu <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>; edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> Cc: Gao, Liming <liming.gao@intel.com<mailto:liming.gao@intel.com>>; Fu, Siyuan <siyuan.fu@intel.com<mailto:siyuan.fu@intel.com>>
> Subject: RE: [PATCH 04/11] MdePkg/BaseLib: Add
> StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
>
> Thanks.
>
> I suggest we clearly say: This function does not support the leading pad space ,
> which includes spaces or tab characters, before the first valid char.
>
> For example, "    1.2.3.4" is considered as invalid IPv4 address.
> And I suggest we return EFI_UNSUPPORTED.
>
> The comment is applied to add [Ascii]StrToGuid/IpV4/IpV6.
>
> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: Ni, Ruiyu
> > Sent: Wednesday, February 22, 2017 12:51 PM
> > To: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>
> > Cc: Gao, Liming <liming.gao@intel.com<mailto:liming.gao@intel.com>>; Yao, Jiewen
> > <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>; Fu, Siyuan <siyuan.fu@intel.com<mailto:siyuan.fu@intel.com>>
> > Subject: [PATCH 04/11] MdePkg/BaseLib: Add
> > StrToGuid/StrHexToBytes/StrToIpv[4/6]Address
> >
> > The patch adds 4 APIs to convert Unicode string to GUID, bytes buffer,
> > IP v4 address and IP v6 address.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com<mailto:ruiyu.ni@intel.com>>
> > Cc: Liming Gao <liming.gao@intel.com<mailto:liming.gao@intel.com>>
> > Cc: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> > Cc: Siyuan Fu <siyuan.fu@intel.com<mailto:siyuan.fu@intel.com>>
> > ---
> >  MdePkg/Include/Library/BaseLib.h    | 241 ++++++++++++++
> >  MdePkg/Library/BaseLib/SafeString.c | 623
> > ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 864 insertions(+)
> >
> > diff --git a/MdePkg/Include/Library/BaseLib.h
> > b/MdePkg/Include/Library/BaseLib.h
> > index d71ccb7..8aac4c8 100644
> > --- a/MdePkg/Include/Library/BaseLib.h
> > +++ b/MdePkg/Include/Library/BaseLib.h
> > @@ -1536,6 +1536,247 @@ StrHexToUint64 (
> >    IN      CONST CHAR16             *String
> >    );
> >
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> > +
> > +  This function outputs a value of type IPv6_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  X:X:X:X:X:X:X:X[/P]
> > +
> > +  X contains one to four hexadecimal digit characters in the range
> > + [0-9], [a-f]
> > and
> > +  [A-F]. X is converted to a value of type UINT16, whose low byte is
> > + stored in
> > low
> > +  memory address and high byte is stored in high memory address. P
> > + contains
> > decimal
> > +  digit characters in the range [0-9]. The running zero in the
> > + beginning of P will  be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid hexadecimal digit character after eight X's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  "::" can be used to compress one or more groups of X when X contains only
> 0.
> > +  The "::" can only appear once in the String.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv6
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv6 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If X contains more than four
> > hexadecimal
> > +                                    digit characters.
> > +                                   If String contains "::" and number of X
> > +                                    is not less than 8.
> > +                                   If P starts with character that is not a
> > +                                    valid decimal digit character.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 128.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv6Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv6_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  );
> > +
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> > +
> > +  This function outputs a value of type IPv4_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  D.D.D.D[/P]
> > +
> > +  D and P are decimal digit characters in the range [0-9]. The
> > + running zero in  the beginning of D and P will be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid decimal digit character after four D's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv4
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv4 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If String is not in the correct format.
> > +                                   If any decimal number converted
> > + from
> > D
> > +                                    exceeds 255.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 32.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv4Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv4_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  );
> > +
> > +#define GUID_STRING_LENGTH  36
> > +
> > +/**
> > +  Convert a Null-terminated Unicode GUID string to a value of type
> > +  EFI_GUID.
> > +
> > +  This function outputs a GUID value by interpreting the contents of
> > + the Unicode string specified by String. The format of the input
> > + Unicode string String consists of 36 characters, as follows:
> > +
> > +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> > +
> > +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> > + [A-F], with each pair representing a single byte hexadecimal value.
> > +
> > +  The mapping between String and the EFI_GUID structure is as follows:
> > +                  aa          Data1[24:31]
> > +                  bb          Data1[16:23]
> > +                  cc          Data1[8:15]
> > +                  dd          Data1[0:7]
> > +                  ee          Data2[8:15]
> > +                  ff          Data2[0:7]
> > +                  gg          Data3[8:15]
> > +                  hh          Data3[0:7]
> > +                  ii          Data4[0:7]
> > +                  jj          Data4[8:15]
> > +                  kk          Data4[16:23]
> > +                  ll          Data4[24:31]
> > +                  mm          Data4[32:39]
> > +                  nn          Data4[40:47]
> > +                  oo          Data4[48:55]
> > +                  pp          Data4[56:63]
> > +
> > +  If String is NULL, then ASSERT().
> > +  If Guid is NULL, then ASSERT().
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Guid                     Pointer to the converted GUID.
> > +
> > +  @retval RETURN_SUCCESS           Guid is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If String is not as the above format.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToGuid (
> > +  IN  CONST CHAR16       *String,
> > +  OUT GUID               *Guid
> > +  );
> > +
> > +/**
> > +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> > +
> > +  This function outputs a byte array by interpreting the contents of
> > + the Unicode string specified by String in hexadecimal format. The
> > + format of  the input Unicode string String is:
> > +
> > +                  [XX]*
> > +
> > +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> > +  The function decodes every two hexadecimal digit characters as one byte.
> > The
> > +  decoding stops after Length of characters and outputs Buffer
> > + containing  (Length / 2) bytes.
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Buffer is NULL, then ASSERT().
> > +
> > +  If Length is not multiple of 2, then ASSERT().
> > +
> > +  If PcdMaximumStringLength is not zero and Length is greater than
> > + PcdMaximumAsciiStringLength, then ASSERT().
> > +
> > +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Length                   The number of Unicode characters to
> > decode.
> > +  @param  Buffer                   Pointer to the converted bytes array.
> > +  @param  MaxBufferSize            The maximum size of Buffer.
> > +
> > +  @retval RETURN_SUCCESS           Buffer is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If Length is not multiple of 2.
> > +                                   If PcdMaximumStringLength is not
> > zero,
> > +                                    and Length is greater than
> > +                                    PcdMaximumAsciiStringLength.
> > +                                   If Length of characters from
> > + String
> > contain
> > +                                    a character that is not valid
> > hexadecimal
> > +                                    digit characters, or a Null-terminator.
> > +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> > (Length / 2).
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrHexToBytes (
> > +  IN  CONST CHAR16       *String,
> > +  IN  UINTN              Length,
> > +  OUT UINT8              *Buffer,
> > +  IN  UINTN              MaxBufferSize
> > +  );
> > +
> >  #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
> >
> >  /**
> > diff --git a/MdePkg/Library/BaseLib/SafeString.c
> > b/MdePkg/Library/BaseLib/SafeString.c
> > index 315059e..ede1c99 100644
> > --- a/MdePkg/Library/BaseLib/SafeString.c
> > +++ b/MdePkg/Library/BaseLib/SafeString.c
> > @@ -1074,6 +1074,629 @@ StrHexToUint64S (  }
> >
> >  /**
> > +  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
> > +
> > +  This function outputs a value of type IPv6_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  X:X:X:X:X:X:X:X[/P]
> > +
> > +  X contains one to four hexadecimal digit characters in the range
> > + [0-9], [a-f]
> > and
> > +  [A-F]. X is converted to a value of type UINT16, whose low byte is
> > + stored in
> > low
> > +  memory address and high byte is stored in high memory address. P
> > + contains
> > decimal
> > +  digit characters in the range [0-9]. The running zero in the
> > + beginning of P will  be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid hexadecimal digit character after eight X's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  "::" can be used to compress one or more groups of X when X contains only
> 0.
> > +  The "::" can only appear once in the String.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv6
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv6 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If X contains more than four
> > hexadecimal
> > +                                    digit characters.
> > +                                   If String contains "::" and number of X
> > +                                    is not less than 8.
> > +                                   If P starts with character that is not a
> > +                                    valid decimal digit character.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 128.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv6Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv6_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  UINTN                  AddressIndex;
> > +  UINTN                  Uintn;
> > +  IPv6_ADDRESS           LocalAddress;
> > +  UINT8                  LocalPrefixLength;
> > +  CONST CHAR16           *Pointer;
> > +  CHAR16                 *End;
> > +  UINTN                  CompressStart;
> > +  BOOLEAN                ExpectPrefix;
> > +
> > +  LocalPrefixLength = MAX_UINT8;
> > +  CompressStart     = ARRAY_SIZE (Address->Addr);
> > +  ExpectPrefix      = FALSE;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE
> > (Address->Addr) + 1;) {
> > +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> > +      if (*Pointer != L':') {
> > +        //
> > +        // ":" or "/" should be followed by digit characters.
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +
> > +      //
> > +      // Meet second ":" after previous ":" or "/"
> > +      // or meet first ":" in the beginning of String.
> > +      //
> > +      if (ExpectPrefix) {
> > +        //
> > +        // ":" shall not be after "/"
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +
> > +      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex
> > + ==
> > ARRAY_SIZE (Address->Addr)) {
> > +        //
> > +        // "::" can only appear once.
> > +        // "::" can only appear when address is not full length.
> > +        //
> > +        return RETURN_INVALID_PARAMETER;
> > +      } else {
> > +        //
> > +        // Remember the start of zero compressing.
> > +        //
> > +        CompressStart = AddressIndex;
> > +        Pointer++;
> > +
> > +        if (CompressStart == 0) {
> > +          if (*Pointer != L':') {
> > +            //
> > +            // Single ":" shall not be in the beginning of String.
> > +            //
> > +            return RETURN_INVALID_PARAMETER;
> > +          }
> > +          Pointer++;
> > +        }
> > +      }
> > +    }
> > +
> > +    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
> > +      if (*Pointer == L'/') {
> > +        //
> > +        // Might be optional "/P" after "::".
> > +        //
> > +        if (CompressStart != AddressIndex) {
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +      } else {
> > +        break;
> > +      }
> > +    } else {
> > +      if (!ExpectPrefix) {
> > +        //
> > +        // Get X.
> > +        //
> > +        Status = StrHexToUintnS (Pointer, &End, &Uintn);
> > +        if (RETURN_ERROR (Status) || End - Pointer > 4) {
> > +          //
> > +          // Number of hexadecimal digit characters is no more than 4.
> > +          //
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +        Pointer = End;
> > +        //
> > +        // Uintn won't exceed MAX_UINT16 if number of hexadecimal
> > + digit
> > characters is no more than 4.
> > +        //
> > +        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8);
> > +        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn;
> > +        AddressIndex += 2;
> > +      } else {
> > +        //
> > +        // Get P, then exit the loop.
> > +        //
> > +        Status = StrDecimalToUintnS (Pointer, &End, &Uintn);
> > +        if (RETURN_ERROR (Status) || End == Pointer || Uintn > 128) {
> > +          //
> > +          // Prefix length should not exceed 128.
> > +          //
> > +          return RETURN_INVALID_PARAMETER;
> > +        }
> > +        LocalPrefixLength = (UINT8) Uintn;
> > +        Pointer = End;
> > +        break;
> > +      }
> > +    }
> > +
> > +    //
> > +    // Skip ':' or "/"
> > +    //
> > +    if (*Pointer == L'/') {
> > +      ExpectPrefix = TRUE;
> > +    } else if (*Pointer == L':') {
> > +      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +        //
> > +        // Meet additional ":" after all 8 16-bit address
> > +        //
> > +        break;
> > +      }
> > +    } else {
> > +      //
> > +      // Meet other character that is not "/" or ":" after all 8 16-bit address
> > +      //
> > +      break;
> > +    }
> > +    Pointer++;
> > +  }
> > +
> > +  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart !=
> > ARRAY_SIZE (Address->Addr)) ||
> > +    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart ==
> > ARRAY_SIZE (Address->Addr))
> > +      ) {
> > +    //
> > +    // Full length of address shall not have compressing zeros.
> > +    // Non-full length of address shall have compressing zeros.
> > +    //
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  CopyMem (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
> > + ZeroMem (&Address->Addr[CompressStart], ARRAY_SIZE (Address->Addr) -
> > AddressIndex);
> > +  CopyMem (
> > +    &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) -
> > AddressIndex],
> > +    &LocalAddress.Addr[CompressStart],
> > +    AddressIndex - CompressStart
> > +    );
> > +
> > +  if (PrefixLength != NULL) {
> > +    *PrefixLength = LocalPrefixLength;  }  if (EndPointer != NULL) {
> > +    *EndPointer = (CHAR16 *) Pointer;  }
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
> > +
> > +  This function outputs a value of type IPv4_ADDRESS and may output a
> > + value  of type UINT8 by interpreting the contents of the Unicode
> > + string specified  by String. The format of the input Unicode string String is as
> follows:
> > +
> > +                  D.D.D.D[/P]
> > +
> > +  D and P are decimal digit characters in the range [0-9]. The
> > + running zero in  the beginning of D and P will be ignored. /P is optional.
> > +
> > +  When /P is not in the String, the function stops at the first
> > + character that is  not a valid decimal digit character after four D's are
> converted.
> > +
> > +  When /P is in the String, the function stops at the first character
> > + that is not  a valid decimal digit character after P is converted.
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Address is NULL, then ASSERT().
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If PcdMaximumUnicodeStringLength is not zero, and String contains
> > + more
> > than
> > +  PcdMaximumUnicodeStringLength Unicode characters, not including the
> > + Null-terminator, then ASSERT().
> > +
> > +  If EndPointer is not NULL and Address is translated from String, a
> > + pointer  to the character that stopped the scan is stored at the
> > + location pointed to  by EndPointer.
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  EndPointer               Pointer to character that stops scan.
> > +  @param  Address                  Pointer to the converted IPv4
> > address.
> > +  @param  PrefixLength             Pointer to the converted IPv4 address
> > prefix
> > +                                   length. MAX_UINT8 is returned when
> > /P is
> > +                                   not in the String.
> > +
> > +  @retval RETURN_SUCCESS           Address is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If PcdMaximumUnicodeStringLength
> > + is
> > not
> > +                                    zero, and String contains more than
> > +                                    PcdMaximumUnicodeStringLength
> > Unicode
> > +                                    characters, not including the
> > +                                    Null-terminator.
> > +                                   If String is not in the correct format.
> > +                                   If any decimal number converted
> > + from
> > D
> > +                                    exceeds 255.
> > +                                   If the decimal number converted
> > + from
> > P
> > +                                    exceeds 32.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToIpv4Address (
> > +  IN  CONST CHAR16       *String,
> > +  OUT CHAR16             **EndPointer, OPTIONAL
> > +  OUT IPv4_ADDRESS       *Address,
> > +  OUT UINT8              *PrefixLength OPTIONAL
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  UINTN                  AddressIndex;
> > +  UINTN                  Uintn;
> > +  IPv4_ADDRESS           LocalAddress;
> > +  UINT8                  LocalPrefixLength;
> > +  CHAR16                 *Pointer;
> > +
> > +  LocalPrefixLength = MAX_UINT8;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex <
> > ARRAY_SIZE (Address->Addr) + 1;) {
> > +    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
> > +      //
> > +      // D or P contains invalid characters.
> > +      //
> > +      break;
> > +    }
> > +
> > +    //
> > +    // Get D or P.
> > +    //
> > +    Status = StrDecimalToUintnS ((CONST CHAR16 *) Pointer, &Pointer,
> > &Uintn);
> > +    if (RETURN_ERROR (Status)) {
> > +      return RETURN_INVALID_PARAMETER;
> > +    }
> > +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +      //
> > +      // It's P.
> > +      //
> > +      if (Uintn > 32) {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +      LocalPrefixLength = (UINT8) Uintn;
> > +    } else {
> > +      //
> > +      // It's D.
> > +      //
> > +      if (Uintn > MAX_UINT8) {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +      LocalAddress.Addr[AddressIndex] = (UINT8) Uintn;
> > +      AddressIndex++;
> > +    }
> > +
> > +    //
> > +    // Check the '.' or '/', depending on the AddressIndex.
> > +    //
> > +    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
> > +      if (*Pointer == L'/') {
> > +        //
> > +        // '/P' is in the String.
> > +        // Skip "/" and get P in next loop.
> > +        //
> > +        Pointer++;
> > +      } else {
> > +        //
> > +        // '/P' is not in the String.
> > +        //
> > +        break;
> > +      }
> > +    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> > +      if (*Pointer == L'.') {
> > +        //
> > +        // D should be followed by '.'
> > +        //
> > +        Pointer++;
> > +      } else {
> > +        return RETURN_INVALID_PARAMETER;
> > +      }
> > +    }
> > +  }
> > +
> > +  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  CopyMem (Address, &LocalAddress, sizeof (*Address));  if
> > + (PrefixLength != NULL) {
> > +    *PrefixLength = LocalPrefixLength;  }  if (EndPointer != NULL) {
> > +    *EndPointer = Pointer;
> > +  }
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode GUID string to a value of type
> > +  EFI_GUID.
> > +
> > +  This function outputs a GUID value by interpreting the contents of
> > + the Unicode string specified by String. The format of the input
> > + Unicode string String consists of 36 characters, as follows:
> > +
> > +                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
> > +
> > +  The pairs aa - pp are two characters in the range [0-9], [a-f] and
> > + [A-F], with each pair representing a single byte hexadecimal value.
> > +
> > +  The mapping between String and the EFI_GUID structure is as follows:
> > +                  aa          Data1[24:31]
> > +                  bb          Data1[16:23]
> > +                  cc          Data1[8:15]
> > +                  dd          Data1[0:7]
> > +                  ee          Data2[8:15]
> > +                  ff          Data2[0:7]
> > +                  gg          Data3[8:15]
> > +                  hh          Data3[0:7]
> > +                  ii          Data4[0:7]
> > +                  jj          Data4[8:15]
> > +                  kk          Data4[16:23]
> > +                  ll          Data4[24:31]
> > +                  mm          Data4[32:39]
> > +                  nn          Data4[40:47]
> > +                  oo          Data4[48:55]
> > +                  pp          Data4[56:63]
> > +
> > +  If String is NULL, then ASSERT().
> > +  If Guid is NULL, then ASSERT().
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Guid                     Pointer to the converted GUID.
> > +
> > +  @retval RETURN_SUCCESS           Guid is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If String is not as the above format.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrToGuid (
> > +  IN  CONST CHAR16       *String,
> > +  OUT GUID               *Guid
> > +  )
> > +{
> > +  RETURN_STATUS          Status;
> > +  GUID                   LocalGuid;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Guid shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // Get aabbccdd in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1),
> > + (UINT8 *)
> > &LocalGuid.Data1, sizeof (LocalGuid.Data1));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);  String += 2 *
> > + sizeof (LocalGuid.Data1) + 1;
> > +
> > +  //
> > +  // Get eeff in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2),
> > + (UINT8 *)
> > &LocalGuid.Data2, sizeof (LocalGuid.Data2));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);  String += 2 *
> > + sizeof (LocalGuid.Data2) + 1;
> > +
> > +  //
> > +  // Get gghh in big-endian.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3),
> > + (UINT8 *)
> > &LocalGuid.Data3, sizeof (LocalGuid.Data3));
> > +  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  //
> > +  // Convert big-endian to little-endian.
> > +  //
> > +  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);  String += 2 *
> > + sizeof (LocalGuid.Data3) + 1;
> > +
> > +  //
> > +  // Get iijj.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);  if
> > + (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +  String += 2 * 2 + 1;
> > +
> > +  //
> > +  // Get kkllmmnnoopp.
> > +  //
> > +  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);  if
> > + (RETURN_ERROR (Status)) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  CopyGuid (Guid, &LocalGuid);
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Convert a Null-terminated Unicode hexadecimal string to a byte array.
> > +
> > +  This function outputs a byte array by interpreting the contents of
> > + the Unicode string specified by String in hexadecimal format. The
> > + format of  the input Unicode string String is:
> > +
> > +                  [XX]*
> > +
> > +  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
> > +  The function decodes every two hexadecimal digit characters as one byte.
> > The
> > +  decoding stops after Length of characters and outputs Buffer
> > + containing  (Length / 2) bytes.
> > +
> > +  If String is not aligned in a 16-bit boundary, then ASSERT().
> > +
> > +  If String is NULL, then ASSERT().
> > +
> > +  If Buffer is NULL, then ASSERT().
> > +
> > +  If Length is not multiple of 2, then ASSERT().
> > +
> > +  If PcdMaximumStringLength is not zero and Length is greater than
> > + PcdMaximumAsciiStringLength, then ASSERT().
> > +
> > +  If MaxBufferSize is less than (Length / 2), then ASSERT().
> > +
> > +  @param  String                   Pointer to a Null-terminated Unicode
> > string.
> > +  @param  Length                   The number of Unicode characters to
> > decode.
> > +  @param  Buffer                   Pointer to the converted bytes array.
> > +  @param  MaxBufferSize            The maximum size of Buffer.
> > +
> > +  @retval RETURN_SUCCESS           Buffer is translated from String.
> > +  @retval RETURN_INVALID_PARAMETER If String is NULL.
> > +                                   If Data is NULL.
> > +                                   If Length is not multiple of 2.
> > +                                   If PcdMaximumStringLength is not
> > zero,
> > +                                    and Length is greater than
> > +                                    PcdMaximumAsciiStringLength.
> > +                                   If Length of characters from
> > + String
> > contain
> > +                                    a character that is not valid
> > hexadecimal
> > +                                    digit characters, or a Null-terminator.
> > +  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than
> > (Length / 2).
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +StrHexToBytes (
> > +  IN  CONST CHAR16       *String,
> > +  IN  UINTN              Length,
> > +  OUT UINT8              *Buffer,
> > +  IN  UINTN              MaxBufferSize
> > +  )
> > +{
> > +  UINTN                  Index;
> > +
> > +  ASSERT (((UINTN) String & BIT0) == 0);
> > +
> > +  //
> > +  // 1. None of String or Buffer shall be a null pointer.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL),
> > RETURN_INVALID_PARAMETER);
> > +  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // 2. Length shall not be greater than RSIZE_MAX.
> > +  //
> > +  if (RSIZE_MAX != 0) {
> > +    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX),
> > RETURN_INVALID_PARAMETER);
> > +  }
> > +
> > +  //
> > +  // 3. Length shall not be odd.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0),
> > RETURN_INVALID_PARAMETER);
> > +
> > +  //
> > +  // 4. MaxBufferSize shall equal to or greater than Length / 2.
> > +  //
> > +  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2),
> > RETURN_BUFFER_TOO_SMALL);
> > +
> > +  //
> > +  // 5. String shall not contains invalid hexadecimal digits.
> > +  //
> > +  for (Index = 0; Index < Length; Index++) {
> > +    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
> > +      break;
> > +    }
> > +  }
> > +  if (Index != Length) {
> > +    return RETURN_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // Convert the hex string to bytes.
> > +  //
> > +  for(Index = 0; Index < Length; Index++) {
> > +
> > +    //
> > +    // For even characters, write the upper nibble for each buffer byte,
> > +    // and for even characters, the lower nibble.
> > +    //
> > +    if ((Index & BIT0) == 0) {
> > +      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn
> > + (String[Index]) <<
> > 4;
> > +    } else {
> > +      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
> > +    }
> > +  }
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> >    Returns the length of a Null-terminated Ascii string.
> >
> >    This function is similar as strlen_s defined in C11.
> > --
> > 2.9.0.windows.1


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-02-22  8:14 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-22  4:50 [PATCH 00/11] Add StrToGuid/HexToBytes/Ipv4/Ipv6 in BaseLib Ruiyu Ni
2017-02-22  4:50 ` [PATCH 01/11] MdePkg: Define IPv4_ADDRESS and IPv6_ADDRESS in Base.h Ruiyu Ni
2017-02-22  4:50 ` [PATCH 02/11] MdePkg/UefiDevicePathLib: Rename StrToGuid to avoid link failure Ruiyu Ni
2017-02-22  4:50 ` [PATCH 03/11] SignedCapsulePkg/IniParsing: " Ruiyu Ni
2017-02-22  4:50 ` [PATCH 04/11] MdePkg/BaseLib: Add StrToGuid/StrHexToBytes/StrToIpv[4/6]Address Ruiyu Ni
2017-02-22  6:02   ` Yao, Jiewen
2017-02-22  7:58     ` Ni, Ruiyu
2017-02-22  8:14       ` Yao, Jiewen
2017-02-22  4:50 ` [PATCH 05/11] MdePkg/BaseLib: Add AsciiStrToGuid/HexToBytes/ToIpv[4/6]Address Ruiyu Ni
2017-02-22  4:50 ` [PATCH 06/11] MdePkg/UefiDevicePathLib: Use BaseLib string conversion services Ruiyu Ni
2017-02-22  4:50 ` [PATCH 07/11] MdeModulePkg/CapsuleApp: Use StrToGuid in BaseLib Ruiyu Ni
2017-02-22  4:50 ` [PATCH 08/11] SecurityPkg/SecureBootConfigDxe: " Ruiyu Ni
2017-02-22  4:50 ` [PATCH 09/11] ShellPkg/Debug1CommandLib: Use StrToGuid/StrHexToBytes " Ruiyu Ni
2017-02-22  4:50 ` [PATCH 10/11] SignedCapsulePkg/IniParsingLib: Use AsciiStrToGuid " Ruiyu Ni
2017-02-22  5:28   ` Yao, Jiewen
2017-02-22  7:40     ` Ni, Ruiyu
2017-02-22  4:50 ` [PATCH 11/11] MdeModulePkg/NetLib: Use StrToIpv4/6Address " Ruiyu Ni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox