From patchwork Wed Oct 26 10:00:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 16832 Received: (qmail 45324 invoked by alias); 26 Oct 2016 10:01:09 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 45287 invoked by uid 89); 26 Oct 2016 10:01:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.2 spammy=pt2, es2, Hx-languages-length:2781, 2016-10-26 X-HELO: mx1.redhat.com Date: Wed, 26 Oct 2016 12:00:46 +0200 To: libc-alpha@sourceware.org Subject: [PATCH] iconv: Avoid writable data and relocations in ISO646 User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20161026100046.7E426439942E0@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) 2016-10-26 Florian Weimer * iconvdata/iso646.c (enum variant): Drop illegal_var. (names): Turn into concatenation of strings. (gconv_init): Adapt iteration over names. diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c index b048c20..54e6b33 100644 --- a/iconvdata/iso646.c +++ b/iconvdata/iso646.c @@ -60,9 +60,9 @@ enum direction from_iso646 }; +/* See names below, must be in the same order. */ enum variant { - illegal_var, GB, /* BS_4730 */ CA, /* CSA_Z243.4-1985-1 */ CA2, /* CSA_Z243.4-1985-2 */ @@ -88,33 +88,33 @@ enum variant SE2 /* SEN_850200_C */ }; -static const char *names[] = -{ - [GB] = "BS_4730//", - [CA] = "CSA_Z243.4-1985-1//", - [CA2] = "CSA_Z243.4-1985-2//", - [DE] = "DIN_66003//", - [DK] = "DS_2089//", - [ES] = "ES//", - [ES2] = "ES2//", - [CN] = "GB_1988-80//", - [IT] = "IT//", - [JP] = "JIS_C6220-1969-RO//", - [JP_OCR_B] = "JIS_C6229-1984-B//", - [YU] = "JUS_I.B1.002//", - [KR] = "KSC5636//", - [HU] = "MSZ_7795.3//", - [CU] = "NC_NC00-10//", - [FR] = "NF_Z_62-010//", - [FR1] = "NF_Z_62-010_1973//", /* Note that we don't have the parenthesis - in the name. */ - [NO] = "NS_4551-1//", - [NO2] = "NS_4551-2//", - [PT] = "PT//", - [PT2] = "PT2//", - [SE] = "SEN_850200_B//", - [SE2] = "SEN_850200_C//" -}; +/* Must be in the same order as enum variant above. */ +static const char names[] = + "BS_4730//\0" + "CSA_Z243.4-1985-1//\0" + "CSA_Z243.4-1985-2//\0" + "DIN_66003//\0" + "DS_2089//\0" + "ES//\0" + "ES2//\0" + "GB_1988-80//\0" + "IT//\0" + "JIS_C6220-1969-RO//\0" + "JIS_C6229-1984-B//\0" + "JUS_I.B1.002//\0" + "KSC5636//\0" + "MSZ_7795.3//\0" + "NC_NC00-10//\0" + "NF_Z_62-010//\0" + "NF_Z_62-010_1973//\0" /* Note that we don't have the parenthesis in + the name. */ + "NS_4551-1//\0" + "NS_4551-2//\0" + "PT//\0" + "PT2//\0" + "SEN_850200_B//\0" + "SEN_850200_C//\0" + "\0"; struct iso646_data { @@ -130,20 +130,24 @@ gconv_init (struct __gconv_step *step) /* Determine which direction. */ struct iso646_data *new_data; enum direction dir = illegal_dir; - enum variant var; int result; - for (var = sizeof (names) / sizeof (names[0]) - 1; var > illegal_var; --var) - if (__strcasecmp (step->__from_name, names[var]) == 0) - { - dir = from_iso646; - break; - } - else if (__strcasecmp (step->__to_name, names[var]) == 0) - { - dir = to_iso646; - break; - } + enum variant var = 0; + for (const char *name = names; *name != '\0'; + name = __rawmemchr (name, '\0') + 1) + { + if (__strcasecmp (step->__from_name, name) == 0) + { + dir = from_iso646; + break; + } + else if (__strcasecmp (step->__to_name, name) == 0) + { + dir = to_iso646; + break; + } + ++var; + } result = __GCONV_NOCONV; if (__builtin_expect (dir, from_iso646) != illegal_dir)