From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.45]) by mx.groups.io with SMTP id smtpd.web10.1093.1589482768433222919 for ; Thu, 14 May 2020 11:59:29 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: ispras.ru, ip: 83.149.199.45, mailfrom: cheptsov@ispras.ru) Received: from [127.0.0.1] (unknown [77.232.9.83]) by mail.ispras.ru (Postfix) with ESMTPSA id 070AECD469; Thu, 14 May 2020 21:59:24 +0300 (MSK) From: "Vitaly Cheptsov" Message-Id: Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: [edk2-devel] [PATCH V6 1/1] MdePkg: Fix SafeString performing assertions on runtime checks Date: Thu, 14 May 2020 21:59:24 +0300 In-Reply-To: Cc: "devel@edk2.groups.io" , Andrew Fish , Ard Biesheuvel , Bret Barkelew , "Brian J . Johnson" , "Chiu, Chasel" , "Justen, Jordan L" , Laszlo Ersek , Leif Lindholm , "Gao, Liming" , =?utf-8?Q?Marvin_H=C3=A4user?= , "Zimmer, Vincent" , "Gao, Zhichao" To: "Kinney, Michael D" References: <20200514092537.29609-1-cheptsov@ispras.ru> <20200514092537.29609-2-cheptsov@ispras.ru> X-Mailer: Apple Mail (2.3608.80.23.2.2) X-Groupsio-MsgNum: 59587 Content-Type: multipart/signed; boundary="Apple-Mail=_29A8425E-B314-49E0-99DA-97E8A9D2BBC1"; protocol="application/pgp-signature"; micalg=pgp-sha512 --Apple-Mail=_29A8425E-B314-49E0-99DA-97E8A9D2BBC1 Content-Type: multipart/alternative; boundary="Apple-Mail=_83B0548A-316B-4724-9912-726F3D3B9DBA" --Apple-Mail=_83B0548A-316B-4724-9912-726F3D3B9DBA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Mike, The code you posted may inflict undefined behaviour is not valid C for sev= eral reasons. The compiler is free to do whatever it desires. Please refer = to ISO/IEC 9899 for more details. If applications cast raw pointers to typed pointers without checking their= alignment, well, god bless them :) My opinion is both the compiler and the hardware are welcome to do the wor= st once your third line is discovered. On a number of CPUs such addresses c= annot be even represented in the first place. Yet, once again it is out of the scope of the current problem. Best wishes, Vitaly > 14 =D0=BC=D0=B0=D1=8F 2020 =D0=B3., =D0=B2 20:58, Kinney, Michael D =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0)= : >=20 > Vitaly, >=20 > Why do you think there is no way to craft an odd address > without memory corruption. >=20 > UINT8 ByteArray[100]; > CHAR16 *String >=20 > String =3D (CHAR16 *)(&Array[3]); >=20 > The reason I raised the question of these other ASSERT()s > is that I thought the use case was using these safe string > APIs from a UEFI App, and the UEFI App always wants to evaluate > the return status to know if the operation was completed or > not. In build that removes all ASSERT()s, an odd address > will generate an exception on some CPU archs. Wouldn=E2=80=99t it > be better for the UEFI App that is already designed to handle > error return status to get an error code instead of an > exception? >=20 > Mike >=20 >> -----Original Message----- >> From: devel@edk2.groups.io > On >> Behalf Of Vitaly Cheptsov >> Sent: Thursday, May 14, 2020 10:39 AM >> To: Kinney, Michael D > >> Cc: devel@edk2.groups.io ; Andrew Fish >> >; Ard Biesheuvel >> >; Bret Ba= rkelew >> >; Bri= an J . Johnson >> >; Chiu, Chasel >> >; Justen, Jordan = L >> >; Laszlo = Ersek >> >; Leif Lindholm >; >> Gao, Liming >; Marvi= n H=C3=A4user >> >; Zimmer, Vincent >> >; Gao, Zhic= hao >> > >> Subject: Re: [edk2-devel] [PATCH V6 1/1] MdePkg: Fix >> SafeString performing assertions on runtime checks >>=20 >> Mike, >>=20 >> Firstly, NULL check and odd-address checks are >> essentially different things: >> =E2=80=94 NULL address is basically =C2=ABno object=C2=BB, =C2=ABoption= al >> argument=C2=BB (e.g. failed allocation). >> =E2=80=94 Odd address is memory corruption, as there is no way >> to craft such address anyhow else. >> For this reason the implementation is allowed to treat >> them differently. >>=20 >> Secondly, as I said in my cover letter there is no >> behaviour change here for RELEASE builds. Behaviour >> changes unrelated to the bugfix will have to go to a >> separate patch. I agree that we may want to reconsider >> the interface in the future, but that=E2=80=99s for a separate >> bugzilla and patch. Not discussing it currently is >> important to avoid diverting from the primary problem. >> Could create a bugzilla not to forget about it soon >> after the stable tag. >>=20 >> Best wishes, >> Vitaly >>=20 >>> 14 =D0=BC=D0=B0=D1=8F 2020 =D0=B3., =D0=B2 19:38, Kinney, Michael D >> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB= (=D0=B0): >>>=20 >>> Why preserve the ASSERT()s for an a Unicode strings >>> that are not aligned in a 16-bit boundary? >>>=20 >>> This is essentially the same as an invalid pointer >> value >>> just like NULL. If NULL pointer returns an error >> code, >>> shouldn't and invalid pointer value? >>>=20 >>> Thanks, >>>=20 >>> Mike >>>=20 >>>> -----Original Message----- >>>> From: devel@edk2.groups.io On >>>> Behalf Of Vitaly Cheptsov >>>> Sent: Thursday, May 14, 2020 2:26 AM >>>> To: devel@edk2.groups.io >>>> Cc: Andrew Fish ; Ard Biesheuvel >>>> ; Bret Barkelew >>>> ; Brian J . Johnson >>>> ; Chiu, Chasel >>>> ; Justen, Jordan L >>>> ; Laszlo Ersek >>>> ; Leif Lindholm >> ; >>>> Gao, Liming ; Marvin H=C3=A4user >>>> ; Kinney, Michael D >>>> ; Zimmer, Vincent >>>> ; Gao, Zhichao >>>> >>>> Subject: [edk2-devel] [PATCH V6 1/1] MdePkg: Fix >>>> SafeString performing assertions on runtime checks >>>>=20 >>>> REF: >>>> https://bugzilla.tianocore.org/show_bug.cgi?id=3D2054 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> Runtime checks returned via status return code >> should >>>> not work as >>>>=20 >>>>=20 >>>> assertions to permit parsing not trusted data with >>>> SafeString >>>>=20 >>>>=20 >>>> interfaces. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> CC: Andrew Fish >>>>=20 >>>>=20 >>>> CC: Ard Biesheuvel >>>>=20 >>>>=20 >>>> CC: Bret Barkelew >>>>=20 >>>>=20 >>>> CC: Brian J. Johnson >>>>=20 >>>>=20 >>>> CC: Chasel Chiu >>>>=20 >>>>=20 >>>> CC: Jordan Justen >>>>=20 >>>>=20 >>>> CC: Laszlo Ersek >>>>=20 >>>>=20 >>>> CC: Leif Lindholm >>>>=20 >>>>=20 >>>> CC: Liming Gao >>>>=20 >>>>=20 >>>> CC: Marvin H=C3=A4user >>>>=20 >>>>=20 >>>> CC: Mike Kinney >>>>=20 >>>>=20 >>>> CC: Vincent Zimmer >>>>=20 >>>>=20 >>>> CC: Zhichao Gao >>>>=20 >>>>=20 >>>> Signed-off-by: Vitaly Cheptsov >> >>>>=20 >>>>=20 >>>> --- >>>>=20 >>>>=20 >>>> MdePkg/Include/Library/BaseLib.h | 120 ++-------- >> -- >>>> -------- >>>>=20 >>>>=20 >>>> MdePkg/Library/BaseLib/SafeString.c | 80 ---------- >> -- >>>> - >>>>=20 >>>>=20 >>>> 2 files changed, 7 insertions(+), 193 deletions(-) >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> diff --git a/MdePkg/Include/Library/BaseLib.h >>>> b/MdePkg/Include/Library/BaseLib.h >>>>=20 >>>>=20 >>>> index ecadff8b23..62dc3151bc 100644 >>>>=20 >>>>=20 >>>> --- a/MdePkg/Include/Library/BaseLib.h >>>>=20 >>>>=20 >>>> +++ b/MdePkg/Include/Library/BaseLib.h >>>>=20 >>>>=20 >>>> @@ -189,7 +189,6 @@ StrnSizeS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -225,7 +224,6 @@ StrCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Length > 0 and Destination is not aligned on a >>>> 16-bit boundary, then ASSERT(). >>>>=20 >>>>=20 >>>> If Length > 0 and Source is not aligned on a 16- >> bit >>>> boundary, then ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -263,7 +261,6 @@ StrnCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -303,7 +300,6 @@ StrCatS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -350,12 +346,7 @@ StrnCatS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -406,12 +397,7 @@ StrDecimalToUintnS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -467,12 +453,7 @@ StrDecimalToUint64S ( >>>>=20 >>>>=20 >>>> the first character that is a not a valid >>>> hexadecimal character or NULL, >>>>=20 >>>>=20 >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -528,12 +509,7 @@ StrHexToUintnS ( >>>>=20 >>>>=20 >>>> the first character that is a not a valid >>>> hexadecimal character or NULL, >>>>=20 >>>>=20 >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -622,8 +598,6 @@ AsciiStrnSizeS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strcpy_s defined in >> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -656,8 +630,6 @@ AsciiStrCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strncpy_s defined in >>>> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -692,8 +664,6 @@ AsciiStrnCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strcat_s defined in >> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -730,8 +700,6 @@ AsciiStrCatS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strncat_s defined in >>>> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -777,12 +745,6 @@ AsciiStrnCatS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINTN, then >>>>=20 >>>>=20 >>>> @@ -832,12 +794,6 @@ AsciiStrDecimalToUintnS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINT64, then >>>>=20 >>>>=20 >>>> @@ -891,12 +847,6 @@ AsciiStrDecimalToUint64S ( >>>>=20 >>>>=20 >>>> character that is a not a valid hexadecimal >>>> character or Null-terminator, >>>>=20 >>>>=20 >>>> whichever on comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINTN, then >>>>=20 >>>>=20 >>>> @@ -950,12 +900,6 @@ AsciiStrHexToUintnS ( >>>>=20 >>>>=20 >>>> character that is a not a valid hexadecimal >>>> character or Null-terminator, >>>>=20 >>>>=20 >>>> whichever on comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINT64, then >>>>=20 >>>>=20 >>>> @@ -1506,16 +1450,8 @@ StrHexToUint64 ( >>>>=20 >>>>=20 >>>> "::" can be used to compress one or more groups of >> X >>>> when X contains only 0. >>>>=20 >>>>=20 >>>> The "::" can only appear once in the String. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> by EndPointer. >>>>=20 >>>>=20 >>>> @@ -1567,15 +1503,10 @@ StrToIpv6Address ( >>>>=20 >>>>=20 >>>> When /P is in the String, the function stops at >> the >>>> first character that is not >>>>=20 >>>>=20 >>>> a valid decimal digit character after P is >>>> converted. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> @@ -1640,8 +1571,6 @@ StrToIpv4Address ( >>>>=20 >>>>=20 >>>> oo Data4[48:55] >>>>=20 >>>>=20 >>>> pp Data4[56:63] >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Guid is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated Unicode string. >>>>=20 >>>>=20 >>>> @@ -1676,17 +1605,6 @@ StrToGuid ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Buffer is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Length is not multiple of 2, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero and >>>> Length is greater than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If MaxBufferSize is less than (Length / 2), then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated Unicode string. >>>>=20 >>>>=20 >>>> @param Length The number of >>>> Unicode characters to decode. >>>>=20 >>>>=20 >>>> @param Buffer Pointer to the >>>> converted bytes array. >>>>=20 >>>>=20 >>>> @@ -1777,7 +1695,6 @@ UnicodeStrToAsciiStr ( >>>>=20 >>>>=20 >>>> the upper 8 bits, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -1818,22 +1735,23 @@ UnicodeStrToAsciiStrS ( >>>>=20 >>>>=20 >>>> bits of each Unicode character. The function >>>> terminates the Ascii string >>>>=20 >>>>=20 >>>> Destination by appending a Null-terminator >> character >>>> at the end. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - The caller is responsible to make sure >> Destination >>>> points to a buffer with size >>>>=20 >>>>=20 >>>> - equal or greater than ((StrLen (Source) + 1) * >>>> sizeof (CHAR8)) in bytes. >>>>=20 >>>>=20 >>>> + The caller is responsible to make sure >> Destination >>>> points to a buffer with >>>>=20 >>>>=20 >>>> + size not smaller than ((MIN(StrLen(Source), >> Length) >>>> + 1) * sizeof (CHAR8)) >>>>=20 >>>>=20 >>>> + in bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If any Unicode characters in Source contain non- >> zero >>>> value in the upper 8 >>>>=20 >>>>=20 >>>> bits, then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>> + If an error is returned, then Destination and >>>> DestinationLength are >>>>=20 >>>>=20 >>>> + unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Source The pointer to a Null- >>>> terminated Unicode string. >>>>=20 >>>>=20 >>>> @param Length The maximum number of >>>> Unicode characters to >>>>=20 >>>>=20 >>>> convert. >>>>=20 >>>>=20 >>>> @param Destination The pointer to a Null- >>>> terminated Ascii string. >>>>=20 >>>>=20 >>>> - @param DestMax The maximum number of >>>> Destination Ascii >>>>=20 >>>>=20 >>>> - char, including >>>> terminating null char. >>>>=20 >>>>=20 >>>> + @param DestMax The maximum number of >>>> Destination Ascii char, >>>>=20 >>>>=20 >>>> + including terminating >>>> null char. >>>>=20 >>>>=20 >>>> @param DestinationLength The number of Unicode >>>> characters converted. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @retval RETURN_SUCCESS String is >>>> converted. >>>>=20 >>>>=20 >>>> @@ -2388,10 +2306,6 @@ AsciiStrHexToUint64 ( >>>>=20 >>>>=20 >>>> "::" can be used to compress one or more groups of >> X >>>> when X contains only 0. >>>>=20 >>>>=20 >>>> The "::" can only appear once in the String. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> by EndPointer. >>>>=20 >>>>=20 >>>> @@ -2443,10 +2357,6 @@ AsciiStrToIpv6Address ( >>>>=20 >>>>=20 >>>> When /P is in the String, the function stops at >> the >>>> first character that is not >>>>=20 >>>>=20 >>>> a valid decimal digit character after P is >>>> converted. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> by EndPointer. >>>>=20 >>>>=20 >>>> @@ -2508,9 +2418,6 @@ AsciiStrToIpv4Address ( >>>>=20 >>>>=20 >>>> oo Data4[48:55] >>>>=20 >>>>=20 >>>> pp Data4[56:63] >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Guid is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated ASCII string. >>>>=20 >>>>=20 >>>> @param Guid Pointer to the >>>> converted GUID. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -2541,17 +2448,6 @@ AsciiStrToGuid ( >>>>=20 >>>>=20 >>>> decoding stops after Length of characters and >>>> outputs Buffer containing >>>>=20 >>>>=20 >>>> (Length / 2) bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Buffer is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Length is not multiple of 2, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero and >>>> Length is greater than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If MaxBufferSize is less than (Length / 2), then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated ASCII string. >>>>=20 >>>>=20 >>>> @param Length The number of >> ASCII >>>> characters to decode. >>>>=20 >>>>=20 >>>> @param Buffer Pointer to the >>>> converted bytes array. >>>>=20 >>>>=20 >>>> @@ -2632,7 +2528,6 @@ AsciiStrToUnicodeStr ( >>>>=20 >>>>=20 >>>> equal or greater than ((AsciiStrLen (Source) + 1) >> * >>>> sizeof (CHAR16)) in bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -2678,7 +2573,6 @@ AsciiStrToUnicodeStrS ( >>>>=20 >>>>=20 >>>> ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof >>>> (CHAR8)) in bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then Destination and >>>> DestinationLength are >>>>=20 >>>>=20 >>>> unmodified. >>>>=20 >>>>=20 >>>> diff --git a/MdePkg/Library/BaseLib/SafeString.c >>>> b/MdePkg/Library/BaseLib/SafeString.c >>>>=20 >>>>=20 >>>> index 7dc03d2caa..1db42abb05 100644 >>>>=20 >>>>=20 >>>> --- a/MdePkg/Library/BaseLib/SafeString.c >>>>=20 >>>>=20 >>>> +++ b/MdePkg/Library/BaseLib/SafeString.c >>>>=20 >>>>=20 >>>> @@ -14,7 +14,6 @@ >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> #define SAFE_STRING_CONSTRAINT_CHECK(Expression, >>>> Status) \ >>>>=20 >>>>=20 >>>> do { \ >>>>=20 >>>>=20 >>>> - ASSERT (Expression); \ >>>>=20 >>>>=20 >>>> if (!(Expression)) { \ >>>>=20 >>>>=20 >>>> return Status; \ >>>>=20 >>>>=20 >>>> } \ >>>>=20 >>>>=20 >>>> @@ -197,7 +196,6 @@ StrnSizeS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -279,7 +277,6 @@ StrCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Length > 0 and Destination is not aligned on a >>>> 16-bit boundary, then ASSERT(). >>>>=20 >>>>=20 >>>> If Length > 0 and Source is not aligned on a 16- >> bit >>>> boundary, then ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -372,7 +369,6 @@ StrnCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -473,7 +469,6 @@ StrCatS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -590,12 +585,7 @@ StrnCatS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -705,12 +695,7 @@ StrDecimalToUintnS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -825,12 +810,7 @@ StrDecimalToUint64S ( >>>>=20 >>>>=20 >>>> the first character that is a not a valid >>>> hexadecimal character or NULL, >>>>=20 >>>>=20 >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -956,12 +936,7 @@ StrHexToUintnS ( >>>>=20 >>>>=20 >>>> the first character that is a not a valid >>>> hexadecimal character or NULL, >>>>=20 >>>>=20 >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> If String is not aligned in a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumUnicodeStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumUnicodeStringLength Unicode characters, >>>> not including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> @@ -1856,8 +1831,6 @@ AsciiStrCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strncpy_s defined in >>>> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -1944,8 +1917,6 @@ AsciiStrnCpyS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strcat_s defined in >> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -2040,8 +2011,6 @@ AsciiStrCatS ( >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> This function is similar as strncat_s defined in >>>> C11. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @param Destination A pointer to a >>>> Null-terminated Ascii string. >>>>=20 >>>>=20 >>>> @@ -2154,12 +2123,6 @@ AsciiStrnCatS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINTN, then >>>>=20 >>>>=20 >>>> @@ -2266,12 +2229,6 @@ AsciiStrDecimalToUintnS ( >>>>=20 >>>>=20 >>>> be ignored. Then, the function stops at the first >>>> character that is a not a >>>>=20 >>>>=20 >>>> valid decimal character or a Null-terminator, >>>> whichever one comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid decimal digits in the above >>>> format, then 0 is stored >>>>=20 >>>>=20 >>>> at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINT64, then >>>>=20 >>>>=20 >>>> @@ -2382,12 +2339,6 @@ AsciiStrDecimalToUint64S ( >>>>=20 >>>>=20 >>>> character that is a not a valid hexadecimal >>>> character or Null-terminator, >>>>=20 >>>>=20 >>>> whichever on comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINTN, then >>>>=20 >>>>=20 >>>> @@ -2509,12 +2460,6 @@ AsciiStrHexToUintnS ( >>>>=20 >>>>=20 >>>> character that is a not a valid hexadecimal >>>> character or Null-terminator, >>>>=20 >>>>=20 >>>> whichever on comes first. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Data is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero, and >>>> String contains more than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength Ascii characters, not >>>> including the >>>>=20 >>>>=20 >>>> - Null-terminator, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If String has no valid hexadecimal digits in the >>>> above format, then 0 is >>>>=20 >>>>=20 >>>> stored at the location pointed to by Data. >>>>=20 >>>>=20 >>>> If the number represented by String exceeds the >>>> range defined by UINT64, then >>>>=20 >>>>=20 >>>> @@ -2635,7 +2580,6 @@ AsciiStrHexToUint64S ( >>>>=20 >>>>=20 >>>> the upper 8 bits, then ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then the Destination is >>>> unmodified. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -2735,7 +2679,6 @@ UnicodeStrToAsciiStrS ( >>>>=20 >>>>=20 >>>> If any Unicode characters in Source contain non- >> zero >>>> value in the upper 8 >>>>=20 >>>>=20 >>>> bits, then ASSERT(). >>>>=20 >>>>=20 >>>> If Source is not aligned on a 16-bit boundary, >> then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then Destination and >>>> DestinationLength are >>>>=20 >>>>=20 >>>> unmodified. >>>>=20 >>>>=20 >>>> @@ -2948,7 +2891,6 @@ AsciiStrToUnicodeStrS ( >>>>=20 >>>>=20 >>>> ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof >>>> (CHAR8)) in bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If Destination is not aligned on a 16-bit >> boundary, >>>> then ASSERT(). >>>>=20 >>>>=20 >>>> - If an error would be returned, then the function >>>> will also ASSERT(). >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> If an error is returned, then Destination and >>>> DestinationLength are >>>>=20 >>>>=20 >>>> unmodified. >>>>=20 >>>>=20 >>>> @@ -3072,10 +3014,6 @@ AsciiStrnToUnicodeStrS ( >>>>=20 >>>>=20 >>>> "::" can be used to compress one or more groups of >> X >>>> when X contains only 0. >>>>=20 >>>>=20 >>>> The "::" can only appear once in the String. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> by EndPointer. >>>>=20 >>>>=20 >>>> @@ -3291,10 +3229,6 @@ AsciiStrToIpv6Address ( >>>>=20 >>>>=20 >>>> When /P is in the String, the function stops at >> the >>>> first character that is not >>>>=20 >>>>=20 >>>> a valid decimal digit character after P is >>>> converted. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Address is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> If EndPointer is not NULL and Address is >> translated >>>> from String, a pointer >>>>=20 >>>>=20 >>>> to the character that stopped the scan is stored >> at >>>> the location pointed to >>>>=20 >>>>=20 >>>> by EndPointer. >>>>=20 >>>>=20 >>>> @@ -3448,9 +3382,6 @@ AsciiStrToIpv4Address ( >>>>=20 >>>>=20 >>>> oo Data4[48:55] >>>>=20 >>>>=20 >>>> pp Data4[56:63] >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - If Guid is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated ASCII string. >>>>=20 >>>>=20 >>>> @param Guid Pointer to the >>>> converted GUID. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> @@ -3550,17 +3481,6 @@ AsciiStrToGuid ( >>>>=20 >>>>=20 >>>> decoding stops after Length of characters and >>>> outputs Buffer containing >>>>=20 >>>>=20 >>>> (Length / 2) bytes. >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> - If String is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Buffer is NULL, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If Length is not multiple of 2, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If PcdMaximumAsciiStringLength is not zero and >>>> Length is greater than >>>>=20 >>>>=20 >>>> - PcdMaximumAsciiStringLength, then ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> - If MaxBufferSize is less than (Length / 2), then >>>> ASSERT(). >>>>=20 >>>>=20 >>>> - >>>>=20 >>>>=20 >>>> @param String Pointer to a >> Null- >>>> terminated ASCII string. >>>>=20 >>>>=20 >>>> @param Length The number of >> ASCII >>>> characters to decode. >>>>=20 >>>>=20 >>>> @param Buffer Pointer to the >>>> converted bytes array. >>>>=20 >>>>=20 >>>> -- >>>>=20 >>>>=20 >>>> 2.24.2 (Apple Git-127) >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>=20 >>=20 >>=20 >>=20 --Apple-Mail=_83B0548A-316B-4724-9912-726F3D3B9DBA Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 Mike,

