aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2016-10-26 11:43:21 +0200
committerFlorian Weimer <fweimer@redhat.com>2016-10-26 13:05:49 +0200
commit261e6758e7229aa4c17546b52b002ca9f1b0a67d (patch)
treea8489a01d904457c9cb90c4e9b910c16fbcdd857
parentb9deb8ce2a72de8f74361ea10dd4c4b116458518 (diff)
downloadglibc-261e6758e7229aa4c17546b52b002ca9f1b0a67d.tar
glibc-261e6758e7229aa4c17546b52b002ca9f1b0a67d.tar.gz
glibc-261e6758e7229aa4c17546b52b002ca9f1b0a67d.tar.bz2
glibc-261e6758e7229aa4c17546b52b002ca9f1b0a67d.zip
iconv: Avoid writable data and relocations in ISO646
-rw-r--r--ChangeLog6
-rw-r--r--iconvdata/iso646.c84
2 files changed, 50 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index cddd1e613d..3dd486e417 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2016-10-26 Florian Weimer <fweimer@redhat.com>
+ * iconvdata/iso646.c (enum variant): Drop illegal_var.
+ (names): Turn into concatenation of strings.
+ (gconv_init): Adapt iteration over names.
+
+2016-10-26 Florian Weimer <fweimer@redhat.com>
+
* iconvdata/ibm930.h (__ucs4_to_ibm930sb): Remove indirection and
make const.
* iconvdata/ibm933.h (__ucs4_to_ibm933sb): Likewise.
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
index b048c2018e..54e6b33596 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)