diff options
Diffstat (limited to 'lib/libc/iconv/citrus_iconv.c')
-rw-r--r-- | lib/libc/iconv/citrus_iconv.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/libc/iconv/citrus_iconv.c b/lib/libc/iconv/citrus_iconv.c index fbabf6524399..e785e6721968 100644 --- a/lib/libc/iconv/citrus_iconv.c +++ b/lib/libc/iconv/citrus_iconv.c @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* $NetBSD: citrus_iconv.c,v 1.10 2011/11/19 18:34:21 tnozaki Exp $ */ /*- @@ -29,7 +28,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/queue.h> @@ -81,8 +79,9 @@ init_cache(void) _CITRUS_HASH_INIT(&shared_pool, CI_HASH_SIZE); TAILQ_INIT(&shared_unused); shared_max_reuse = -1; - if (!issetugid() && getenv(CI_ENV_MAX_REUSE)) - shared_max_reuse = atoi(getenv(CI_ENV_MAX_REUSE)); + if (secure_getenv(CI_ENV_MAX_REUSE) != NULL) + shared_max_reuse = + atoi(secure_getenv(CI_ENV_MAX_REUSE)); if (shared_max_reuse < 0) shared_max_reuse = CI_INITIAL_MAX_REUSE; isinit = true; @@ -126,7 +125,12 @@ open_shared(struct _citrus_iconv_shared * __restrict * __restrict rci, * See gettext-0.18.3+ NEWS: * msgfmt now checks PO file headers more strictly with less * false-positives. - * NetBSD don't do this either. + * NetBSD, also, doesn't do the below pass-through. + * + * Also note that this currently falls short if dst options have been + * specified. It may be the case that we want to ignore EILSEQ, in which + * case we should also select iconv_std anyways. This trick, while + * clever, may not be worth it. */ module = (strcmp(src, dst) != 0) ? "iconv_std" : "iconv_none"; #else @@ -135,14 +139,11 @@ open_shared(struct _citrus_iconv_shared * __restrict * __restrict rci, /* initialize iconv handle */ len_convname = strlen(convname); - ci = malloc(sizeof(*ci) + len_convname + 1); + ci = calloc(1, sizeof(*ci) + len_convname + 1); if (!ci) { ret = errno; goto err; } - ci->ci_module = NULL; - ci->ci_ops = NULL; - ci->ci_closure = NULL; ci->ci_convname = (void *)&ci[1]; memcpy(ci->ci_convname, convname, len_convname + 1); @@ -279,7 +280,7 @@ _citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rcv, { struct _citrus_iconv *cv = NULL; struct _citrus_iconv_shared *ci = NULL; - char realdst[PATH_MAX], realsrc[PATH_MAX]; + char realdst[PATH_MAX], realsrc[PATH_MAX], *slashes; #ifdef _PATH_ICONV char buf[PATH_MAX], path[PATH_MAX]; #endif @@ -293,16 +294,25 @@ _citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rcv, if ((strcmp(dst, "") == 0) || (strcmp(dst, "char") == 0)) dst = nl_langinfo(CODESET); + strlcpy(realsrc, src, (size_t)PATH_MAX); + if ((slashes = strstr(realsrc, "//")) != NULL) + *slashes = '\0'; + strlcpy(realdst, dst, (size_t)PATH_MAX); + if ((slashes = strstr(realdst, "//")) != NULL) + *slashes = '\0'; + /* resolve codeset name aliases */ #ifdef _PATH_ICONV + /* + * Note that the below reads from realsrc and realdst while it's + * repopulating (writing to) realsrc and realdst, but it's done so with + * a trip through `buf`. + */ snprintf(path, sizeof(path), "%s/%s", _PATH_ICONV, _CITRUS_ICONV_ALIAS); - strlcpy(realsrc, _lookup_alias(path, src, buf, (size_t)PATH_MAX, + strlcpy(realsrc, _lookup_alias(path, realsrc, buf, (size_t)PATH_MAX, _LOOKUP_CASE_IGNORE), (size_t)PATH_MAX); - strlcpy(realdst, _lookup_alias(path, dst, buf, (size_t)PATH_MAX, + strlcpy(realdst, _lookup_alias(path, realdst, buf, (size_t)PATH_MAX, _LOOKUP_CASE_IGNORE), (size_t)PATH_MAX); -#else - strlcpy(realsrc, src, (size_t)PATH_MAX); - strlcpy(realdst, dst, (size_t)PATH_MAX); #endif /* sanity check */ |