The code you posted may inflict undefined = behaviour is not valid C for several reasons. The compiler is free to do wh= atever it desires. Please refer to ISO/IEC 9899 for more details.

If applications cast raw p= ointers to typed pointers without checking their alignment, well, god bless= them :)
My opinion is both the compiler and the hardw= are are welcome to do the worst once your third line is discovered. On a nu= mber of CPUs such addresses cannot be even represented in the first place.<= /div>

Yet, once again i= t is out of the scope of the current problem.

Best wishes,
Vitaly
=


14 =D0=BC=D0=B0=D1=8F 20= 20 =D0=B3., =D0=B2 20:58, Kinney, Michael D <michael.d.kinney@intel.com> =D0=BD=D0= =B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0):

Vitaly,

Why do you thi= nk there is no way to craft an odd address 
wit= hout memory corruption.

UINT8   ByteArray[100];
CHAR16  *String

String =3D (CHAR16 *)(&Array[3]);

The rea= son I raised the question of these other ASSERT()s
is that I thought the use case was using these = safe string
APIs from a= UEFI App, and the UEFI App always wants to evaluate
the return status to know if the operation wa= s completed or
not. &nb= sp;In build that removes all ASSERT()s, an odd address
will generate an exception on some CPU arch= s.  Wouldn=E2=80=99t it
<= span style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size:= 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; = letter-spacing: normal; text-align: start; text-indent: 0px; text-transform= : none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: = 0px; text-decoration: none; float: none; display: inline !important;" class= = =3D"">be better for the UEFI App that is already designed to handle
=
error return status to get an= error code instead of an 
exception?

