summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortijl <tijl@FreeBSD.org>2014-06-20 07:32:03 +0000
committertijl <tijl@FreeBSD.org>2014-06-20 07:32:03 +0000
commitde4e2206d57bda2268e6b69f09b86ff63cc71f8e (patch)
tree60af671abf1bc0d1bc97daa15754adcb118b899b
parent7944ea7242fccf98384460100e2b5e384628fa89 (diff)
downloadFreeBSD-src-de4e2206d57bda2268e6b69f09b86ff63cc71f8e.zip
FreeBSD-src-de4e2206d57bda2268e6b69f09b86ff63cc71f8e.tar.gz
MFC r267436-267439:
- Replace malloc+memset with calloc. - iconv_open(3): initialise ci_ilseq_invalid field of _citrus_iconv_shared struct after allocation with malloc. - iconvlist(3): reduce a memory leak by copying strings only once. - iconv(1): - Make invalids variable local to do_conv such that it prints the number of invalid characters of the current file instead of an accumulated value. - Make do_conv return an error when invalid characters have been found. Return EXIT_FAILURE from main if any file contained invalid characters. This matches the behaviour of GNU iconv. - Mark usage with __dead2 attribute. - Make the long_options array const. Tested by: Pavel Timofeev <timp87@gmail.com>
-rw-r--r--lib/libc/iconv/bsd_iconv.c5
-rw-r--r--lib/libc/iconv/citrus_db_factory.c4
-rw-r--r--lib/libc/iconv/citrus_iconv.c3
-rw-r--r--lib/libiconv_modules/HZ/citrus_hz.c6
-rw-r--r--usr.bin/iconv/iconv.c27
5 files changed, 21 insertions, 24 deletions
diff --git a/lib/libc/iconv/bsd_iconv.c b/lib/libc/iconv/bsd_iconv.c
index 40a1a4e..f764886 100644
--- a/lib/libc/iconv/bsd_iconv.c
+++ b/lib/libc/iconv/bsd_iconv.c
@@ -83,6 +83,7 @@ __bsd___iconv_open(const char *out, const char *in, struct _citrus_iconv *handle
}
handle->cv_shared->ci_discard_ilseq = strcasestr(out, "//IGNORE");
+ handle->cv_shared->ci_ilseq_invalid = false;
handle->cv_shared->ci_hooks = NULL;
return ((iconv_t)(void *)handle);
@@ -223,7 +224,7 @@ __bsd_iconvlist(int (*do_one) (unsigned int, const char * const *,
return;
}
strlcpy(curkey, list[i], slashpos - list[i] + 1);
- names[j++] = strdup(curkey);
+ names[j++] = curkey;
for (; (i < sz) && (memcmp(curkey, list[i], strlen(curkey)) == 0); i++) {
slashpos = strchr(list[i], '/');
curitem = (char *)malloc(strlen(slashpos) + 1);
@@ -235,7 +236,7 @@ __bsd_iconvlist(int (*do_one) (unsigned int, const char * const *,
if (strcmp(curkey, curitem) == 0) {
continue;
}
- names[j++] = strdup(curitem);
+ names[j++] = curitem;
}
np = (const char * const *)names;
do_one(j, np, data);
diff --git a/lib/libc/iconv/citrus_db_factory.c b/lib/libc/iconv/citrus_db_factory.c
index e9823ab..691fe4e 100644
--- a/lib/libc/iconv/citrus_db_factory.c
+++ b/lib/libc/iconv/citrus_db_factory.c
@@ -270,11 +270,9 @@ _citrus_db_factory_serialize(struct _citrus_db_factory *df, const char *magic,
return (0);
}
/* allocate hash table */
- depp = malloc(sizeof(*depp) * df->df_num_entries);
+ depp = calloc(df->df_num_entries, sizeof(*depp));
if (depp == NULL)
return (-1);
- for (i = 0; i < df->df_num_entries; i++)
- depp[i] = NULL;
/* step1: store the entries which are not conflicting */
STAILQ_FOREACH(de, &df->df_entries, de_entry) {
diff --git a/lib/libc/iconv/citrus_iconv.c b/lib/libc/iconv/citrus_iconv.c
index df2ed73..5c8bf49 100644
--- a/lib/libc/iconv/citrus_iconv.c
+++ b/lib/libc/iconv/citrus_iconv.c
@@ -344,9 +344,8 @@ const char
{
char *buf;
- if ((buf = malloc((size_t)PATH_MAX)) == NULL)
+ if ((buf = calloc((size_t)PATH_MAX, sizeof(*buf))) == NULL)
return (NULL);
- memset((void *)buf, 0, (size_t)PATH_MAX);
_citrus_esdb_alias(name, buf, (size_t)PATH_MAX);
return (buf);
}
diff --git a/lib/libiconv_modules/HZ/citrus_hz.c b/lib/libiconv_modules/HZ/citrus_hz.c
index f9eb006..d772b38 100644
--- a/lib/libiconv_modules/HZ/citrus_hz.c
+++ b/lib/libiconv_modules/HZ/citrus_hz.c
@@ -532,10 +532,9 @@ _citrus_HZ_parse_graphic(void *context, const char *name, const char *s)
p = (void **)context;
escape = (escape_t *)p[0];
ei = (_HZEncodingInfo *)p[1];
- graphic = malloc(sizeof(*graphic));
+ graphic = calloc(1, sizeof(*graphic));
if (graphic == NULL)
return (ENOMEM);
- memset(graphic, 0, sizeof(*graphic));
if (strcmp("GL", name) == 0) {
if (GL(escape) != NULL)
goto release;
@@ -598,10 +597,9 @@ _citrus_HZ_parse_escape(void *context, const char *name, const char *s)
void *p[2];
ei = (_HZEncodingInfo *)context;
- escape = malloc(sizeof(*escape));
+ escape = calloc(1, sizeof(*escape));
if (escape == NULL)
return (EINVAL);
- memset(escape, 0, sizeof(*escape));
if (strcmp("0", name) == 0) {
escape->set = E0SET(ei);
TAILQ_INSERT_TAIL(E0SET(ei), escape, entry);
diff --git a/usr.bin/iconv/iconv.c b/usr.bin/iconv/iconv.c
index 77dd11a..dc2aec0 100644
--- a/usr.bin/iconv/iconv.c
+++ b/usr.bin/iconv/iconv.c
@@ -41,13 +41,11 @@
#include <string.h>
#include <unistd.h>
-static unsigned long long invalids;
+static int do_conv(FILE *, const char *, const char *, bool, bool);
+static int do_list(unsigned int, const char * const *, void *);
+static void usage(void) __dead2;
-static void do_conv(FILE *, const char *, const char *, bool, bool);
-static int do_list(unsigned int, const char * const *, void *);
-static void usage(void);
-
-static struct option long_options[] = {
+static const struct option long_options[] = {
{"from-code", required_argument, NULL, 'f'},
{"list", no_argument, NULL, 'l'},
{"silent", no_argument, NULL, 's'},
@@ -68,12 +66,13 @@ usage(void)
#define INBUFSIZE 1024
#define OUTBUFSIZE (INBUFSIZE * 2)
-static void
+static int
do_conv(FILE *fp, const char *from, const char *to, bool silent,
bool hide_invalid)
{
iconv_t cd;
char inbuf[INBUFSIZE], outbuf[OUTBUFSIZE], *out;
+ unsigned long long invalids;
const char *in;
size_t inbytes, outbytes, ret;
@@ -84,8 +83,9 @@ do_conv(FILE *fp, const char *from, const char *to, bool silent,
int arg = 1;
if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (void *)&arg) == -1)
- err(1, NULL);
+ err(EXIT_FAILURE, NULL);
}
+ invalids = 0;
while ((inbytes = fread(inbuf, 1, INBUFSIZE, fp)) > 0) {
in = inbuf;
while (inbytes > 0) {
@@ -135,6 +135,7 @@ do_conv(FILE *fp, const char *from, const char *to, bool silent,
warnx("warning: invalid characters: %llu", invalids);
iconv_close(cd);
+ return (invalids > 0);
}
static int
@@ -157,7 +158,7 @@ main(int argc, char **argv)
{
FILE *fp;
char *opt_f, *opt_t;
- int ch, i;
+ int ch, i, res;
bool opt_c = false, opt_s = false;
opt_f = opt_t = strdup("");
@@ -202,18 +203,18 @@ main(int argc, char **argv)
if ((strcmp(opt_f, "") == 0) && (strcmp(opt_t, "") == 0))
usage();
if (argc == 0)
- do_conv(stdin, opt_f, opt_t, opt_s, opt_c);
+ res = do_conv(stdin, opt_f, opt_t, opt_s, opt_c);
else {
+ res = 0;
for (i = 0; i < argc; i++) {
fp = (strcmp(argv[i], "-") != 0) ?
fopen(argv[i], "r") : stdin;
if (fp == NULL)
err(EXIT_FAILURE, "Cannot open `%s'",
argv[i]);
- do_conv(fp, opt_f, opt_t, opt_s,
- opt_c);
+ res |= do_conv(fp, opt_f, opt_t, opt_s, opt_c);
(void)fclose(fp);
}
}
- return (EXIT_SUCCESS);
+ return (res == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
OpenPOWER on IntegriCloud