From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (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 7EE66817B2 for ; Sun, 8 Jan 2017 18:03:52 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 08 Jan 2017 18:03:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,338,1477983600"; d="scan'208";a="806573467" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 08 Jan 2017 18:03:52 -0800 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.248.2; Sun, 8 Jan 2017 18:03:51 -0800 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) 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:03:52 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.88]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.204]) with mapi id 14.03.0248.002; Mon, 9 Jan 2017 10:03:48 +0800 From: "Yao, Jiewen" To: "Wu, Hao A" , "edk2-devel@lists.01.org" CC: "Gao, Liming" , "Kinney, Michael D" Thread-Topic: [PATCH 4/4] MdePkg/BaseLib: Add safe string functions [U|A]StrnTo[A|U]StrS Thread-Index: AQHSZnz9yx8XIJuKK06qdIHmy6syT6EvbDLw Date: Mon, 9 Jan 2017 02:03:47 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A8DCEA9@shsmsx102.ccr.corp.intel.com> References: <1483528957-28340-1-git-send-email-hao.a.wu@intel.com> <1483528957-28340-5-git-send-email-hao.a.wu@intel.com> In-Reply-To: <1483528957-28340-5-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 4/4] MdePkg/BaseLib: Add safe string functions [U|A]StrnTo[A|U]StrS 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:03:52 -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 4/4] MdePkg/BaseLib: Add safe string functions > [U|A]StrnTo[A|U]StrS >=20 > Add the following 2 APIs: > UnicodeStrnToAsciiStrS > AsciiStrnToUnicodeStrS >=20 > These APIs are used to enhance APIs UnicodeStrToAsciiStrS and > AsciiStrToUnicodeStrS (without 'n' in names) by: > 1. Adds an input parameter 'Length' to specify the maximum number of > Ascii/Unicode characters to convert. > 2. Adds an output parameter 'DestinationLength' to indicate the number of > Ascii/Unicode characters successfully converted. >=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 | 107 ++++++++++++++++ > MdePkg/Library/BaseLib/SafeString.c | 237 > ++++++++++++++++++++++++++++++++++++ > 2 files changed, 344 insertions(+) >=20 > diff --git a/MdePkg/Include/Library/BaseLib.h > b/MdePkg/Include/Library/BaseLib.h > index abea7b6..d71ccb7 100644 > --- a/MdePkg/Include/Library/BaseLib.h > +++ b/MdePkg/Include/Library/BaseLib.h > @@ -1631,6 +1631,60 @@ UnicodeStrToAsciiStrS ( > IN UINTN DestMax > ); >=20 > +/** > + Convert not more than Length successive characters from a Null-termina= ted > + Unicode string to a Null-terminated Ascii string. If no null char is c= opied > + from Source, then Destination[Length] is always set to null. > + > + This function converts not more than Length successive characters from= the > + Unicode string Source to the Ascii string Destination by copying the l= ower 8 > + bits of each Unicode character. The function terminates the Ascii stri= ng > + Destination by appending a Null-terminator character at the end. > + > + The caller is responsible to make sure Destination points to a buffer = with size > + equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in byte= s. > + > + If any Unicode characters in Source contain non-zero value in the uppe= r 8 > + bits, then ASSERT(). > + If Source is not aligned on a 16-bit boundary, then ASSERT(). > + If an error would be returned, then the function will also ASSERT(). > + > + If an error is returned, then the Destination is unmodified. > + > + @param Source The pointer to a Null-terminated Unicode > string. > + @param Length The maximum number of Unicode > characters to > + convert. > + @param Destination The pointer to a Null-terminated Ascii stri= ng. > + @param DestMax The maximum number of Destination Ascii > + char, including terminating null char. > + @param DestinationLength The number of Unicode characters converted. > + > + @retval RETURN_SUCCESS String is converted. > + @retval RETURN_INVALID_PARAMETER If Destination is NULL. > + If Source is NULL. > + If DestinationLength is NULL. > + If PcdMaximumAsciiStringLength is > not zero, > + and Length or DestMax is greater tha= n > + PcdMaximumAsciiStringLength. > + If PcdMaximumUnicodeStringLength > is not > + zero, and Length or DestMax is > greater than > + PcdMaximumUnicodeStringLength. > + If DestMax is 0. > + @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than > + MIN(StrLen(Source), Length). > + @retval RETURN_ACCESS_DENIED If Source and Destination overlap. > + > +**/ > +RETURN_STATUS > +EFIAPI > +UnicodeStrnToAsciiStrS ( > + IN CONST CHAR16 *Source, > + IN UINTN Length, > + OUT CHAR8 *Destination, > + IN UINTN DestMax, > + OUT UINTN *DestinationLength > + ); > + > #ifndef DISABLE_NEW_DEPRECATED_INTERFACES >=20 > /** > @@ -2219,6 +2273,59 @@ AsciiStrToUnicodeStrS ( > ); >=20 > /** > + Convert not more than Length successive characters from a Null-termina= ted > + Ascii string to a Null-terminated Unicode string. If no null char is c= opied > + from Source, then Destination[Length] is always set to null. > + > + This function converts not more than Length successive characters from= the > + Ascii string Source to the Unicode string Destination. The function > + terminates the Unicode string Destination by appending a Null-terminat= or > + character at the end. > + > + The caller is responsible to make sure Destination points to a buffer = with > + size not smaller than > + ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes. > + > + If Destination is not aligned on a 16-bit boundary, then ASSERT(). > + If an error would be returned, then the function will also ASSERT(). > + > + If an error is returned, then Destination and DestinationLength are > + unmodified. > + > + @param Source The pointer to a Null-terminated Ascii stri= ng. > + @param Length The maximum number of Ascii characters to > convert. > + @param Destination The pointer to a Null-terminated Unicode > string. > + @param DestMax The maximum number of Destination > Unicode char, > + including terminating null char. > + @param DestinationLength The number of Ascii characters converted. > + > + @retval RETURN_SUCCESS String is converted. > + @retval RETURN_INVALID_PARAMETER If Destination is NULL. > + If Source is NULL. > + If DestinationLength is NULL. > + If PcdMaximumUnicodeStringLength > is not > + zero, and Length or DestMax is > greater than > + PcdMaximumUnicodeStringLength. > + If PcdMaximumAsciiStringLength is > not zero, > + and Length or DestMax is greater tha= n > + PcdMaximumAsciiStringLength. > + If DestMax is 0. > + @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than > + MIN(AsciiStrLen(Source), Length). > + @retval RETURN_ACCESS_DENIED If Source and Destination overlap. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrnToUnicodeStrS ( > + IN CONST CHAR8 *Source, > + IN UINTN Length, > + OUT CHAR16 *Destination, > + IN UINTN DestMax, > + OUT UINTN *DestinationLength > + ); > + > +/** > Converts an 8-bit value to an 8-bit BCD value. >=20 > Converts the 8-bit value specified by Value to BCD. The BCD value is > diff --git a/MdePkg/Library/BaseLib/SafeString.c > b/MdePkg/Library/BaseLib/SafeString.c > index 5edc6ef..315059e 100644 > --- a/MdePkg/Library/BaseLib/SafeString.c > +++ b/MdePkg/Library/BaseLib/SafeString.c > @@ -2108,6 +2108,128 @@ UnicodeStrToAsciiStrS ( > return RETURN_SUCCESS; > } >=20 > +/** > + Convert not more than Length successive characters from a Null-termina= ted > + Unicode string to a Null-terminated Ascii string. If no null char is c= opied > + from Source, then Destination[Length] is always set to null. > + > + This function converts not more than Length successive characters from= the > + Unicode string Source to the Ascii string Destination by copying the l= ower 8 > + bits of each Unicode character. The function terminates the Ascii stri= ng > + Destination by appending a Null-terminator character at the end. > + > + The caller is responsible to make sure Destination points to a buffer = with > + size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHA= R8)) > + in bytes. > + > + If any Unicode characters in Source contain non-zero value in the uppe= r 8 > + bits, then ASSERT(). > + If Source is not aligned on a 16-bit boundary, then ASSERT(). > + If an error would be returned, then the function will also ASSERT(). > + > + If an error is returned, then Destination and DestinationLength are > + unmodified. > + > + @param Source The pointer to a Null-terminated Unicode > string. > + @param Length The maximum number of Unicode > characters to > + convert. > + @param Destination The pointer to a Null-terminated Ascii stri= ng. > + @param DestMax The maximum number of Destination Ascii > char, > + including terminating null char. > + @param DestinationLength The number of Unicode characters converted. > + > + @retval RETURN_SUCCESS String is converted. > + @retval RETURN_INVALID_PARAMETER If Destination is NULL. > + If Source is NULL. > + If DestinationLength is NULL. > + If PcdMaximumAsciiStringLength is > not zero, > + and Length or DestMax is greater tha= n > + PcdMaximumAsciiStringLength. > + If PcdMaximumUnicodeStringLength > is not > + zero, and Length or DestMax is > greater than > + PcdMaximumUnicodeStringLength. > + If DestMax is 0. > + @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than > + MIN(StrLen(Source), Length). > + @retval RETURN_ACCESS_DENIED If Source and Destination overlap. > + > +**/ > +RETURN_STATUS > +EFIAPI > +UnicodeStrnToAsciiStrS ( > + IN CONST CHAR16 *Source, > + IN UINTN Length, > + OUT CHAR8 *Destination, > + IN UINTN DestMax, > + OUT UINTN *DestinationLength > + ) > +{ > + UINTN SourceLen; > + > + ASSERT (((UINTN) Source & BIT0) =3D=3D 0); > + > + // > + // 1. None of Destination, Source or DestinationLength shall be a null > + // pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((Destination !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Source !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX= or > + // RSIZE_MAX. > + // > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((Length <=3D ASCII_RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <=3D ASCII_RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + } > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((Length <=3D RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <=3D RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + } > + > + // > + // 3. DestMax shall not equal zero. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax !=3D 0), > RETURN_INVALID_PARAMETER); > + > + // > + // 4. If Length is not less than DestMax, then DestMax shall be greate= r than > + // StrnLenS(Source, DestMax). > + // > + SourceLen =3D StrnLenS (Source, DestMax); > + if (Length >=3D DestMax) { > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), > RETURN_BUFFER_TOO_SMALL); > + } > + > + // > + // 5. Copying shall not take place between objects that overlap. > + // > + if (SourceLen > Length) { > + SourceLen =3D Length; > + } > + SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap > (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), > RETURN_ACCESS_DENIED); > + > + *DestinationLength =3D 0; > + > + // > + // Convert string > + // > + while ((*Source !=3D 0) && (SourceLen > 0)) { > + // > + // If any Unicode characters in Source contain non-zero value in the= upper > + // 8 bits, then ASSERT(). > + // > + ASSERT (*Source < 0x100); > + *(Destination++) =3D (CHAR8) *(Source++); > + SourceLen--; > + (*DestinationLength)++; > + } > + *Destination =3D 0; > + > + return RETURN_SUCCESS; > +} >=20 > /** > Convert one Null-terminated ASCII string to a Null-terminated > @@ -2200,3 +2322,118 @@ AsciiStrToUnicodeStrS ( >=20 > return RETURN_SUCCESS; > } > + > +/** > + Convert not more than Length successive characters from a Null-termina= ted > + Ascii string to a Null-terminated Unicode string. If no null char is c= opied > + from Source, then Destination[Length] is always set to null. > + > + This function converts not more than Length successive characters from= the > + Ascii string Source to the Unicode string Destination. The function > + terminates the Unicode string Destination by appending a Null-terminat= or > + character at the end. > + > + The caller is responsible to make sure Destination points to a buffer = with > + size not smaller than > + ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes. > + > + If Destination is not aligned on a 16-bit boundary, then ASSERT(). > + If an error would be returned, then the function will also ASSERT(). > + > + If an error is returned, then Destination and DestinationLength are > + unmodified. > + > + @param Source The pointer to a Null-terminated Ascii stri= ng. > + @param Length The maximum number of Ascii characters to > convert. > + @param Destination The pointer to a Null-terminated Unicode > string. > + @param DestMax The maximum number of Destination > Unicode char, > + including terminating null char. > + @param DestinationLength The number of Ascii characters converted. > + > + @retval RETURN_SUCCESS String is converted. > + @retval RETURN_INVALID_PARAMETER If Destination is NULL. > + If Source is NULL. > + If DestinationLength is NULL. > + If PcdMaximumUnicodeStringLength > is not > + zero, and Length or DestMax is > greater than > + PcdMaximumUnicodeStringLength. > + If PcdMaximumAsciiStringLength is > not zero, > + and Length or DestMax is greater tha= n > + PcdMaximumAsciiStringLength. > + If DestMax is 0. > + @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than > + MIN(AsciiStrLen(Source), Length). > + @retval RETURN_ACCESS_DENIED If Source and Destination overlap. > + > +**/ > +RETURN_STATUS > +EFIAPI > +AsciiStrnToUnicodeStrS ( > + IN CONST CHAR8 *Source, > + IN UINTN Length, > + OUT CHAR16 *Destination, > + IN UINTN DestMax, > + OUT UINTN *DestinationLength > + ) > +{ > + UINTN SourceLen; > + > + ASSERT (((UINTN) Destination & BIT0) =3D=3D 0); > + > + // > + // 1. None of Destination, Source or DestinationLength shall be a null > + // pointer. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((Destination !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((Source !=3D NULL), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength !=3D NULL), > RETURN_INVALID_PARAMETER); > + > + // > + // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX= or > + // RSIZE_MAX. > + // > + if (RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((Length <=3D RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <=3D RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + } > + if (ASCII_RSIZE_MAX !=3D 0) { > + SAFE_STRING_CONSTRAINT_CHECK ((Length <=3D ASCII_RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax <=3D ASCII_RSIZE_MAX), > RETURN_INVALID_PARAMETER); > + } > + > + // > + // 3. DestMax shall not equal zero. > + // > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax !=3D 0), > RETURN_INVALID_PARAMETER); > + > + // > + // 4. If Length is not less than DestMax, then DestMax shall be greate= r than > + // AsciiStrnLenS(Source, DestMax). > + // > + SourceLen =3D AsciiStrnLenS (Source, DestMax); > + if (Length >=3D DestMax) { > + SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), > RETURN_BUFFER_TOO_SMALL); > + } > + > + // > + // 5. Copying shall not take place between objects that overlap. > + // > + if (SourceLen > Length) { > + SourceLen =3D Length; > + } > + SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap > (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), > RETURN_ACCESS_DENIED); > + > + *DestinationLength =3D 0; > + > + // > + // Convert string > + // > + while ((*Source !=3D 0) && (SourceLen > 0)) { > + *(Destination++) =3D (CHAR16)*(Source++); > + SourceLen--; > + (*DestinationLength)++; > + } > + *Destination =3D 0; > + > + return RETURN_SUCCESS; > +} > -- > 1.9.5.msysgit.0