<= span style=3D"caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size:= 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; = letter-spacing: normal; text-align: start; text-indent: 0px; text-transform= : none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: = 0px; text-decoration: none; float: none; display: inline !important;" class= = =3D"">Mike


-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On
Behalf O= f Vitaly Cheptsov
Sent: Thursday, May 14, 2020 10:39 AM
To: Kinney, Michael D <michael.d.kinney@intel.com>
Cc: devel@edk2.groups.io; Andrew Fish
&l= t;afish@apple.com>; Ar= d Biesheuvel
<ard.biesheuvel@linaro.org>; Bret Barkelew
= <bret.barkelew= @microsoft.com>; Brian J . Johnson
<brian.johnson@hpe.com>; Chiu, C= hasel
<chasel.chiu@intel.com>; Justen, Jordan L
<jordan.l.justen@intel.com= >; Laszlo Ersek
<lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
Ga= o, Liming <liming.gao= @intel.com>; Marvin H=C3=A4user
<mhaeuser@outlook.de>; Zimmer, Vincen= t
<= vincent.zimmer@intel.com>; Gao, Zhichao
<zhichao.gao@intel.com>
Subject: Re: [edk2-devel] [PATCH V6 1/1] MdePkg: Fix
SafeString performing assertions on runtime checks

Mike,

