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.117.1589477947502767876 for ; Thu, 14 May 2020 10:39:08 -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 122EECD461; Thu, 14 May 2020 20:39:04 +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 20:39:04 +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: 59580 Content-Type: multipart/signed; boundary="Apple-Mail=_AAFD838C-62F8-4C86-982A-20886865972B"; protocol="application/pgp-signature"; micalg=pgp-sha512 --Apple-Mail=_AAFD838C-62F8-4C86-982A-20886865972B Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Mike, Firstly, NULL check and odd-address checks are essentially different thing= s: =E2=80=94 NULL address is basically =C2=ABno object=C2=BB, =C2=ABoptional = argument=C2=BB (e.g. failed allocation). =E2=80=94 Odd address is memory corruption, as there is no way to craft su= ch address anyhow else. For this reason the implementation is allowed to treat them differently. Secondly, as I said in my cover letter there is no behaviour change here f= or RELEASE builds. Behaviour changes unrelated to the bugfix will have to g= o 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 d= iscussing it currently is important to avoid diverting from the primary pro= blem. Could create a bugzilla not to forget 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 =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 --Apple-Mail=_AAFD838C-62F8-4C86-982A-20886865972B 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----- iQIzBAEBCgAdFiEEsLABAI5Y5VbvBdmpL8K2O86Eyz4FAl69gjgACgkQL8K2O86E yz4G7g//dB2+IIrNLzpZvNtZKKNxvTeUWyeX/KuFjoHfCOVahANTqwkEbsuYi4dU a4tugDfeljVVK8bsIdycvy2YbFcpq6zKn629qPM3oMwON3WyWTWhW1UybU6AJOUM /ynJC71m8AhG/NZ9K2SeAG1GqXtYxwYinYs/OXTbgnl9NkcKZjVTe494mdwegGuI 3ctl7Jswivm0Z64QhC9NStQRzk55X7XlNwDjDNTWjcdTpatx5wfmiLh/h4zVlofb czCzPWqRw966uu/7PDtgFIats4JLlXU6IdSfhpXfwY82kYovpQoKBkSQ1fPkjMmR MaciyDFq8G1GDRaGfJNydIFO3WSwwXnhzSlxKVgIifA3iDiSIqa/wp54LHWxGBiQ golRCoL4lAHHEHUn3mA4nPshpUtbNxfDQm9/RE7CkxM034ZTA4zPhIjmHg9iBVSR s0hIpflBjY3j8YRxtN2Ut3FwmMfhmM39jFLYKwuY2ETfsjlU3RVO6PD04fg60ZrW Qchcd5pLOBEfDso6hq0kw9+N+agwPP9TCTWV5ayflrPqz/YqzuLBGBGfkvC6C6Z3 H62KXW4epDDArfUIsTXnPFXTzArVZTTnLAqxdnROItaCB5mWcM/6xUJ1uS9noeL/ y/pHzBY5ddnfCbZjtRkEfzM8UBB6g4BcDhYh3O8jvxchNRJHEN4= =a/Ht -----END PGP SIGNATURE----- --Apple-Mail=_AAFD838C-62F8-4C86-982A-20886865972B--