From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from bumble.maple.relay.mailchannels.net (bumble.maple.relay.mailchannels.net [23.83.214.25]) by sourceware.org (Postfix) with ESMTPS id 093D1384F011 for ; Tue, 17 Aug 2021 02:58:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 093D1384F011 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gotplt.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gotplt.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id AD2DA6815C6 for ; Tue, 17 Aug 2021 02:58:37 +0000 (UTC) Received: from pdx1-sub0-mail-a84.g.dreamhost.com (100-96-133-152.trex-nlb.outbound.svc.cluster.local [100.96.133.152]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 6B66E6810B6 for ; Tue, 17 Aug 2021 02:58:36 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a84.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.133.152 (trex/6.3.3); Tue, 17 Aug 2021 02:58:37 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Whimsical-Robust: 26f9871f67fbad30_1629169117548_3548618046 X-MC-Loop-Signature: 1629169117548:1205340443 X-MC-Ingress-Time: 1629169117548 Received: from pdx1-sub0-mail-a84.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a84.g.dreamhost.com (Postfix) with ESMTP id 0486D89A94 for ; Mon, 16 Aug 2021 19:58:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gotplt.org; h=subject:to :references:from:message-id:date:mime-version:in-reply-to :content-type:content-transfer-encoding; s=gotplt.org; bh=TSLpNz KmuiL8iBbBQg0rbxm2mkA=; b=ir2ekzA0gM4Lf+L3vXvnrabGBJ189UYkiEMN65 OGjbFex3mi+jjly8luVDZYPbsjtTsIdbKPBFvfFJL7QOXcIcyOpMsBydssz9DYrb K+wWeVjJSzJpEaZJG5/MZsXXZjYdDBe1CxfVT8Ksriwmv0BMH0ZwMM9gyJMqMwrx YoWlY= Received: from [192.168.1.165] (unknown [1.186.101.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a84.g.dreamhost.com (Postfix) with ESMTPSA id 12A9689A86 for ; Mon, 16 Aug 2021 19:58:34 -0700 (PDT) Subject: [PING2][PATCH v2] setlocale: Fail if iconv module for charset is not present [BZ #27996] To: libc-alpha@sourceware.org References: <2e328221-075c-0297-d437-a1515373dd92@sourceware.org> <20210720023658.1278155-1-siddhesh@sourceware.org> <380077ec-12e6-a06e-d9ed-f433080bd30a@sourceware.org> X-DH-BACKEND: pdx1-sub0-mail-a84 From: Siddhesh Poyarekar Message-ID: Date: Tue, 17 Aug 2021 08:28:29 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: <380077ec-12e6-a06e-d9ed-f433080bd30a@sourceware.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-3035.7 required=5.0 tests=BAYES_00, BODY_8BITS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2021 02:58:49 -0000 Ping! On 8/11/21 1:12 PM, Siddhesh Poyarekar via Libc-alpha wrote: > Ping! >=20 > On 7/20/21 8:06 AM, Siddhesh Poyarekar via Libc-alpha wrote: >> setlocale currently succeeds even if the requested locale uses a >> charset that does not have a converter module installed.=C2=A0 Check f= or >> existence of the charset (either the one requested through the input >> name or the one needed by the selected locale file) and fail if it >> doesn't. >> >> The new test tst-invalid-charset verifes that loading test5 and test6 >> locales fail because both locales have charsets without a converter, >> viz. test5 and test6 respectively.=C2=A0 Also, test6.c has been remove= d as >> it was unused. >> --- >> Changes from v1: >> - Find full transformation paths both ways instead of merely looking f= or >> =C2=A0=C2=A0 a FROM converter. >> >> =C2=A0 locale/findlocale.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 77 ++++++++++++----- >> =C2=A0 localedata/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 12 ++- >> =C2=A0 localedata/tests/test6.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 | 137 ------------------------------- >> =C2=A0 localedata/tst-invalid-charset.c |=C2=A0 31 +++++++ >> =C2=A0 4 files changed, 95 insertions(+), 162 deletions(-) >> =C2=A0 delete mode 100644 localedata/tests/test6.c >> =C2=A0 create mode 100644 localedata/tst-invalid-charset.c >> >> diff --git a/locale/findlocale.c b/locale/findlocale.c >> index ab09122b0c..7ccc98cd8b 100644 >> --- a/locale/findlocale.c >> +++ b/locale/findlocale.c >> @@ -98,6 +98,30 @@ valid_locale_name (const char *name) >> =C2=A0=C2=A0=C2=A0 return 1; >> =C2=A0 } >> +/* Return true if we have gconv modules to transform between the=20 >> INTERNAL >> +=C2=A0=C2=A0 encoding and CODESET.=C2=A0 */ >> +static bool >> +codeset_has_module (const char *codeset) >> +{ >> +=C2=A0 struct __gconv_step *steps; >> +=C2=A0 size_t nsteps; >> + >> +=C2=A0 char *ccodeset =3D (char *) alloca (strlen (codeset) + 3); >> +=C2=A0 strip (ccodeset, codeset); >> + >> +=C2=A0 if (__gconv_find_transform ("INTERNAL", ccodeset, &steps, &nst= eps, 0) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 !=3D __GCONV_OK) >> +=C2=A0=C2=A0=C2=A0 return false; >> +=C2=A0 __gconv_close_transform (steps, nsteps); >> + >> +=C2=A0 if (__gconv_find_transform (ccodeset, "INTERNAL", &steps, &nst= eps, 0) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 !=3D __GCONV_OK) >> +=C2=A0=C2=A0=C2=A0 return false; >> +=C2=A0 __gconv_close_transform (steps, nsteps); >> + >> +=C2=A0 return true; >> +} >> + >> =C2=A0 struct __locale_data * >> =C2=A0 _nl_find_locale (const char *locale_path, size_t locale_path_le= n, >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 int categ= ory, const char **name) >> @@ -200,6 +224,10 @@ _nl_find_locale (const char *locale_path, size_t=20 >> locale_path_len, >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Memory allocate problem.=C2=A0 */ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return NULL; >> +=C2=A0 /* The requested codeset does not have a converter, don't use = it.=C2=A0 */ >> +=C2=A0 if (codeset !=3D NULL && !codeset_has_module (codeset)) >> +=C2=A0=C2=A0=C2=A0 return NULL; >> + >> =C2=A0=C2=A0=C2=A0 /* If exactly this locale was already asked for we = have an entry with >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 the complete name.=C2=A0 */ >> =C2=A0=C2=A0=C2=A0 locale_file =3D _nl_make_l10nflist (&_nl_locale_fil= e_list[category], >> @@ -248,6 +276,33 @@ _nl_find_locale (const char *locale_path, size_t=20 >> locale_path_len, >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return NULL; >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } >> +=C2=A0 /* Get the codeset information from the locale file.=C2=A0 */ >> +=C2=A0 static const int codeset_idx[] =3D >> +=C2=A0=C2=A0=C2=A0 { >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_CTYPE] =3D _NL_ITEM_INDEX (CODES= ET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_NUMERIC] =3D _NL_ITEM_INDEX (_NL= _NUMERIC_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_TIME] =3D _NL_ITEM_INDEX (_NL_TI= ME_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_COLLATE] =3D _NL_ITEM_INDEX (_NL= _COLLATE_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MONETARY] =3D _NL_ITEM_INDEX (_N= L_MONETARY_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MESSAGES] =3D _NL_ITEM_INDEX (_N= L_MESSAGES_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_PAPER] =3D _NL_ITEM_INDEX (_NL_P= APER_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_NAME] =3D _NL_ITEM_INDEX (_NL_NA= ME_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_ADDRESS] =3D _NL_ITEM_INDEX (_NL= _ADDRESS_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_TELEPHONE] =3D _NL_ITEM_INDEX (_= NL_TELEPHONE_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MEASUREMENT] =3D _NL_ITEM_INDEX = (_NL_MEASUREMENT_CODESET), >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_IDENTIFICATION] =3D _NL_ITEM_IND= EX=20 >> (_NL_IDENTIFICATION_CODESET) >> +=C2=A0=C2=A0=C2=A0 }; >> +=C2=A0 const struct __locale_data *data; >> +=C2=A0 const char *locale_codeset; >> + >> +=C2=A0 data =3D (const struct __locale_data *) locale_file->data; >> +=C2=A0 locale_codeset =3D (const char *)=20 >> data->values[codeset_idx[category]].string; >> +=C2=A0 assert (locale_codeset !=3D NULL); >> + >> +=C2=A0 /* The locale codeset does not have a converter, don't use it.= =C2=A0 */ >> +=C2=A0 if (locale_codeset[0] !=3D '\0' && !codeset_has_module (locale= _codeset)) >> +=C2=A0=C2=A0=C2=A0 return NULL; >> + >> =C2=A0=C2=A0=C2=A0 /* The LC_CTYPE category allows to check whether a = locale is really >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 usable.=C2=A0 If the locale name = contains a charset name and the >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 charset name used in the locale (= present in the LC_CTYPE data) is >> @@ -256,31 +311,9 @@ _nl_find_locale (const char *locale_path, size_t=20 >> locale_path_len, >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 in the locale name.=C2=A0 */ >> =C2=A0=C2=A0=C2=A0 if (codeset !=3D NULL) >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Get the codeset information from th= e locale file.=C2=A0 */ >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 static const int codeset_idx[] =3D >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_CTYPE] =3D _NL_ITEM_INDEX (CODES= ET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_NUMERIC] =3D _NL_ITEM_INDEX (_NL= _NUMERIC_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_TIME] =3D _NL_ITEM_INDEX (_NL_TI= ME_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_COLLATE] =3D _NL_ITEM_INDEX (_NL= _COLLATE_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MONETARY] =3D _NL_ITEM_INDEX (_N= L_MONETARY_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MESSAGES] =3D _NL_ITEM_INDEX (_N= L_MESSAGES_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_PAPER] =3D _NL_ITEM_INDEX (_NL_P= APER_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_NAME] =3D _NL_ITEM_INDEX (_NL_NA= ME_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_ADDRESS] =3D _NL_ITEM_INDEX (_NL= _ADDRESS_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_TELEPHONE] =3D _NL_ITEM_INDEX (_= NL_TELEPHONE_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_MEASUREMENT] =3D _NL_ITEM_INDEX = (_NL_MEASUREMENT_CODESET), >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [__LC_IDENTIFICATION] =3D _NL_ITEM_IND= EX=20 >> (_NL_IDENTIFICATION_CODESET) >> -=C2=A0=C2=A0=C2=A0 }; >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const struct __locale_data *data; >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const char *locale_codeset; >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 char *clocale_codeset; >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 char *ccodeset; >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 data =3D (const struct __locale_data *= ) locale_file->data; >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 locale_codeset =3D >> -=C2=A0=C2=A0=C2=A0 (const char *) data->values[codeset_idx[category]]= .string; >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 assert (locale_codeset !=3D NULL); >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Note the length of the a= llocated memory: +3 for up to two=20 >> slashes >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 and the NUL byte.=C2=A0 */ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 clocale_codeset =3D (char *= ) alloca (strlen (locale_codeset) + 3); >> diff --git a/localedata/Makefile b/localedata/Makefile >> index 14e04cd3c5..2af399ec51 100644 >> --- a/localedata/Makefile >> +++ b/localedata/Makefile >> @@ -124,11 +124,13 @@ test-input :=3D \ >> =C2=A0 test-input-data =3D $(addsuffix .in, $(test-input)) >> =C2=A0 test-output :=3D $(foreach s, .out .xout, \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 $(addsuffix $s, $(basename $(test-input)))) >> +# Note that tst-invalid-charset depends on test5 and test6 being=20 >> locales that >> +# do not have valid charset converters. >> =C2=A0 ld-test-names :=3D test1 test2 test3 test4 test5 test6 test7 >> =C2=A0 ld-test-srcs :=3D $(addprefix tests/,$(addsuffix .cm,$(ld-test-= names)) \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(addsuffix .def,$(ld-te= st-names)) \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(addsuffix .ds,test5 te= st6) \ >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 test6.c trans.def) >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 trans.def) >> =C2=A0 fmon-tests =3D n01y12 n02n40 n10y31 n11y41 n12y11 n20n32 n30y20= n41n00 \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 y01y10 y0= 2n22 y22n42 y30y21 y32n31 y40y00 y42n21 >> @@ -158,7 +160,7 @@ tests =3D $(locale_test_suite) tst-digits=20 >> tst-setlocale bug-iconv-trans \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tst-leaks tst-mbswcs1 tst-mbswcs2 tst-m= bswcs3 tst-mbswcs4=20 >> tst-mbswcs5 \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tst-mbswcs6 tst-xlocale1 tst-xlocale2 b= ug-usesetlocale \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tst-strfmon1 tst-sscanf bug-setlocale1 = tst-setlocale2=20 >> tst-setlocale3 \ >> -=C2=A0=C2=A0=C2=A0 tst-wctype tst-iconv-math-trans >> +=C2=A0=C2=A0=C2=A0 tst-wctype tst-iconv-math-trans tst-invalid-charse= t >> =C2=A0 tests-static =3D bug-setlocale1-static >> =C2=A0 tests +=3D $(tests-static) >> =C2=A0 ifeq (yes,$(build-shared)) >> @@ -401,7 +403,10 @@ $(objpfx)tst-langinfo-setlocale-static.out:=20 >> tst-langinfo.sh \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 '$(run-pr= ogram-env)' '$(test-program-cmd-after-env)' > $@; \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(evaluate-test) >> +# These tests depend on tst-locale because they use the locales=20 >> compiled by >> +# that test. >> =C2=A0 $(objpfx)tst-digits.out: $(objpfx)tst-locale.out >> +$(objpfx)tst-invalid-charset.out: $(objpfx)tst-locale.out >> =C2=A0 $(objpfx)tst-mbswcs6.out: $(addprefix $(objpfx),$(CTYPE_FILES)) >> =C2=A0 endif >> @@ -461,7 +466,8 @@ $(objpfx)mtrace-tst-leaks.out: $(objpfx)tst-leaks.= out >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(common-objpfx)malloc/mtrace $(objpfx)= tst-leaks.mtrace > $@; \ >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(evaluate-test) >> -bug-setlocale1-ENV-only =3D LOCPATH=3D$(objpfx) LC_CTYPE=3Dde_DE.UTF-= 8 >> +bug-setlocale1-ENV-only =3D GCONV_PATH=3D$(common-objpfx)iconvdata \ >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 LOCPATH=3D$(objpfx) LC_CTYPE=3Dde_DE.UTF-8 >> =C2=A0 bug-setlocale1-static-ENV-only =3D $(bug-setlocale1-ENV-only) >> =C2=A0 $(objdir)/iconvdata/gconv-modules: >> diff --git a/localedata/tests/test6.c b/localedata/tests/test6.c >> deleted file mode 100644 >> index edb5fe4a5f..0000000000 >> --- a/localedata/tests/test6.c >> +++ /dev/null >> @@ -1,137 +0,0 @@ >> -/* Test program for character classes and mappings. >> -=C2=A0=C2=A0 Copyright (C) 1999-2021 Free Software Foundation, Inc. >> -=C2=A0=C2=A0 This file is part of the GNU C Library. >> -=C2=A0=C2=A0 Contributed by Ulrich Drepper , 1999= . >> - >> -=C2=A0=C2=A0 The GNU C Library is free software; you can redistribute= it and/or >> -=C2=A0=C2=A0 modify it under the terms of the GNU Lesser General Publ= ic >> -=C2=A0=C2=A0 License as published by the Free Software Foundation; ei= ther >> -=C2=A0=C2=A0 version 2.1 of the License, or (at your option) any late= r version. >> - >> -=C2=A0=C2=A0 The GNU C Library is distributed in the hope that it wil= l be useful, >> -=C2=A0=C2=A0 but WITHOUT ANY WARRANTY; without even the implied warra= nty of >> -=C2=A0=C2=A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0= See the GNU >> -=C2=A0=C2=A0 Lesser General Public License for more details. >> - >> -=C2=A0=C2=A0 You should have received a copy of the GNU Lesser Genera= l Public >> -=C2=A0=C2=A0 License along with the GNU C Library; if not, see >> -=C2=A0=C2=A0 .=C2=A0 */ >> - >> -#include >> -#include >> -#include >> - >> - >> -int >> -main (void) >> -{ >> -=C2=A0 const char lower[] =3D "abcdefghijklmnopqrstuvwxyz"; >> -=C2=A0 const char upper[] =3D "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; >> -#define LEN (sizeof (upper) - 1) >> -=C2=A0 const wchar_t wlower[] =3D L"abcdefghijklmnopqrstuvwxyz"; >> -=C2=A0 const wchar_t wupper[] =3D L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; >> -=C2=A0 int i; >> -=C2=A0 int result =3D 0; >> - >> -=C2=A0 setlocale (LC_ALL, "test6"); >> - >> -=C2=A0 for (i =3D 0; i < LEN; ++i) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* Test basic table handling (basic =3D= =3D not more than 256=20 >> characters). >> -=C2=A0=C2=A0=C2=A0=C2=A0 The charmaps swaps the normal lower-upper ca= se meaning of the >> -=C2=A0=C2=A0=C2=A0=C2=A0 ASCII characters used in the source code whi= le the Unicode mapping >> -=C2=A0=C2=A0=C2=A0=C2=A0 in the repertoire map has the normal corresp= ondents.=C2=A0 This test >> -=C2=A0=C2=A0=C2=A0=C2=A0 shows the independence of the tables for `ch= ar' and `wchar_t' >> -=C2=A0=C2=A0=C2=A0=C2=A0 characters.=C2=A0 */ >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (islower (lower[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("islower ('%c') false\n", lowe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (! isupper (lower[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("isupper ('%c') false\n", lowe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (! islower (upper[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("islower ('%c') false\n", uppe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (isupper (upper[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("isupper ('%c') false\n", uppe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (toupper (lower[i]) !=3D lower[i]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("toupper ('%c') false\n", lowe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (tolower (lower[i]) !=3D upper[i]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("tolower ('%c') false\n", lowe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (tolower (upper[i]) !=3D upper[i]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("tolower ('%c') false\n", uppe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (toupper (upper[i]) !=3D lower[i]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("toupper ('%c') false\n", uppe= r[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (iswlower (wupper[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("iswlower (L'%c') false\n", up= per[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (! iswupper (wupper[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("iswupper (L'%c') false\n", up= per[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (iswupper (wlower[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("iswupper (L'%c') false\n", lo= wer[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (! iswlower (wlower[i])) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("iswlower (L'%c') false\n", lo= wer[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (towupper (wlower[i]) !=3D wupper[i= ]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("towupper ('%c') false\n", low= er[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (towlower (wlower[i]) !=3D wlower[i= ]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("towlower ('%c') false\n", low= er[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (towlower (wupper[i]) !=3D wlower[i= ]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("towlower ('%c') false\n", upp= er[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (towupper (wupper[i]) !=3D wupper[i= ]) >> -=C2=A0=C2=A0=C2=A0 { >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 printf ("towupper ('%c') false\n", upp= er[i]); >> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 result =3D 1; >> -=C2=A0=C2=A0=C2=A0 } >> -=C2=A0=C2=A0=C2=A0 } >> - >> -=C2=A0 return result; >> -} >> diff --git a/localedata/tst-invalid-charset.c=20 >> b/localedata/tst-invalid-charset.c >> new file mode 100644 >> index 0000000000..46a5198c66 >> --- /dev/null >> +++ b/localedata/tst-invalid-charset.c >> @@ -0,0 +1,31 @@ >> +/* Test program to verify that setlocale fails for charsets that do=20 >> not have a >> +=C2=A0=C2=A0 converter. >> +=C2=A0=C2=A0 Copyright (C) 2021 Free Software Foundation, Inc. >> +=C2=A0=C2=A0 This file is part of the GNU C Library. >> + >> +=C2=A0=C2=A0 The GNU C Library is free software; you can redistribute= it and/or >> +=C2=A0=C2=A0 modify it under the terms of the GNU Lesser General Publ= ic >> +=C2=A0=C2=A0 License as published by the Free Software Foundation; ei= ther >> +=C2=A0=C2=A0 version 2.1 of the License, or (at your option) any late= r version. >> + >> +=C2=A0=C2=A0 The GNU C Library is distributed in the hope that it wil= l be useful, >> +=C2=A0=C2=A0 but WITHOUT ANY WARRANTY; without even the implied warra= nty of >> +=C2=A0=C2=A0 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0= See the GNU >> +=C2=A0=C2=A0 Lesser General Public License for more details. >> + >> +=C2=A0=C2=A0 You should have received a copy of the GNU Lesser Genera= l Public >> +=C2=A0=C2=A0 License along with the GNU C Library; if not, see >> +=C2=A0=C2=A0 .=C2=A0 */ >> + >> +#include >> +#include >> +#include >> + >> + >> +int >> +main (void) >> +{ >> +=C2=A0 /* Fail if setlocale succeeds for any of these locales.=C2=A0 = */ >> +=C2=A0 return (setlocale (LC_ALL, "test5") !=3D NULL >> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 || setlocale (LC_ALL, "test6") !=3D NU= LL); >> +} >> >=20