Firstly, NULL check and odd-addr= ess checks are
essentially different things:
= =E2=80=94 NULL address is basically =C2=ABno object=C2=BB, =C2=ABoptional<= br class=3D"">argument=C2=BB (e.g. failed allocation).
=E2=80= = =94 Odd address is memory corruption, as there is no way
to = craft such address anyhow else.
For this reason the implement= ation is allowed to treat
them differently.
Secondly, as I said in my cover letter there is no
behaviour change here for RELEASE builds. Behaviour
changes= unrelated to the bugfix will have to go to a
separate patch.= I agree that we may want to reconsider
the interface in the = future, but that=E2=80=99s for a separate
bugzilla and patch.= Not discussing it currently is
important to avoid diverting = from the primary problem.
Could create a bugzilla not to forg= et about it soon
after the stable tag.

Best wishes,
Vitaly

14 =D0=BC=D0=B0=D1=8F 2020 =D0=B3., =D0=B2 = 19:38, Kinney, Michael D
<michael.d.kinney@intel.com> = =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0):

Why preserve the ASSERT()s for = an a Unicode strings
that are not aligned in a 16-bit boundar= y?

This is essentially the same as an invalid = pointer
value
just like NULL.  If NULL pointer returns an error
code,
shouldn't and invalid pointer value?

Th= anks,

Mike

