From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-out1.informatik.tu-muenchen.de (mail-out1.in.tum.de [131.159.0.8]) by sourceware.org (Postfix) with ESMTPS id E8F4B384B406; Wed, 3 Mar 2021 19:26:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E8F4B384B406 Received: by mail.in.tum.de (Postfix, from userid 107) id 628501C1544; Wed, 3 Mar 2021 20:26:09 +0100 (CET) Received: (Authenticated sender: sichert) by mail.in.tum.de (Postfix) with ESMTPSA id B4C861C153B; Wed, 3 Mar 2021 20:26:06 +0100 (CET) (Extended-Queue-bit tech_awrrs@fff.in.tum.de) Subject: Re: [PATCH] libstdc++: Avoid accidental ADL when calling make_reverse_iterator To: Patrick Palka Cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org References: <0cb77c84-100b-1f4a-1570-873ef0c94f5e@in.tum.de> <51b7e2fc-63d6-1271-4214-37a4266ecf5@idea> From: Moritz Sichert Message-ID: <38f0dca9-d993-f124-e304-6e37cf8dcd91@in.tum.de> Date: Wed, 3 Mar 2021 20:26:05 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <51b7e2fc-63d6-1271-4214-37a4266ecf5@idea> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms090208060805030604060907" X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, NICE_REPLY_A, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Mar 2021 19:26:13 -0000 This is a cryptographically signed message in MIME format. --------------ms090208060805030604060907 Content-Type: multipart/mixed; boundary="------------34A763FAFBB72573F4F78021" Content-Language: de-DE This is a multi-part message in MIME format. --------------34A763FAFBB72573F4F78021 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Thanks for the review. I attached the updated patch. Can you commit this for me or point me to what I should do next? This is = my first contribution here. Best, Moritz Am 03.03.21 um 19:02 schrieb Patrick Palka: > On Wed, 3 Mar 2021, Moritz Sichert via Libstdc++ wrote: >=20 >> std::ranges::reverse_view uses make_reverse_iterator in its >> implementation as described in [range.reverse.view]. This accidentally= >> allows ADL as an unqualified name is used in the call. According to >> [contents], however, this should be treated as a qualified lookup into= >> the std namespace. >> >> This leads to errors due to ambiguous name lookups when another >> make_reverse_iterator function is found via ADL. >> >> I found this as llvm has its own implementation of ranges which also h= as >> llvm::make_reverse_iterator. This lead to a compile error with >> std::vector | std::ranges::views::reverse. >=20 > Thanks for the patch! It looks good to me. Some very minor comments > below. >=20 >> >> Best, >> Moritz >> >=20 >> libstdc++-v3/Changelog: >> >> * include/std/ranges: Avoid accidental ADL when calling >> make_reverse_iterator. >> * testsuite/std/ranges/adaptors/reverse_no_adl.cc: New test. >> Test that views::reverse works when make_reverse_iterator is >> defined in a namespace that could be found via ADL. >> --- >> libstdc++-v3/include/std/ranges | 12 +++--- >> .../std/ranges/adaptors/reverse_no_adl.cc | 39 +++++++++++++++++= ++ >> 2 files changed, 45 insertions(+), 6 deletions(-) >> create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/revers= e_no_adl.cc >> >> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/st= d/ranges >> index 1be74beb860..adbc6d7b274 100644 >> --- a/libstdc++-v3/include/std/ranges >> +++ b/libstdc++-v3/include/std/ranges >> @@ -2958,29 +2958,29 @@ namespace views >> { >> if constexpr (_S_needs_cached_begin) >> if (_M_cached_begin._M_has_value()) >> - return make_reverse_iterator(_M_cached_begin._M_get(_M_base)); >> + return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base= )); >> =20 >> auto __it =3D ranges::next(ranges::begin(_M_base), ranges::end(_M_b= ase)); >> if constexpr (_S_needs_cached_begin) >> _M_cached_begin._M_set(_M_base, __it); >> - return make_reverse_iterator(std::move(__it)); >> + return std::make_reverse_iterator(std::move(__it)); >> } >> =20 >> constexpr auto >> begin() requires common_range<_Vp> >> - { return make_reverse_iterator(ranges::end(_M_base)); } >> + { return std::make_reverse_iterator(ranges::end(_M_base)); } >> =20 >> constexpr auto >> begin() const requires common_range >> - { return make_reverse_iterator(ranges::end(_M_base)); } >> + { return std::make_reverse_iterator(ranges::end(_M_base)); } >> =20 >> constexpr reverse_iterator> >> end() >> - { return make_reverse_iterator(ranges::begin(_M_base)); } >> + { return std::make_reverse_iterator(ranges::begin(_M_base)); } >> =20 >> constexpr auto >> end() const requires common_range >> - { return make_reverse_iterator(ranges::begin(_M_base)); } >> + { return std::make_reverse_iterator(ranges::begin(_M_base)); } >> =20 >> constexpr auto >> size() requires sized_range<_Vp> >> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl= =2Ecc b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl.cc >> new file mode 100644 >> index 00000000000..9aa96c7d40e >> --- /dev/null >> +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl.cc >> @@ -0,0 +1,39 @@ >> +// Copyright (C) 2020-2021 Free Software Foundation, Inc. >> +// >> +// This file is part of the GNU ISO C++ Library. This library is fre= e >> +// software; you can redistribute it and/or modify it under the >> +// terms of the GNU General Public License as published by the >> +// Free Software Foundation; either version 3, or (at your option) >> +// any later version. >> + >> +// This library is distributed in the hope that it will be useful, >> +// but WITHOUT ANY WARRANTY; without even the implied warranty of >> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +// GNU General Public License for more details. >> + >> +// You should have received a copy of the GNU General Public License = along >> +// with this library; see the file COPYING3. If not see >> +// . >> + >> +// { dg-options "-std=3Dgnu++2a" } >> +// { dg-do run { target c++2a } } >=20 > Since this isn't an execution test, we should use "compile" instead of > "run" here. >=20 >> >> + >> +#include >> + >> +// This test tests that views::reverse works and does not use ADL whi= ch could >> +// lead to accidentally finding test_ns::make_reverse_iterator(const = A&). >> + >> +namespace test_ns >> +{ >> + struct A {}; >> + template >> + void make_reverse_iterator(T&&) {} >> +} // namespace test_ns >> + >> +void test() >> +{ >> + test_ns::A as[] =3D {{}, {}}; >> + auto v =3D as | std::views::reverse; >> + static_assert(std::ranges::view); >=20 > I suppose we could also check >=20 > static_assert(std::ranges::range) >=20 > which'll additionally verify the std:: qualification inside the const > begin()/end() overloads. >=20 >> +} >> + >> --=20 >> 2.30.1 >> >=20 --------------34A763FAFBB72573F4F78021 Content-Type: text/x-patch; charset=UTF-8; name="libstdc-Avoid-accidental-ADL-when-calling-make_rever.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename*0="libstdc-Avoid-accidental-ADL-when-calling-make_rever.patch" =46rom 9f9858c24519bcea903de477a37b31eed09725c1 Mon Sep 17 00:00:00 2001 From: Moritz Sichert Date: Wed, 3 Mar 2021 18:14:28 +0100 Subject: [PATCH] libstdc++: Avoid accidental ADL when calling make_reverse_iterator std::ranges::reverse_view uses make_reverse_iterator in its implementation as described in [range.reverse.view]. This accidentally allows ADL as an unqualified name is used in the call. According to [contents], however, this should be treated as a qualified lookup into the std namespace. This leads to errors due to ambiguous name lookups when another make_reverse_iterator function is found via ADL. libstdc++-v3/Changelog: * include/std/ranges: Avoid accidental ADL when calling make_reverse_iterator. * testsuite/std/ranges/adaptors/reverse_no_adl.cc: New test. Test that views::reverse works when make_reverse_iterator is defined in a namespace that could be found via ADL. --- libstdc++-v3/include/std/ranges | 12 +++--- .../std/ranges/adaptors/reverse_no_adl.cc | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no= _adl.cc diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/r= anges index 1be74beb860..adbc6d7b274 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -2958,29 +2958,29 @@ namespace views { if constexpr (_S_needs_cached_begin) if (_M_cached_begin._M_has_value()) - return make_reverse_iterator(_M_cached_begin._M_get(_M_base)); + return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));= =20 auto __it =3D ranges::next(ranges::begin(_M_base), ranges::end(_M_base)= ); if constexpr (_S_needs_cached_begin) _M_cached_begin._M_set(_M_base, __it); - return make_reverse_iterator(std::move(__it)); + return std::make_reverse_iterator(std::move(__it)); } =20 constexpr auto begin() requires common_range<_Vp> - { return make_reverse_iterator(ranges::end(_M_base)); } + { return std::make_reverse_iterator(ranges::end(_M_base)); } =20 constexpr auto begin() const requires common_range - { return make_reverse_iterator(ranges::end(_M_base)); } + { return std::make_reverse_iterator(ranges::end(_M_base)); } =20 constexpr reverse_iterator> end() - { return make_reverse_iterator(ranges::begin(_M_base)); } + { return std::make_reverse_iterator(ranges::begin(_M_base)); } =20 constexpr auto end() const requires common_range - { return make_reverse_iterator(ranges::begin(_M_base)); } + { return std::make_reverse_iterator(ranges::begin(_M_base)); } =20 constexpr auto size() requires sized_range<_Vp> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl.cc= b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl.cc new file mode 100644 index 00000000000..7d01f5d42a2 --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse_no_adl.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2020-2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License alo= ng +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=3Dgnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +// This test tests that views::reverse works and does not use ADL which = could +// lead to accidentally finding test_ns::make_reverse_iterator(const A&)= =2E + +namespace test_ns +{ + struct A {}; + template + void make_reverse_iterator(T&&) {} +} // namespace test_ns + +void test() +{ + test_ns::A as[] =3D {{}, {}}; + auto v =3D as | std::views::reverse; + static_assert(std::ranges::view); + static_assert(std::ranges::view); +} + --=20 2.30.1 --------------34A763FAFBB72573F4F78021-- --------------ms090208060805030604060907 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCC EakwggUSMIID+qADAgECAgkA4wvV+K8l2YEwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYT AkRFMSswKQYDVQQKDCJULVN5c3RlbXMgRW50ZXJwcmlzZSBTZXJ2aWNlcyBHbWJIMR8wHQYD VQQLDBZULVN5c3RlbXMgVHJ1c3QgQ2VudGVyMSUwIwYDVQQDDBxULVRlbGVTZWMgR2xvYmFs Um9vdCBDbGFzcyAyMB4XDTE2MDIyMjEzMzgyMloXDTMxMDIyMjIzNTk1OVowgZUxCzAJBgNV BAYTAkRFMUUwQwYDVQQKEzxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMgRGV1dHNjaGVu IEZvcnNjaHVuZ3NuZXR6ZXMgZS4gVi4xEDAOBgNVBAsTB0RGTi1QS0kxLTArBgNVBAMTJERG Ti1WZXJlaW4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAMtg1/9moUHN0vqHl4pzq5lN6mc5WqFggEcVToyVsuXPztNXS43O+FZs FVV2B+pG/cgDRWM+cNSrVICxI5y+NyipCf8FXRgPxJiZN7Mg9mZ4F4fCnQ7MSjLnFp2uDo0p eQcAIFTcFV9Kltd4tjTTwXS1nem/wHdN6r1ZB+BaL2w8pQDcNb1lDY9/Mm3yWmpLYgHurDg0 WUU2SQXaeMpqbVvAgWsRzNI8qIv4cRrKO+KA3Ra0Z3qLNupOkSk9s1FcragMvp0049ENF4N1 xDkesJQLEvHVaY4l9Lg9K7/AjsMeO6W/VRCrKq4Xl14zzsjz9AkH4wKGMUZrAcUQDBHHWekC AwEAAaOCAXQwggFwMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUk+PYMiba1fFKpZFK4OpL 4qIMz+EwHwYDVR0jBBgwFoAUv1kgNgB5oKAia4zV8mHSuCzLgkowEgYDVR0TAQH/BAgwBgEB /wIBAjAzBgNVHSAELDAqMA8GDSsGAQQBga0hgiwBAQQwDQYLKwYBBAGBrSGCLB4wCAYGZ4EM AQICMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9wa2kwMzM2LnRlbGVzZWMuZGUvcmwvVGVs ZVNlY19HbG9iYWxSb290X0NsYXNzXzIuY3JsMIGGBggrBgEFBQcBAQR6MHgwLAYIKwYBBQUH MAGGIGh0dHA6Ly9vY3NwMDMzNi50ZWxlc2VjLmRlL29jc3ByMEgGCCsGAQUFBzAChjxodHRw Oi8vcGtpMDMzNi50ZWxlc2VjLmRlL2NydC9UZWxlU2VjX0dsb2JhbFJvb3RfQ2xhc3NfMi5j ZXIwDQYJKoZIhvcNAQELBQADggEBAIcL/z4Cm2XIVi3WO5qYi3FP2ropqiH5Ri71sqQPrhE4 eTizDnS6dl2e6BiClmLbTDPo3flq3zK9LExHYFV/53RrtCyD2HlrtrdNUAtmB7Xts5et6u5/ MOaZ/SLick0+hFvu+c+Z6n/XUjkurJgARH5pO7917tALOxrN5fcPImxHhPalR6D90Bo0fa3S PXez7vTXTf/D6OWST1k+kEcQSrCFWMBvf/iu7QhCnh7U3xQuTY+8npTD5+32GPg8SecmqKc2 2CzeIs2LgtjZeOJVEqM7h0S2EQvVDFKvaYwPBt/QolOLV5h7z/0HJPT8vcP9SpIClxvyt7bP ZYoaorVyGTkwggWsMIIElKADAgECAgcbY7rQHiw9MA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD VQQGEwJERTFFMEMGA1UEChM8VmVyZWluIHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRzY2hl biBGb3JzY2h1bmdzbmV0emVzIGUuIFYuMRAwDgYDVQQLEwdERk4tUEtJMS0wKwYDVQQDEyRE Rk4tVmVyZWluIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDIwHhcNMTYwNTI0MTEzODQwWhcN MzEwMjIyMjM1OTU5WjCBjTELMAkGA1UEBhMCREUxRTBDBgNVBAoMPFZlcmVpbiB6dXIgRm9l cmRlcnVuZyBlaW5lcyBEZXV0c2NoZW4gRm9yc2NodW5nc25ldHplcyBlLiBWLjEQMA4GA1UE CwwHREZOLVBLSTElMCMGA1UEAwwcREZOLVZlcmVpbiBHbG9iYWwgSXNzdWluZyBDQTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ07eRxH3h+Gy8Zp1xCeOdfZojDbchwFfylf S2jxrRnWTOFrG7ELf6Gr4HuLi9gtzm6IOhDuV+UefwRRNuu6cG1joL6WLkDh0YNMZj0cZGnl m6Stcq5oOVGHecwX064vXWNxSzl660Knl5BpBb+Q/6RAcL0D57+eGIgfn5mITQ5HjUhfZZkQ 0tkqSe3BuS0dnxLLFdM/fx5ULzquk1enfnjK1UriGuXtQX1TX8izKvWKMKztFwUkP7agCwf9 TRqaA1KgNpzeJIdl5Of6x5ZzJBTN0OgbaJ4YWa52fvfRCng8h0uwN89Tyjo4EPPLR22MZD08 WkVKusqAfLjz56dMTM0CAwEAAaOCAgUwggIBMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0P AQH/BAQDAgEGMCkGA1UdIAQiMCAwDQYLKwYBBAGBrSGCLB4wDwYNKwYBBAGBrSGCLAEBBDAd BgNVHQ4EFgQUazqYi/nyU4na4K2yMh4JH+iqO3QwHwYDVR0jBBgwFoAUk+PYMiba1fFKpZFK 4OpL4qIMz+EwgY8GA1UdHwSBhzCBhDBAoD6gPIY6aHR0cDovL2NkcDEucGNhLmRmbi5kZS9n bG9iYWwtcm9vdC1nMi1jYS9wdWIvY3JsL2NhY3JsLmNybDBAoD6gPIY6aHR0cDovL2NkcDIu cGNhLmRmbi5kZS9nbG9iYWwtcm9vdC1nMi1jYS9wdWIvY3JsL2NhY3JsLmNybDCB3QYIKwYB BQUHAQEEgdAwgc0wMwYIKwYBBQUHMAGGJ2h0dHA6Ly9vY3NwLnBjYS5kZm4uZGUvT0NTUC1T ZXJ2ZXIvT0NTUDBKBggrBgEFBQcwAoY+aHR0cDovL2NkcDEucGNhLmRmbi5kZS9nbG9iYWwt cm9vdC1nMi1jYS9wdWIvY2FjZXJ0L2NhY2VydC5jcnQwSgYIKwYBBQUHMAKGPmh0dHA6Ly9j ZHAyLnBjYS5kZm4uZGUvZ2xvYmFsLXJvb3QtZzItY2EvcHViL2NhY2VydC9jYWNlcnQuY3J0 MA0GCSqGSIb3DQEBCwUAA4IBAQCBeEWkTqR/DlXwCbFqPnjMaDWpHPOVnj/z+N9rOHeJLI21 rT7H8pTNoAauusyosa0zCLYkhmI2THhuUPDVbmCNT1IxQ5dGdfBi5G5mUcFCMWdQ5UnnOR7L n8qGSN4IFP8VSytmm6A4nwDO/afr0X9XLchMX9wQEZc+lgQCXISoKTlslPwQkgZ7nu7YRrQb tQMMONncsKk/cQYLsgMHM8KNSGMlJTx6e1du94oFOO+4oK4v9NsH1VuEGMGpuEvObJAaguS5 Pfp38dIfMwK/U+d2+dwmJUFvL6Yb+qQTkPp8ftkLYF3sv8pBoGH7EUkp2KgtdRXYShjqFu9V NCIaE40GMIIG3zCCBcegAwIBAgIMIyJmIHxFfEnDMyKXMA0GCSqGSIb3DQEBCwUAMIGNMQsw CQYDVQQGEwJERTFFMEMGA1UECgw8VmVyZWluIHp1ciBGb2VyZGVydW5nIGVpbmVzIERldXRz Y2hlbiBGb3JzY2h1bmdzbmV0emVzIGUuIFYuMRAwDgYDVQQLDAdERk4tUEtJMSUwIwYDVQQD DBxERk4tVmVyZWluIEdsb2JhbCBJc3N1aW5nIENBMB4XDTIwMDcwNjA5MDIxMFoXDTIxMDgz MDExMDE1OFowgdAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11 ZW5jaGVuMSkwJwYDVQQKDCBUZWNobmlzY2hlIFVuaXZlcnNpdGFldCBNdWVuY2hlbjEiMCAG A1UECwwZRmFrdWx0YWV0IGZ1ZXIgSW5mb3JtYXRpazEeMBwGA1UEAwwVTW9yaXR6LUZlbGlw ZSBTaWNoZXJ0MS4wLAYJKoZIhvcNAQkBFh9tb3JpdHotZmVsaXBlLnNpY2hlcnRAaW4udHVt LmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZujI3OvKYG9WFur8mtHb6VS szPw0xOFsQpAyEqB8n7x2wjJ/CqqK/JKlhOdJkV28UfMSNlEdMK9DxwLFZbeAy+0l2c90Uuj +wMYcpNAL3nOvE4cb2/2h6HJMPAorNq+oowPfCBEKTJu5VqVKzDKBDZkWNnMvQeAWutt4l2K W888hp9ji34K4La2Sa0bErIhItL35w7SFsljsgYt20B5qEqSPrH9TE7rw7uz+RUi3M/SZr+F bFe5iCCxDps7Gu+R2sz6cv3K6R/Po/gcuJ3Z0S6sA9lGwQQ4zN2V5BM0O4NbhAjcMabWmZNv /9zaN3sEkOXL+Zmyph2OizdF3THp2wIDAQABo4IC+DCCAvQwPgYDVR0gBDcwNTAPBg0rBgEE AYGtIYIsAQEEMBAGDisGAQQBga0hgiwBAQQHMBAGDisGAQQBga0hgiwCAQQHMAkGA1UdEwQC MAAwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAdBgNV HQ4EFgQUw0rcf9J0+miXebQGptkuzJERCbgwHwYDVR0jBBgwFoAUazqYi/nyU4na4K2yMh4J H+iqO3QwgckGA1UdEQSBwTCBvoERc2ljaGVydEBpbi50dW0uZGWBH21vcml0ei1mZWxpcGUu c2ljaGVydEBpbi50dW0uZGWBIXNpY2hlcnRAaW5mb3JtYXRpay50dS1tdWVuY2hlbi5kZYEv bW9yaXR6LWZlbGlwZS5zaWNoZXJ0QGluZm9ybWF0aWsudHUtbXVlbmNoZW4uZGWBEnNpY2hl cnRAY3MudHVtLmVkdYEgbW9yaXR6LWZlbGlwZS5zaWNoZXJ0QGNzLnR1bS5lZHUwgY0GA1Ud HwSBhTCBgjA/oD2gO4Y5aHR0cDovL2NkcDEucGNhLmRmbi5kZS9kZm4tY2EtZ2xvYmFsLWcy L3B1Yi9jcmwvY2FjcmwuY3JsMD+gPaA7hjlodHRwOi8vY2RwMi5wY2EuZGZuLmRlL2Rmbi1j YS1nbG9iYWwtZzIvcHViL2NybC9jYWNybC5jcmwwgdsGCCsGAQUFBwEBBIHOMIHLMDMGCCsG AQUFBzABhidodHRwOi8vb2NzcC5wY2EuZGZuLmRlL09DU1AtU2VydmVyL09DU1AwSQYIKwYB BQUHMAKGPWh0dHA6Ly9jZHAxLnBjYS5kZm4uZGUvZGZuLWNhLWdsb2JhbC1nMi9wdWIvY2Fj ZXJ0L2NhY2VydC5jcnQwSQYIKwYBBQUHMAKGPWh0dHA6Ly9jZHAyLnBjYS5kZm4uZGUvZGZu LWNhLWdsb2JhbC1nMi9wdWIvY2FjZXJ0L2NhY2VydC5jcnQwDQYJKoZIhvcNAQELBQADggEB AAWfFM8Xt8AJzmzr9VhhZMjtLxJgK42mnXfXuKpW36pMcwI0/yy2tSGMSr3/O7fFr32K+UmF Ti2L8qhJvc1UxUCuZf8ryL4M3kCy80JKlCAMHBvj85PdA65XFT+PI5t9mKCYp1CLZ0PLZvth DYlhvTNo7/0mUehEwE7MheXdTCbZfvyG2TVxH/toizY8k1wPllmkdS6jsVfXcUvoTeHTi6UZ qh/6o0aKav/7cRwRlNNVwv224H67rBQluGWDomGxyrCQBYXj1vdJKqKEXiPAbtT3F7LS7vc1 2WAUR/M4C+L4UpesrvG30qOMbzQKvuVz+RGPMRATHhkghORm6h+QJYoxggQLMIIEBwIBATCB njCBjTELMAkGA1UEBhMCREUxRTBDBgNVBAoMPFZlcmVpbiB6dXIgRm9lcmRlcnVuZyBlaW5l cyBEZXV0c2NoZW4gRm9yc2NodW5nc25ldHplcyBlLiBWLjEQMA4GA1UECwwHREZOLVBLSTEl MCMGA1UEAwwcREZOLVZlcmVpbiBHbG9iYWwgSXNzdWluZyBDQQIMIyJmIHxFfEnDMyKXMA0G CWCGSAFlAwQCAQUAoIICPTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ BTEPFw0yMTAzMDMxOTI2MDVaMC8GCSqGSIb3DQEJBDEiBCB950ENL/M9YqMZLo8mtLdJUOht VxwDMh0NtCmDjWVcozBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjALBglghkgBZQME AQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIH MA0GCCqGSIb3DQMCAgEoMIGvBgkrBgEEAYI3EAQxgaEwgZ4wgY0xCzAJBgNVBAYTAkRFMUUw QwYDVQQKDDxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMgRGV1dHNjaGVuIEZvcnNjaHVu Z3NuZXR6ZXMgZS4gVi4xEDAOBgNVBAsMB0RGTi1QS0kxJTAjBgNVBAMMHERGTi1WZXJlaW4g R2xvYmFsIElzc3VpbmcgQ0ECDCMiZiB8RXxJwzMilzCBsQYLKoZIhvcNAQkQAgsxgaGggZ4w gY0xCzAJBgNVBAYTAkRFMUUwQwYDVQQKDDxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMg RGV1dHNjaGVuIEZvcnNjaHVuZ3NuZXR6ZXMgZS4gVi4xEDAOBgNVBAsMB0RGTi1QS0kxJTAj BgNVBAMMHERGTi1WZXJlaW4gR2xvYmFsIElzc3VpbmcgQ0ECDCMiZiB8RXxJwzMilzANBgkq hkiG9w0BAQEFAASCAQB8EJ0WDyWitGDKy0o/B+2vOx23Hcs0Zisqu6RzHJjTPhgj7Kb3qjLl POA3yjQLXlhe1Gr+3njNWoJB+GZT9o+d/kHALL5gcnt33hfstBkc1r/HyoKse1cSofZ2fX+i XPpNChDB74k07NXQIiNIXHzK/BcTs1rNANQ1yrXQWmwG5Eg6fVnCuIrDonadnsxXA/C0eHwW CU9RaMa07xQfkj/HjUuG39VhCLdPJPF/dmZHvUWqRgDHxyIQ6lMffLibrAihq8vVMvLKnuqr wCWrD0RKPDSm5Kc3xrOYDtOKDHhNlBB4CTtEcf6d+C8AOD5+N7Rtcm08Oo9ud6O7VJkVCqLX AAAAAAAA --------------ms090208060805030604060907--