* [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