-----Original Message-----
Fro= m: devel@edk2.groups.io<= /a> <devel@edk2.group= s.io> On
Behalf Of Vitaly Cheptsov
Sent:= Thursday, May 14, 2020 2:26 AM
To: devel@edk2.groups.io
Cc: Andrew= Fish <afish@apple.com= >; Ard Biesheuvel
<ard.biesheuvel@linaro.org>; Bret Barkelew
<bret.= barkelew@microsoft.com>; Brian J . Johnson
<brian.johnson@hpe.com>= ; Chiu, Chasel
<chasel.chiu@intel.com>; Justen, Jordan L
<= ;jordan.l.justen@in= tel.com>; Laszlo Ersek
<lersek@redhat.com>; Leif Lindholm
<leif@nuviainc.com>;
Gao, Liming <liming.gao@intel.com>; Marvin= H=C3=A4user
<mhaeuser@outlook.de>; Kinney, Michael D
<michael.d.kinney@inte= l.com>; Zimmer, Vincent
<vincent.zimmer@intel.com>; Gao, Zhichao=
<zhic= hao.gao@intel.com>
Subject: [edk2-devel] [PATCH V6 1/1= ] MdePkg: Fix
SafeString performing assertions on runtime che= cks

REF:
https://bugzilla.tian= ocore.org/show_bug.cgi?id=3D2054





Runtime checks returned= via status return code
should
not work as


assertions= to permit parsing not trusted data with
SafeString


interfaces.





CC: Andrew F= ish <afish@apple.com&g= t;


CC: Ard Biesheuvel <ard.biesheuvel@linaro.or= g>


CC: Bret Barkelew <= ;bret.barkelew@mi= crosoft.com>


CC: Brian J= . Johnson <brian.joh= nson@hpe.com>


CC: Chasel= Chiu <chasel.chiu@i= ntel.com>


CC: Jordan Jus= ten <jordan.l.ju= sten@intel.com>


CC: Lasz= lo Ersek <lersek@redhat.= com>


CC: Leif Lindholm &= lt;leif@nuviainc.com>= ;


CC: Liming Gao <liming.gao@intel.com>


CC: Marvin H=C3=A4user <mhaeuser@outlook.de>


CC: Mike Kinney <michael.d.kinney@intel.com&g= t;


CC: Vincent Zimmer <vincent.zimmer@intel.com<= /a>>


CC: Zhichao Gao <
zhichao.gao@intel.com&= gt;


Signed-off-by: Vitaly Chept= sov
<vit9696@protonmail.com>


---


Md= ePkg/Include/Library/BaseLib.h    | 120 ++--------
--
--------

MdePkg/Library/BaseLib/SafeString.c |  80 -= ---------
--
-


2 files changed, 7 insertions(+), 193 = deletions(-)




diff --git a/MdePkg/Include/Library/BaseLib.hb/MdePkg/Include/Library/BaseLib.h


index ecadff8b23..62dc3151bc 100644


--- a/MdePkg/Include/Library/BaseLib.h
=

+++ b/MdePkg/Include/Library/BaseLib.h


