From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 94D5E817B2 for ; Sun, 8 Jan 2017 18:02:46 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 08 Jan 2017 18:02:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,338,1477983600"; d="scan'208";a="1109767051" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by fmsmga002.fm.intel.com with ESMTP; 08 Jan 2017 18:02:45 -0800 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.248.2; Sun, 8 Jan 2017 18:02:45 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.248.2; Sun, 8 Jan 2017 18:02:45 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.88]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.132]) with mapi id 14.03.0248.002; Mon, 9 Jan 2017 10:02:42 +0800 From: "Yao, Jiewen" To: "Wu, Hao A" , "edk2-devel@lists.01.org" CC: "Gao, Liming" , "Kinney, Michael D" Thread-Topic: [PATCH 2/4] MdePkg/BaseLib: Add safe string functions that convert str to value Thread-Index: AQHSZnz1MhfXYTBWzkSEyikweLX76qEva+hQ Date: Mon, 9 Jan 2017 02:02:41 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A8DCE84@shsmsx102.ccr.corp.intel.com> References: <1483528957-28340-1-git-send-email-hao.a.wu@intel.com> <1483528957-28340-3-git-send-email-hao.a.wu@intel.com> In-Reply-To: <1483528957-28340-3-git-send-email-hao.a.wu@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH 2/4] MdePkg/BaseLib: Add safe string functions that convert str to value X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jan 2017 02:02:46 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: jiewen.yao@intel.com > -----Original Message----- > From: Wu, Hao A > Sent: Wednesday, January 4, 2017 7:23 PM > To: edk2-devel@lists.01.org > Cc: Wu, Hao A ; Yao, Jiewen ; > Gao, Liming ; Kinney, Michael D > > Subject: [PATCH 2/4] MdePkg/BaseLib: Add safe string functions that conve= rt str > to value >=20 > Add the following 8 APIs: > [Ascii]StrDecimalToUintnS > [Ascii]StrDecimalToUint64S > [Ascii]StrHexToUintnS > [Ascii]StrHexToUint64S >=20 > These safe version APIs are used to enhance their counterpart (APIs > without trailing 'S' in function names). >=20 > These safe version APIs perform checks to the input string and will retur= n > relative status to reflect the check result: > When the input string exceeds the range of UINTN/64, these APIs will > return RETURN_UNSUPPORTED and store MAX_UINTN/64 in the output data. > When no conversion can be performed for the input string, these APIs will > return RETURN_SUCCESS and store 0 in the output data. >=20 > The optional parameter 'EndPointer', if provided, will point to the > character that stopped the scan. >=20 > Cc: Jiewen Yao > Cc: Liming Gao > Cc: Michael Kinney > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Hao Wu > --- > MdePkg/Include/Library/BaseLib.h | 462 ++++++++++++++ > MdePkg/Library/BaseLib/BaseLibInternals.h | 166 ++++- > MdePkg/Library/BaseLib/SafeString.c | 975 > +++++++++++++++++++++++++++++- > 3 files changed, 1598 insertions(+), 5 deletions(-) >=20 > diff --git a/MdePkg/Include/Library/BaseLib.h > b/MdePkg/Include/Library/BaseLib.h > index 72d1f0b..52011ee 100644 > --- a/MdePkg/Include/Library/BaseLib.h > +++ b/MdePkg/Include/Library/BaseLib.h > @@ -390,6 +390,240 @@ StrnCatS ( > ); >=20 > /** > + Convert a Null-terminated Unicode decimal string to a value of type UI= NTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Unicode string specified by String as a decimal number. The format= of the > + input Unicode string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrDecimalToUintnS ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ); > + > +/** > + Convert a Null-terminated Unicode decimal string to a value of type UI= NT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Unicode string specified by String as a decimal number. The format= of the > + input Unicode string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrDecimalToUint64S ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ); > + > +/** > + Convert a Null-terminated Unicode hexadecimal string to a value of typ= e > + UINTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Unicode string specified by String as a hexadecimal number. The fo= rmat of > + the input Unicode string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. > + If "x" appears in the input string, it must be prefixed with at least = one 0. > + The function will ignore the pad space, which includes spaces or tab > + characters, before [zeros], [x] or [hexadecimal digit]. The running ze= ro > + before [x] or [hexadecimal digit] will be ignored. Then, the decoding = starts > + after [x] or the first valid hexadecimal digit. Then, the function sto= ps at > + the first character that is a not a valid hexadecimal character or NUL= L, > + whichever one comes first. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrHexToUintnS ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ); > + > +/** > + Convert a Null-terminated Unicode hexadecimal string to a value of typ= e > + UINT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Unicode string specified by String as a hexadecimal number. The fo= rmat of > + the input Unicode string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. > + If "x" appears in the input string, it must be prefixed with at least = one 0. > + The function will ignore the pad space, which includes spaces or tab > + characters, before [zeros], [x] or [hexadecimal digit]. The running ze= ro > + before [x] or [hexadecimal digit] will be ignored. Then, the decoding = starts > + after [x] or the first valid hexadecimal digit. Then, the function sto= ps at > + the first character that is a not a valid hexadecimal character or NUL= L, > + whichever one comes first. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrHexToUint64S ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ); > + > +/** > Returns the length of a Null-terminated Ascii string. >=20 > This function is similar as strlen_s defined in C11. > @@ -582,6 +816,234 @@ AsciiStrnCatS ( > IN UINTN Length > ); >=20 > +/** > + Convert a Null-terminated Ascii decimal string to a value of type UINT= N. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Ascii string specified by String as a decimal number. The format o= f the > + input Ascii string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrDecimalToUintnS ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ); > + > +/** > + Convert a Null-terminated Ascii decimal string to a value of type UINT= 64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Ascii string specified by String as a decimal number. The format o= f the > + input Ascii string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrDecimalToUint64S ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ); > + > +/** > + Convert a Null-terminated Ascii hexadecimal string to a value of type = UINTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Ascii string specified by String as a hexadecimal number. The form= at of > + the input Ascii string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. If > + "x" appears in the input string, it must be prefixed with at least one= 0. The > + function will ignore the pad space, which includes spaces or tab chara= cters, > + before [zeros], [x] or [hexadecimal digits]. The running zero before [= x] or > + [hexadecimal digits] will be ignored. Then, the decoding starts after = [x] or > + the first valid hexadecimal digit. Then, the function stops at the fir= st > + character that is a not a valid hexadecimal character or Null-terminat= or, > + whichever on comes first. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrHexToUintnS ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ); > + > +/** > + Convert a Null-terminated Ascii hexadecimal string to a value of type = UINT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Ascii string specified by String as a hexadecimal number. The form= at of > + the input Ascii string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. If > + "x" appears in the input string, it must be prefixed with at least one= 0. The > + function will ignore the pad space, which includes spaces or tab chara= cters, > + before [zeros], [x] or [hexadecimal digits]. The running zero before [= x] or > + [hexadecimal digits] will be ignored. Then, the decoding starts after = [x] or > + the first valid hexadecimal digit. Then, the function stops at the fir= st > + character that is a not a valid hexadecimal character or Null-terminat= or, > + whichever on comes first. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrHexToUint64S ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ); > + >=20 > #ifndef DISABLE_NEW_DEPRECATED_INTERFACES >=20 > diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h > b/MdePkg/Library/BaseLib/BaseLibInternals.h > index a8f712b..ea387ce 100644 > --- a/MdePkg/Library/BaseLib/BaseLibInternals.h > +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h > @@ -1,7 +1,7 @@ > /** @file > Declaration of internal functions in BaseLib. >=20 > - Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
> + Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
> 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 > @@ -477,6 +477,170 @@ InternalLongJump ( > ); >=20 >=20 > +/** > + Check if a Unicode character is a decimal character. > + > + This internal function checks if a Unicode character is a > + decimal character. The valid decimal character is from > + L'0' to L'9'. > + > + @param Char The character to check against. > + > + @retval TRUE If the Char is a decmial character. > + @retval FALSE If the Char is not a decmial character. > + > +**/ > +BOOLEAN > +EFIAPI > +InternalIsDecimalDigitCharacter ( > + IN CHAR16 Char > + ); > + > + > +/** > + Convert a Unicode character to upper case only if > + it maps to a valid small-case ASCII character. > + > + This internal function only deal with Unicode character > + which maps to a valid small-case ASCII character, i.e. > + L'a' to L'z'. For other Unicode character, the input character > + is returned directly. > + > + @param Char The character to convert. > + > + @retval LowerCharacter If the Char is with range L'a' to L'z'. > + @retval Unchanged Otherwise. > + > +**/ > +CHAR16 > +EFIAPI > +InternalCharToUpper ( > + IN CHAR16 Char > + ); > + > + > +/** > + 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 > +EFIAPI > +InternalHexCharToUintn ( > + IN CHAR16 Char > + ); > + > + > +/** > + Check if a Unicode character is a hexadecimal character. > + > + This internal function checks if a Unicode character is a > + decimal character. The valid hexadecimal character is > + L'0' to L'9', L'a' to L'f', or L'A' to L'F'. > + > + > + @param Char The character to check against. > + > + @retval TRUE If the Char is a hexadecmial character. > + @retval FALSE If the Char is not a hexadecmial character. > + > +**/ > +BOOLEAN > +EFIAPI > +InternalIsHexaDecimalDigitCharacter ( > + IN CHAR16 Char > + ); > + > + > +/** > + Check if a ASCII character is a decimal character. > + > + This internal function checks if a Unicode character is a > + decimal character. The valid decimal character is from > + '0' to '9'. > + > + @param Char The character to check against. > + > + @retval TRUE If the Char is a decmial character. > + @retval FALSE If the Char is not a decmial character. > + > +**/ > +BOOLEAN > +EFIAPI > +InternalAsciiIsDecimalDigitCharacter ( > + IN CHAR8 Char > + ); > + > + > +/** > + Converts a lowercase Ascii character to upper one. > + > + If Chr is lowercase Ascii character, then converts it to upper one. > + > + If Value >=3D 0xA0, then ASSERT(). > + If (Value & 0x0F) >=3D 0x0A, then ASSERT(). > + > + @param Chr one Ascii character > + > + @return The uppercase value of Ascii character > + > +**/ > +CHAR8 > +EFIAPI > +InternalBaseLibAsciiToUpper ( > + IN CHAR8 Chr > + ); > + > + > +/** > + Check if a ASCII character is a hexadecimal character. > + > + This internal function checks if a ASCII character is a > + decimal character. The valid hexadecimal character is > + L'0' to L'9', L'a' to L'f', or L'A' to L'F'. > + > + > + @param Char The character to check against. > + > + @retval TRUE If the Char is a hexadecmial character. > + @retval FALSE If the Char is not a hexadecmial character. > + > +**/ > +BOOLEAN > +EFIAPI > +InternalAsciiIsHexaDecimalDigitCharacter ( > + IN CHAR8 Char > + ); > + > + > +/** > + Convert a ASCII character to numerical value. > + > + This internal function only deal with Unicode character > + which maps to a valid hexadecimal ASII character, i.e. > + '0' to '9', 'a' to 'f' or 'A' to 'F'. For other > + ASCII character, the value returned does not make sense. > + > + @param Char The character to convert. > + > + @return The numerical value converted. > + > +**/ > +UINTN > +EFIAPI > +InternalAsciiHexCharToUintn ( > + IN CHAR8 Char > + ); > + > + > // > // Ia32 and x64 specific functions > // > diff --git a/MdePkg/Library/BaseLib/SafeString.c > b/MdePkg/Library/BaseLib/SafeString.c > index f80db9f..5edc6ef 100644 > --- a/MdePkg/Library/BaseLib/SafeString.c > +++ b/MdePkg/Library/BaseLib/SafeString.c > @@ -12,10 +12,7 @@ >=20 > **/ >=20 > -#include > -#include > -#include > -#include > +#include "BaseLibInternals.h" >=20 > #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength)) >=20 > @@ -585,6 +582,498 @@ StrnCatS ( > } >=20 > /** > + Convert a Null-terminated Unicode decimal string to a value of type UI= NTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Unicode string specified by String as a decimal number. The format= of the > + input Unicode string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrDecimalToUintnS ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ) > +{ > + ASSERT (((UINTN) String & BIT0) =3D=3D 0); > + > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than RSIZE_MAX. > + // > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <=3D > RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D L' ') || (*String =3D=3D L'\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D L'0') { > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalIsDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINTN, then MAX_UINTN is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) { > + *Data =3D MAX_UINTN; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D *Data * 10 + (*String - L'0'); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Unicode decimal string to a value of type UI= NT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Unicode string specified by String as a decimal number. The format= of the > + input Unicode string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrDecimalToUint64S ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ) > +{ > + ASSERT (((UINTN) String & BIT0) =3D=3D 0); > + > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than RSIZE_MAX. > + // > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <=3D > RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D L' ') || (*String =3D=3D L'\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D L'0') { > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalIsDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINT64, then MAX_UINT64 is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) { > + *Data =3D MAX_UINT64; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D MultU64x32 (*Data, 10) + (*String - L'0'); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Unicode hexadecimal string to a value of typ= e > + UINTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Unicode string specified by String as a hexadecimal number. The fo= rmat of > + the input Unicode string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. > + If "x" appears in the input string, it must be prefixed with at least = one 0. > + The function will ignore the pad space, which includes spaces or tab > + characters, before [zeros], [x] or [hexadecimal digit]. The running ze= ro > + before [x] or [hexadecimal digit] will be ignored. Then, the decoding = starts > + after [x] or the first valid hexadecimal digit. Then, the function sto= ps at > + the first character that is a not a valid hexadecimal character or NUL= L, > + whichever one comes first. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrHexToUintnS ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ) > +{ > + ASSERT (((UINTN) String & BIT0) =3D=3D 0); > + > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than RSIZE_MAX. > + // > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <=3D > RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D L' ') || (*String =3D=3D L'\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D L'0') { > + String++; > + } > + > + if (InternalCharToUpper (*String) =3D=3D L'X') { > + if (*(String - 1) !=3D L'0') { > + *Data =3D 0; > + return RETURN_SUCCESS; > + } > + // > + // Skip the 'X' > + // > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalIsHexaDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINTN, then MAX_UINTN is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) { > + *Data =3D MAX_UINTN; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D (*Data << 4) + InternalHexCharToUintn (*String); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Unicode hexadecimal string to a value of typ= e > + UINT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Unicode string specified by String as a hexadecimal number. The fo= rmat of > + the input Unicode string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. > + If "x" appears in the input string, it must be prefixed with at least = one 0. > + The function will ignore the pad space, which includes spaces or tab > + characters, before [zeros], [x] or [hexadecimal digit]. The running ze= ro > + before [x] or [hexadecimal digit] will be ignored. Then, the decoding = starts > + after [x] or the first valid hexadecimal digit. Then, the function sto= ps at > + the first character that is a not a valid hexadecimal character or NUL= L, > + whichever one comes first. > + > + If String is NULL, then ASSERT(). > + If Data 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 String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value 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. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +StrHexToUint64S ( > + IN CONST CHAR16 *String, > + OUT CHAR16 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ) > +{ > + ASSERT (((UINTN) String & BIT0) =3D=3D 0); > + > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than RSIZE_MAX. > + // > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <=3D > RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D L' ') || (*String =3D=3D L'\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D L'0') { > + String++; > + } > + > + if (InternalCharToUpper (*String) =3D=3D L'X') { > + if (*(String - 1) !=3D L'0') { > + *Data =3D 0; > + return RETURN_SUCCESS; > + } > + // > + // Skip the 'X' > + // > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalIsHexaDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINT64, then MAX_UINT64 is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String)= , 4)) > { > + *Data =3D MAX_UINT64; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR16 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > Returns the length of a Null-terminated Ascii string. >=20 > This function is similar as strlen_s defined in C11. > @@ -1041,6 +1530,484 @@ AsciiStrnCatS ( > } >=20 > /** > + Convert a Null-terminated Ascii decimal string to a value of type UINT= N. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Ascii string specified by String as a decimal number. The format o= f the > + input Ascii string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrDecimalToUintnS ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ) > +{ > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than ASCII_RSIZE_MAX. > + // > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, > ASCII_RSIZE_MAX + 1) <=3D ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D ' ') || (*String =3D=3D '\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D '0') { > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalAsciiIsDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINTN, then MAX_UINTN is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) { > + *Data =3D MAX_UINTN; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D *Data * 10 + (*String - '0'); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Ascii decimal string to a value of type UINT= 64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Ascii string specified by String as a decimal number. The format o= f the > + input Ascii string String is: > + > + [spaces] [decimal digits]. > + > + The valid decimal digit character is in the range [0-9]. The function = will > + ignore the pad space, which includes spaces or tab characters, before > + [decimal digits]. The running zero in the beginning of [decimal digits= ] will > + be ignored. Then, the function stops at the first character that is a = not a > + valid decimal character or a Null-terminator, whichever one comes firs= t. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid decimal digits in the above format, then 0 is s= tored > + at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + decimal digits right after the optional pad spaces, the value of Strin= g 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrDecimalToUint64S ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ) > +{ > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than ASCII_RSIZE_MAX. > + // > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, > ASCII_RSIZE_MAX + 1) <=3D ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D ' ') || (*String =3D=3D '\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D '0') { > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalAsciiIsDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINT64, then MAX_UINT64 is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) { > + *Data =3D MAX_UINT64; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D MultU64x32 (*Data, 10) + (*String - '0'); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Ascii hexadecimal string to a value of type = UINTN. > + > + This function outputs a value of type UINTN by interpreting the conten= ts of > + the Ascii string specified by String as a hexadecimal number. The form= at of > + the input Ascii string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. If > + "x" appears in the input string, it must be prefixed with at least one= 0. The > + function will ignore the pad space, which includes spaces or tab chara= cters, > + before [zeros], [x] or [hexadecimal digits]. The running zero before [= x] or > + [hexadecimal digits] will be ignored. Then, the decoding starts after = [x] or > + the first valid hexadecimal digit. Then, the function stops at the fir= st > + character that is a not a valid hexadecimal character or Null-terminat= or, > + whichever on comes first. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINTN= , > then > + MAX_UINTN is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINTN. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrHexToUintnS ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINTN *Data > + ) > +{ > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than ASCII_RSIZE_MAX. > + // > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, > ASCII_RSIZE_MAX + 1) <=3D ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D ' ') || (*String =3D=3D '\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D '0') { > + String++; > + } > + > + if (InternalBaseLibAsciiToUpper (*String) =3D=3D 'X') { > + if (*(String - 1) !=3D '0') { > + *Data =3D 0; > + return RETURN_SUCCESS; > + } > + // > + // Skip the 'X' > + // > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINTN, then MAX_UINTN is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> = 4)) { > + *Data =3D MAX_UINTN; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D (*Data << 4) + InternalAsciiHexCharToUintn (*String); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > + Convert a Null-terminated Ascii hexadecimal string to a value of type = UINT64. > + > + This function outputs a value of type UINT64 by interpreting the conte= nts of > + the Ascii string specified by String as a hexadecimal number. The form= at of > + the input Ascii string String is: > + > + [spaces][zeros][x][hexadecimal digits]. > + > + The valid hexadecimal digit character is in the range [0-9], [a-f] and= [A-F]. > + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefi= x. If > + "x" appears in the input string, it must be prefixed with at least one= 0. The > + function will ignore the pad space, which includes spaces or tab chara= cters, > + before [zeros], [x] or [hexadecimal digits]. The running zero before [= x] or > + [hexadecimal digits] will be ignored. Then, the decoding starts after = [x] or > + the first valid hexadecimal digit. Then, the function stops at the fir= st > + character that is a not a valid hexadecimal character or Null-terminat= or, > + whichever on comes first. > + > + If String is NULL, then ASSERT(). > + If Data is NULL, then ASSERT(). > + If PcdMaximumAsciiStringLength is not zero, and String contains more t= han > + PcdMaximumAsciiStringLength Ascii characters, not including the > + Null-terminator, then ASSERT(). > + > + If String has no valid hexadecimal digits in the above format, then 0 = is > + stored at the location pointed to by Data. > + If the number represented by String exceeds the range defined by UINT6= 4, > then > + MAX_UINT64 is stored at the location pointed to by Data. > + > + If EndPointer is not NULL, a pointer to the character that stopped the= scan > + is stored at the location pointed to by EndPointer. If String has no v= alid > + hexadecimal digits right after the optional pad spaces, the value of S= tring > + 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 Data Pointer to the converted value. > + > + @retval RETURN_SUCCESS Value is translated from String. > + @retval RETURN_INVALID_PARAMETER If String is NULL. > + If Data is NULL. > + If PcdMaximumAsciiStringLength is not > zero, > + and String contains more than > + PcdMaximumAsciiStringLength Ascii > + characters, not including the > + Null-terminator. > + @retval RETURN_UNSUPPORTED If the number represented by String > exceeds > + the range defined by UINT64. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrHexToUint64S ( > + IN CONST CHAR8 *String, > + OUT CHAR8 **EndPointer, OPTIONAL > + OUT UINT64 *Data > + ) > +{ > + // > + // 1. Neither String nor Data shall be a null pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((String !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Data !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. The length of String shall not be greater than ASCII_RSIZE_MAX. > + // > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, > ASCII_RSIZE_MAX + 1) <=3D ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + > + // > + // Ignore the pad spaces (space or tab) > + // > + while ((*String =3D=3D ' ') || (*String =3D=3D '\t')) { > + String++; > + } > + > + // > + // Ignore leading Zeros after the spaces > + // > + while (*String =3D=3D '0') { > + String++; > + } > + > + if (InternalBaseLibAsciiToUpper (*String) =3D=3D 'X') { > + if (*(String - 1) !=3D '0') { > + *Data =3D 0; > + return RETURN_SUCCESS; > + } > + // > + // Skip the 'X' > + // > + String++; > + } > + > + *Data =3D 0; > + > + while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) { > + // > + // If the number represented by String overflows according to the ra= nge > + // defined by UINT64, then MAX_UINT64 is stored in *Data and > + // RETURN_UNSUPPORTED is returned. > + // > + if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*St= ring), > 4)) { > + *Data =3D MAX_UINT64; > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_UNSUPPORTED; > + } > + > + *Data =3D LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*Strin= g); > + String++; > + } > + > + if (EndPointer !=3D NULL) { > + *EndPointer =3D (CHAR8 *) String; > + } > + return RETURN_SUCCESS; > +} > + > +/** > Convert a Null-terminated Unicode string to a Null-terminated > ASCII string. >=20 > -- > 1.9.5.msysgit.0