|
|
6c0556 |
commit 9429049c178b3af3d6afeb3717ff1f2214dc9572
|
|
|
6c0556 |
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
|
|
6c0556 |
Date: Mon Jun 28 09:15:55 2021 +0530
|
|
|
6c0556 |
|
|
|
6c0556 |
iconvconfig: Fix multiple issues
|
|
|
6c0556 |
|
|
|
6c0556 |
It was noticed on big-endian systems that msgfmt would fail with the
|
|
|
6c0556 |
following error:
|
|
|
6c0556 |
|
|
|
6c0556 |
msgfmt: gconv_builtin.c:70: __gconv_get_builtin_trans: Assertion `cnt < sizeof (map) / sizeof (map[0])' failed.
|
|
|
6c0556 |
Aborted (core dumped)
|
|
|
6c0556 |
|
|
|
6c0556 |
This is only seen on installed systems because it was due to a
|
|
|
6c0556 |
corrupted gconv-modules.cache. iconvconfig had the following issues
|
|
|
6c0556 |
(it was specifically freeing fulldir that caused this issue, but other
|
|
|
6c0556 |
cleanups are also needed) that this patch fixes.
|
|
|
6c0556 |
|
|
|
6c0556 |
- Add prefix only if dir starts with '/'
|
|
|
6c0556 |
- Use asprintf instead of mempcpy so that the directory string is NULL
|
|
|
6c0556 |
terminated
|
|
|
6c0556 |
- Make a copy of the directory reference in new_module so that fulldir
|
|
|
6c0556 |
can be freed within the same scope in handle_dir.
|
|
|
6c0556 |
|
|
|
6c0556 |
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
|
|
6c0556 |
|
|
|
6c0556 |
diff --git a/iconv/Makefile b/iconv/Makefile
|
|
|
6c0556 |
index d09b8ac842731780..6df9862e748ae588 100644
|
|
|
6c0556 |
--- a/iconv/Makefile
|
|
|
6c0556 |
+++ b/iconv/Makefile
|
|
|
6c0556 |
@@ -33,7 +33,7 @@ vpath %.c ../locale/programs ../intl
|
|
|
6c0556 |
iconv_prog-modules = iconv_charmap charmap charmap-dir linereader \
|
|
|
6c0556 |
dummy-repertoire simple-hash xstrdup xmalloc \
|
|
|
6c0556 |
record-status
|
|
|
6c0556 |
-iconvconfig-modules = strtab xmalloc hash-string
|
|
|
6c0556 |
+iconvconfig-modules = strtab xmalloc xasprintf xstrdup hash-string
|
|
|
6c0556 |
extra-objs = $(iconv_prog-modules:=.o) $(iconvconfig-modules:=.o)
|
|
|
6c0556 |
CFLAGS-iconv_prog.c += -I../locale/programs
|
|
|
6c0556 |
CFLAGS-iconv_charmap.c += -I../locale/programs
|
|
|
6c0556 |
diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c
|
|
|
6c0556 |
index 01ecf6f67d55dbbf..777da870d2f8e99a 100644
|
|
|
6c0556 |
--- a/iconv/iconvconfig.c
|
|
|
6c0556 |
+++ b/iconv/iconvconfig.c
|
|
|
6c0556 |
@@ -250,6 +250,7 @@ static const char gconv_module_ext[] = MODULE_EXT;
|
|
|
6c0556 |
|
|
|
6c0556 |
|
|
|
6c0556 |
#include <programs/xmalloc.h>
|
|
|
6c0556 |
+#include <programs/xasprintf.h>
|
|
|
6c0556 |
|
|
|
6c0556 |
|
|
|
6c0556 |
/* C string table handling. */
|
|
|
6c0556 |
@@ -519,11 +520,12 @@ module_compare (const void *p1, const void *p2)
|
|
|
6c0556 |
/* Create new module record. */
|
|
|
6c0556 |
static void
|
|
|
6c0556 |
new_module (const char *fromname, size_t fromlen, const char *toname,
|
|
|
6c0556 |
- size_t tolen, const char *directory,
|
|
|
6c0556 |
+ size_t tolen, const char *dir_in,
|
|
|
6c0556 |
const char *filename, size_t filelen, int cost, size_t need_ext)
|
|
|
6c0556 |
{
|
|
|
6c0556 |
struct module *new_module;
|
|
|
6c0556 |
- size_t dirlen = strlen (directory) + 1;
|
|
|
6c0556 |
+ size_t dirlen = strlen (dir_in) + 1;
|
|
|
6c0556 |
+ const char *directory = xstrdup (dir_in);
|
|
|
6c0556 |
char *tmp;
|
|
|
6c0556 |
void **inserted;
|
|
|
6c0556 |
|
|
|
6c0556 |
@@ -654,20 +656,10 @@ handle_dir (const char *dir)
|
|
|
6c0556 |
size_t dirlen = strlen (dir);
|
|
|
6c0556 |
bool found = false;
|
|
|
6c0556 |
|
|
|
6c0556 |
- /* Add the prefix before sending it off to the parser. */
|
|
|
6c0556 |
- char *fulldir = xmalloc (prefix_len + dirlen + 2);
|
|
|
6c0556 |
- char *cp = mempcpy (mempcpy (fulldir, prefix, prefix_len), dir, dirlen);
|
|
|
6c0556 |
+ char *fulldir = xasprintf ("%s%s%s", dir[0] == '/' ? prefix : "",
|
|
|
6c0556 |
+ dir, dir[dirlen - 1] != '/' ? "/" : "");
|
|
|
6c0556 |
|
|
|
6c0556 |
- if (dir[dirlen - 1] != '/')
|
|
|
6c0556 |
- {
|
|
|
6c0556 |
- *cp++ = '/';
|
|
|
6c0556 |
- *cp = '\0';
|
|
|
6c0556 |
- dirlen++;
|
|
|
6c0556 |
- }
|
|
|
6c0556 |
-
|
|
|
6c0556 |
- found = gconv_parseconfdir (fulldir, dirlen + prefix_len);
|
|
|
6c0556 |
-
|
|
|
6c0556 |
- free (fulldir);
|
|
|
6c0556 |
+ found = gconv_parseconfdir (fulldir, strlen (fulldir));
|
|
|
6c0556 |
|
|
|
6c0556 |
if (!found)
|
|
|
6c0556 |
{
|
|
|
6c0556 |
@@ -679,6 +671,8 @@ handle_dir (const char *dir)
|
|
|
6c0556 |
"configuration files with names ending in .conf.");
|
|
|
6c0556 |
}
|
|
|
6c0556 |
|
|
|
6c0556 |
+ free (fulldir);
|
|
|
6c0556 |
+
|
|
|
6c0556 |
return found ? 0 : 1;
|
|
|
6c0556 |
}
|
|
|
6c0556 |
|