@@ -189,7 +189,6 @@ StrnSizeS (





 If Destination is not aligned on a 16-bit
boundary,
then ASSERT().
<= br class=3D"">
 If Source is not aligned on a 16-bit bou= ndary,
then
ASSERT().<= br class=3D"">

-  If an error would be re= turned, then the function
will also ASSERT().
<= br class=3D"">



&= nbsp;If an error is returned, then the Destination is
unmodif= ied.





@@ -225,7 +224,6 @@ StrCpyS (





 If= Length > 0 and Destination is not aligned on a
16-bit bou= ndary, then ASSERT().


 If = Length > 0 and Source is not aligned on a 16-
bit
boundary, then ASSERT().


-  If an error would be returned, then the fu= nction
will also ASSERT().





 If an error is= returned, then the Destination is
unmodified.
=




= @@ -263,7 +261,6 @@ StrnCpyS (


=


 If Destination is not al= igned on a 16-bit
boundary,
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 th= e Destination is
unmodified.




@@ -303,7 +300,6 @= @ StrCatS (





 If Destination is not aligned on a 16-bit
boundary,
then ASSERT()= .


 If Source is not aligne= d 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.





@@ -350,12 +346,7 @@ StrnCatS (


 be ignored. Then, the function = stops at the first
character that is a not a

 valid decimal character or a Null-termina= tor,
whichever one comes first.

=



-  If Stri= ng is NULL, then ASSERT().


- &n= bsp;If Data is NULL, then ASSERT().


 If String is not aligned in a 16-bit boundary,
<= /blockquote>
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 stored

 at the location pointed to= by Data.


@@ -406,12 +397,7 @@ = StrDecimalToUintnS (


 be i= gnored. Then, the function stops at the first
character that = is a not a


 valid decimal = character or a Null-terminator,
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 PcdMaximumUnicode= StringLength is not zero, and
String contains more than


-  PcdMaximumUnicodeStringLengt= h Unicode characters,
not including the


-  Null-terminator, then ASSERT().





 If String has no valid decimal digits in the above
fo= rmat, then 0 is stored


 at= the location pointed to by Data.


@@ -467,12 +453,7 @@ StrDecimalToUint64S (

=
 the first character that is a not a valid
hexadecimal character or NULL,


 whichever one comes first.





-  If String is NU= LL, then ASSERT().


-  If D= ata is NULL, then ASSERT().


&nb= sp;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


- &nbs= p;Null-terminator, then ASSERT().





 If String has no vali= d hexadecimal digits in the
above format, then 0 is


 stored at the location pointed t= o by Data.


@@ -528,12 +509,7 @@= StrHexToUintnS (


 the fir= st character that is a not a valid
hexadecimal character or N= ULL,


 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 Pcd= MaximumUnicodeStringLength is not zero, and
String contains m= ore than


-  PcdMaximumUnic= odeStringLength 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.


@@ -622,8 +598,6 @@ AsciiStrnSizeS (




&n= bsp;This function is similar as strcpy_s defined in
C11.





-  If an error would be returned,= then the function
will also ASSERT().


-


 I= f an error is returned, then the Destination is
unmodified.



 @param  Destination      &= nbsp;       A pointer to a
Null-terminated Ascii string.


= @@ -656,8 +630,6 @@ AsciiStrCpyS (





 This function is = similar as strncpy_s defined in
C11.





-  = If an error would be returned, then the function
will also AS= SERT().


-


 If an error is returned, then the Destination = is
unmodified.




 @param  Destination &= nbsp;           &nbs= p;A pointer to a
Null-terminated Ascii string.
=

@@ -692,8 +664,6 @@ AsciiStrnCpyS (





 This function is similar as strcat_s defined in
=
C11.


<= br class=3D"">

-  If an error would be re= turned, then the function
will also ASSERT().
<= br class=3D"">
-


=  If an error is returned, then the Destination is
unmodi= fied.





 @param  Destination    &nbs= p;         A pointer to a
Null-terminated Ascii string.


@@ -730,8 +700,6 @@ AsciiStrCatS (




 This functi= on is similar as strncat_s defined in
C11.





- &n= bsp;If an error would be returned, then the function
will als= o ASSERT().


-

 If an error is returned, then the Destinat= ion is
unmodified.





 @param  Destinati= on             =  A pointer to a
Null-terminated Ascii string.


@@ -777,12 +745,6 @@ AsciiStrnCatS (

 be ignored. Then, the func= tion stops at the first
character that is a not a


 valid decimal character or a Null-te= rminator,
whichever one comes first.





-  = If String is NULL, then ASSERT().


-  If Data is NULL, then ASSERT().

-  If PcdMaximumAsciiStringLength is not zero, and
String contains more than


-  PcdMaximumAsciiStringLength Ascii characters, not
i= ncluding the


-  Null-termi= nator, then ASSERT().


-


 If String has no valid decimal d= igits in the above
format, then 0 is stored

 at the location pointed to by Data.


 If the number represented by St= ring exceeds the
range defined by UINTN, then
<= br class=3D"">
@@ -832,12 +794,6 @@ AsciiStrDecimalToUintnS (=


 be ignored. Then, the fu= nction stops at the first
character that is a not a


 valid decimal character or a Nul= l-terminator,
whichever one comes first.





- &nbs= p;If String is NULL, then ASSERT().


-  If Data is NULL, then ASSERT().


-  If PcdMaximumAsciiStringLength is not zero, and
String contains more than


-  PcdMaximumAsciiStringLength Ascii characters, not
including the


-  Nu= ll-terminator, then ASSERT().


-=


 If String has no valid d= ecimal digits in the above
format, then 0 is stored


 at the location pointed to by Da= ta.


 If the number represe= nted by String exceeds the
range defined by UINT64, then


@@ -891,12 +847,6 @@ AsciiStrDecima= lToUint64S (


 character th= at is a not a valid hexadecimal
character or Null-terminator,=


 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 than

-  PcdMaximumAsciiStringLength Ascii charac= ters, not
including the


-  Null-terminator, then ASSERT().


-


 If Stri= ng has no valid hexadecimal digits in the
above format, then = 0 is


 stored at the locati= on pointed to by Data.


 If= the number represented by String exceeds the
range defined b= y UINTN, then


@@ -950,12 +900,6= @@ AsciiStrHexToUintnS (


 = ;character that is a not a valid hexadecimal
character or Nul= l-terminator,


 whichever o= n comes first.



<= br class=3D"">
-  If String is NULL, then ASSERT().


-  If Data is NULL, then ASSER= T().


-  If PcdMaximumAscii= StringLength is not zero, and
String contains more than


-  PcdMaximumAsciiStringLength = Ascii characters, not
including the


-  Null-terminator, then ASSERT().


-


 If String has no valid hexadecimal digits in the
abov= e format, then 0 is


 store= d at the location pointed to by Data.


 If the number represented by String exceeds the
= range defined by UINT64, then


@= @ -1506,16 +1450,8 @@ StrHexToUint64 (


 "::" can be used to compress one or more groups of
X
when X contains only 0.


 The "::" can only appear onc= e in the String.





-  If String is NULL, then ASSERT().

-

-  If Address is NULL, then ASSERT().


-


&nbs= p;If String is not aligned in a 16-bit boundary,
then
ASSERT().





-  If PcdMaxim= umUnicodeStringLength is not zero, and
String contains more t= han


-  PcdMaximumUnicodeSt= ringLength 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.


@@ -1567,15 +150= 3,10 @@ StrToIpv6Address (


&nbs= p;When /P is in the String, the function stops at
the
first character that is not
<= br class=3D"">
 a valid decimal digit character after P = is
converted.




-  If String is NULL, then A= SSERT().


-


-  If Address is NULL, then ASSERT().


-


 If String is not aligned in a 16-bit boundary,
=
then
ASSERT().





 I= f PcdMaximumUnicodeStringLength is not zero, and
String conta= ins more than


 PcdMaximumU= nicodeStringLength Unicode characters,
not including the


-  Null-terminator, then ASSER= T().





 If EndPointer is not NULL and Address is
translated
from String, a p= ointer


 to the character t= hat stopped the scan is stored
at
the location pointed to


@@ -1640,8 +1571,6 @@ StrToIpv4Address (


         &nbs= p;       oo     &nbs= p;    Data4[48:55]


           &= nbsp;     pp       &= nbsp;  Data4[56:63]


<= br class=3D"">

-  If String is NULL, then= ASSERT().


-  If Guid is N= ULL, then ASSERT().


 If St= ring is not aligned in a 16-bit boundary,
then
ASSERT().





 @param  Stri= ng             =       Pointer to a
Null-
terminated Unicode string.
<= br class=3D"">
@@ -1676,17 +1605,6 @@ StrToGuid (





 If String is not aligned in a 16-bit boundary,
then
ASSERT().





-  If S= tring is NULL, then ASSERT().


-=


-  If Buffer is NULL, the= n ASSERT().


-

-  If Length is not multiple of 2, then ASS= ERT().


-


-  If PcdMaximumUnicodeStringLength is not zero = and
Length is greater than


-  PcdMaximumUnicodeStringLength, then ASSERT().


-


-  If MaxBufferSize is less than (Length / 2), then
ASSERT().


-

 @param  String    &nb= sp;            =   Pointer to a
Null-
terminated Unicode string.


 @param  Length        =            The numbe= r of
Unicode characters to decode.


 @param  Buffer      &= nbsp;           &nbs= p;Pointer to the
converted bytes array.


@@ -1777,7 +1695,6 @@ UnicodeStrToAsciiStr (


 the upper 8 bits, then ASSERT().=




=
 If Source is not aligned on a 16-bit boundary,
then
ASSERT().
=

-  If an error would be returned, then t= he function
will also ASSERT().

=



 If an err= or is returned, then the Destination is
unmodified.





@@ -1818,22 +1735,23 @@ UnicodeStrToAsciiStrS (


 bits of each Unicode character. The function<= br class=3D"">terminates the Ascii string


 Destination by appending a Null-terminator
<= /blockquote>
character
at the end.
<= br class=3D"">



-=  The caller is responsible to make sure
Destination
<= blockquote type=3D"cite" class=3D"">points to a buffer with size


-  equal or greater than ((StrLen= (Source) + 1) *
sizeof (CHAR8)) in bytes.


+  The caller is responsible to make sure
Destination
points to a = buffer with


+  size not sm= aller than ((MIN(StrLen(Source),
Le= ngth)
+ 1) * sizeof (CHAR8))

<= br class=3D"">+  in bytes.





 If any Unicode characte= rs in Source contain non-
zero
value in the upper 8


&= nbsp;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, t= hen the Destination is
unmodified.


+  If an error is returned, then Destination and
DestinationLength are


+  unmodified.





 @param  Source   =           The pointer to = a Null-
terminated Unicode string.


 @param  Length      &= nbsp;      The maximum number of
Unicode characters to


 &= nbsp;           &nbs= p;            &= nbsp; convert.


 @para= m  Destination        The pointer t= o a Null-
terminated Ascii string.


-  @param  DestMax     &nbs= p;      The maximum number of
D= estination Ascii


-   =             &nb= sp;            =  char, including
terminating null char.

+  @param  DestMax    =         The maximum number of
Destination Ascii char,


+             = ;            &n= bsp;   including terminating
null char.


 @param  DestinationLength =  The number of Unicode
characters converted.





 @retval RETURN_SUCCESS        &= nbsp;   String is
converted.

@@ -2388,10 +2306,6 @@ AsciiStrHexToUint64 (


 "::" 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 St= ring, a pointer


 to the ch= aracter that stopped the scan is stored
at
the location pointed to

=
 by EndPointer.


@@ -2443,10 +2357,6 @@ AsciiStrToIpv6Address (


 When /P is in the String, the function stops a= t
the
first character = that is not


 a valid decim= al digit character after P is
converted.





- &nbs= p;If String is NULL, then ASSERT().


-


-  If Address is = NULL, then ASSERT().


-


 If EndPointer is not NULL and Ad= dress is
translated
<= blockquote type=3D"cite" class=3D"">
fr= om String, a pointer


 to t= he character that stopped the scan is stored
at
the location pointed to


 by EndPointer.

@@ -2508,9 +2418,6 @@ AsciiStrToIpv4Address (

        =          oo    =       Data4[48:55]


         &nb= sp;       pp     &nb= sp;    Data4[56:63]





-  If String is = NULL, then ASSERT().


-  If= Guid is NULL, then ASSERT().


-=


 @param  String &nbs= p;            &= nbsp;    Pointer to a
Null-
terminated ASCII string.


 @param  Guid      = ;            &n= bsp;  Pointer to the
converted GUID.
=




= @@ -2541,17 +2448,6 @@ AsciiStrToGuid (


 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
Leng= th is greater than


-  PcdM= aximumAsciiStringLength, then ASSERT().


-


-  If MaxBuffer= Size is less than (Length / 2), then
ASSERT().
=

-


 @param  String         =           Pointer to a
Null-
terminated ASCII= string.


 @param  Len= gth             = ;      The number of
ASCII
characters to decode.


 @param  Buffer     = ;            &n= bsp; Pointer to the
converted bytes array.


@@ -2632,7 +2528,6 @@ AsciiStrToUnicodeStr (=


 equal or greater than ((= AsciiStrLen (Source) + 1)
*
sizeof (CHAR16)) 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 A= SSERT().





 If an error is returned, then the Destination = is
unmodified.




@@ -2678,7 +2573,6 @@ AsciiStrTo= UnicodeStrS (


 ((MIN(Ascii= StrLen(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 t= he function
will also ASSERT().

=



 If an err= or is returned, then Destination and
DestinationLength are

 unmodified.
<= br class=3D"">
diff --git a/MdePkg/Library/BaseLib/SafeString= .c
b/MdePkg/Library/BaseLib/SafeString.c


index 7dc03d2caa..1db42abb05 100644
<= br class=3D"">
--- a/MdePkg/Library/BaseLib/SafeString.c


+++ b/MdePkg/Library/BaseLib/SafeSt= ring.c


@@ -14,7 +14,6 @@





#define SAFE_STRING_CONSTRAINT_CHECK(Expression,
Stat= us)  \


 do { \


-    ASSERT (Expressio= n); \


   if (!(E= xpression)) { \


  &nb= sp;  return Status; \


   } \


@@ -197,= 7 +196,6 @@ StrnSizeS (





 If Destination is not aligned o= n a 16-bit
boundary,
=
t= hen ASSERT().


 If Source i= s not aligned on a 16-bit boundary,
then
ASSERT().


-  If an error would be returned, then the function
wil= l also ASSERT().





 If an error is returned, then the Dest= ination is
unmodified.





@@ -279,7 +277,6 @@ Str= CpyS (





 If Length > 0 and Destination is not aligned= on a
16-bit boundary, then ASSERT().


 If Length > 0 and Source is not aligned on a= 16-
bit
boundary, the= n ASSERT().


-  If an error= would be returned, then the function
will also ASSERT().





 If an error is returned, then the Destination is
unmodified.





@@ -372,7 +369,6 @@ StrnCpyS (





 If Destination is not aligned on a 16-bit
boundary,
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().





 I= f an error is returned, then the Destination is
unmodified.



@@ -473,7 +469,6 @@ StrCatS (




 If Destinati= on is not aligned on a 16-bit
bound= ary,
then ASSERT().


 If Source is not aligned on a 16-bit boundary,
then
ASSERT().


-  If an error would be returned, then the functionwill also ASSERT().





 If an error is returne= d, then the Destination is
unmodified.





@@ -590,= 12 +585,7 @@ StrnCatS (


 b= e ignored. Then, the function stops at the first
character th= at is a not a


 valid decim= al character or a Null-terminator,
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
<= blockquote type=3D"cite" class=3D"">
AS= SERT().


-  If PcdMaximumUn= icodeStringLength is not zero, and
String contains more than<= br class=3D"">

-  PcdMaximumUnicodeString= Length Unicode characters,
not including the

-  Null-terminator, then ASSERT().





 If String has no valid decimal digits in the above
format, then 0 is stored


&nb= sp;at the location pointed to by Data.


@@ -705,12 +695,7 @@ StrDecimalToUintnS (


 be ignored. Then, the function stops at the fir= st
character that is a not a

 valid decimal character or a Null-terminator,
whichever one comes first.


<= br class=3D"">

-  If String is NULL, then= ASSERT().


-  If Data is N= ULL, then ASSERT().


 If St= ring is not aligned in a 16-bit boundary,
then
ASSERT().


-  If PcdMaximumUnicodeStringLength is not zero, and
String contains more than


-  PcdMaximumUnicodeStringLength Unicode characters,
n= ot including the


-  Null-t= erminator, then ASSERT().





 If String has no valid decima= l digits in the above
format, then 0 is stored
=

 at the location pointed to by Data.


@@ -825,12 +810,7 @@ StrDecimalToU= int64S (


 the first charac= ter that is a not a valid
hexadecimal character or NULL,


 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 PcdMaximumUnicode= StringLength is not zero, and
String contains more than


-  PcdMaximumUnicodeStringLengt= h Unicode characters,
not including the


-  Null-terminator, then ASSERT().





 If String has no valid hexadecimal digits in the
abov= e format, then 0 is


 store= d at the location pointed to by Data.


@@ -956,12 +936,7 @@ StrHexToUintnS (

<= br class=3D""> the first character that is a not a valid
hexadecimal character or NULL,


 whichever one comes first.





-  If String is NULL, = then ASSERT().


-  If Data = is NULL, then ASSERT().


 I= f String is not aligned in a 16-bit boundary,
then
ASSERT().


-  If PcdMaximumUnicodeStringLength is not zero, and
String contains more than


-  PcdMaximumUnicodeStringLength Unicode characters,
n= ot including the


-  Null-t= erminator, then ASSERT().





 If String has no valid hexade= cimal digits in the
above format, then 0 is

 stored at the location pointed to by Data.=


@@ -1856,8 +1831,6 @@ AsciiStr= CpyS (





 This function is similar as strncpy_s defined i= n
C11.





-  If an error would be returned,= then the function
will also ASSERT().


-


 I= f an error is returned, then the Destination is
unmodified.



 @param  Destination      &= nbsp;       A pointer to a
Null-terminated Ascii string.


= @@ -1944,8 +1917,6 @@ AsciiStrnCpyS (





 This function is = similar as strcat_s defined in
C11.=




<= br class=3D"">-  If an error would be returned, then the function
will also ASSERT().


-=


 If an error is returned,= then the Destination is
unmodified.





 @p= aram  Destination         &nbs= p;    A pointer to a
Null-terminated Asci= i string.


@@ -2040,8 +2011,6 @@= AsciiStrCatS (



=

 This function is similar as strncat_s d= efined in
C11.




-  If an error would be ret= urned, then the function
will also ASSERT().

-


&= nbsp;If an error is returned, then the Destination is
unmodif= ied.





 @param  Destination    &nbs= p;         A pointer to a
Null-terminated Ascii string.


@@ -2154,12 +2123,6 @@ AsciiStrnCatS (


 be ignored. Then, the function stops at the firstcharacter that is a not a


 valid decimal character or a Null-terminator,
wh= ichever one comes first.





-  If String is NULL, then ASSE= RT().


-  If Data is NULL, = then ASSERT().


-  If PcdMa= ximumAsciiStringLength is not zero, and
String contains more = than


-  PcdMaximumAsciiStr= ingLength Ascii characters, not
including the
<= br class=3D"">
-  Null-terminator, then ASSERT().


-


 If String has no valid decimal 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


@@ -2266,12 +2229,6 @@ AsciiStrDecimalToUintnS (


 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 first.





-  If String is NULL, = then ASSERT().


-  If Data = is NULL, then ASSERT().


-  = ;If PcdMaximumAsciiStringLength is not zero, and
String conta= ins more than


-  PcdMaximu= mAsciiStringLength Ascii characters, not
including the


-  Null-terminator, then ASSERT(= ).


-


 If String has no valid decimal digits in the above<= br class=3D"">format, then 0 is stored


 at the location pointed to by Data.


 If the number represented by String exceeds the=
range defined by UINT64, then

<= br class=3D"">@@ -2382,12 +2339,6 @@ AsciiStrDecimalToUint64S (


 character that is a not a valid hexa= decimal
character or Null-terminator,


 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 than


-  PcdMaximumAsciiStringLength Ascii characters, not
including the


-  Nu= ll-terminator, then ASSERT().


-=


 If String has no valid h= exadecimal digits in the
above format, then 0 is


 stored at the location pointed to by = Data.


 If the number repre= sented by String exceeds the
range defined by UINTN, then


@@ -2509,12 +2460,6 @@ AsciiStrHex= ToUintnS (


 character that= is a not a valid hexadecimal
character or Null-terminator,

 whichever on comes first.<= br class=3D"">



<= br class=3D"">-  If String is NULL, then ASSERT().


-  If Data is NULL, then ASSERT().


-  If PcdMaximumAsciiStringLength= is not zero, and
String contains more than

-  PcdMaximumAsciiStringLength Ascii charac= ters, not
including the


-  Null-terminator, then ASSERT().


-


 If Stri= ng has no valid hexadecimal digits in the
above format, then = 0 is


 stored at the locati= on pointed to by Data.


 If= the number represented by String exceeds the
range defined b= y UINT64, then


@@ -2635,7 +2580= ,6 @@ AsciiStrHexToUint64S (


&n= bsp;the upper 8 bits, then ASSERT().





 If Source is not = aligned on a 16-bit boundary,
then<= br class=3D"">
ASSERT().


-  = If an error would be returned, then the function
will also AS= SERT().





 If an error is returned, then the Destination i= s
unmodified.




@@ -2735,7 +2679,6 @@ UnicodeStrT= oAsciiStrS (


 If any Unico= de characters in Source contain non-
zero
value in the upper 8

 bits, then ASSERT().


 If Source is not aligned on a 16-bit boundary,
=
then
ASSERT().


-  If an error would be returned, then the func= tion
will also ASSERT().





 If an error is r= eturned, then Destination and
DestinationLength are


 unmodified.


@@ -2948,7 +2891,6 @@ AsciiStrToUnicodeStrS (


 ((MIN(AsciiStrLen(Source), Len= gth) + 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, th= en Destination and
DestinationLength are


 unmodified.


@@ -3072,10 +3014,6 @@ AsciiStrnToUnicodeStrS (

 "::" can be used to compress one or more = groups of
X
when X con= tains only 0.


 The "::" ca= n 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
<= /blockquote>
translated
from String, a pointer


 to the character that stoppe= d the scan is stored
at
the location pointed to


 = ;by EndPointer.


@@ -3291,10 +32= 29,6 @@ AsciiStrToIpv6Address (


 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 NU= LL, then ASSERT().


-


-  If Address is NULL, then ASSER= T().


-


 If EndPointer is not NULL and Address is
translated
from String, a p= ointer


 to the character t= hat stopped the scan is stored
at
the location pointed to


 by EndPointer.


@@ = -3448,9 +3382,6 @@ AsciiStrToIpv4Address (

          &nb= sp;      oo      &nb= sp;   Data4[48:55]


            =      pp        =   Data4[56:63]





-  If String is NULL, then ASSE= RT().


-  If Guid is NULL, = then ASSERT().


-
=

 @param  String    &= nbsp;           &nbs= p;  Pointer to a
Null-
terminated ASCII string.


 @param  Guid        &n= bsp;            = ;Pointer to the
converted GUID.

=



@@ -3550,17 +34= 81,6 @@ AsciiStrToGuid (


 = decoding stops after Length of characters and
outputs Buffer = containing


 (Length / 2) b= ytes.





-  If String is NULL, then ASSERT().


-


-  If Buffer is NULL, then ASSERT().


-


-  If = Length is not multiple of 2, then ASSERT().

-


-  If PcdMa= ximumAsciiStringLength is not zero and
Length is greater than=


-  PcdMaximumAsciiStringL= ength, then ASSERT().


-


-  If MaxBufferSize is less than = (Length / 2), then
ASSERT().

-


 @param &nbs= p;String            =        Pointer to a
Null-
terminated ASCII string.


 @param  Length   &nbs= p;            &= nbsp;  The number of
ASCI= I
characters to decode.


 @param  Buffer        =            Pointer t= o the
converted bytes array.

--


2.24.2 (Apple Gi= t-127)











--Apple-Mail=_83B0548A-316B-4724-9912-726F3D3B9DBA-- --Apple-Mail=_29A8425E-B314-49E0-99DA-97E8A9D2BBC1 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEsLABAI5Y5VbvBdmpL8K2O86Eyz4FAl69lQwACgkQL8K2O86E yz7SgBAAlqxsmB43L+t54vjffuUpeVYU+xeWRcelGU6y86dUSNDclAPmzRtA8UnJ HWGU7yr9qn/PPA5c6nmcXpXTBPCC03QMRGYoyuGzMW4MxrwAYp11+IYSUeEcpcOr SpoiWFCuMqW7N9BTtWBrWydF78t6B8enEIG5HU1PgbP5BusXQKDZvB+ARJE9NN7q DoJ8321ZDWx/sjy8Wjp/DlS0VxYmpvTKJ7BdKSGZzKW8CcCgU4jo+eyV6hQziGEc g1svOq3Mj5pJdt2wzu35jSG4sQpYg8MMbb4NrDhH83OVBMeY1Sb1irS0Adgm+sbC 7zkLftfHruamjWRXkaA1Ki1tptLpQkjGDR387j7gG55c/0yR2rCXpGzp0ih3ypvR jVD0WY7GTeckUvHSj6NwTWPhOVqGx1J8gmcnCSFy/ai/xyuwbABllnpFZ88meoIP CtW/KOXuswoH/ZGSPoeghVHKq8B4k72VdjT3uUBayoownYR49YVuNwS/GUC4PfLU N3SfHVy2UeFMHEuP0VQezTV68NLzvl7YK+HZN6ZKoG8e68dolvq9LBK7UQPd0xqB q1hSUY8dr0M7uTZxE+WfC40zg8srA0nfnbgR6pjSdp7+aQvl93W/1+m0/h8rvHfd wbNIXpHgiCotjw0UzzBNUcxArI404FSUN5FB6PKIR3jxgdK05nk= =1mLw -----END PGP SIGNATURE----- --Apple-Mail=_29A8425E-B314-49E0-99DA-97E8A9D2BBC1--