From: Todd C. Miller Date: Mon, 19 Mar 2012 15:23:25 +0000 (-0400) Subject: Add ecalloc() and commented out recalloc(). X-Git-Tag: SUDO_1_8_5~1^2~127 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dbbb48c45f4293cf0fd83015c9cdd1e26c3cdce9;p=sudo Add ecalloc() and commented out recalloc(). Use inline strnlen() instead of strlen() in estrndup(). --- diff --git a/common/alloc.c b/common/alloc.c index 7d5fe7e9e..cbf8f626f 100644 --- a/common/alloc.c +++ b/common/alloc.c @@ -106,6 +106,29 @@ emalloc2(size_t nmemb, size_t size) return ptr; } +/* + * ecalloc() allocates nmemb * size bytes and exits with an error + * if overflow would occur or if the system malloc(3) fails. + * On success, the allocated space is zero-filled. + */ +void * +ecalloc(size_t nmemb, size_t size) +{ + void *ptr; + + if (nmemb == 0 || size == 0) + errorx2(1, _("internal error, tried to ecalloc(0)")); + if (nmemb != 1) { + if (nmemb > SIZE_MAX / size) + errorx2(1, _("internal error, ecalloc() overflow")); + size *= nmemb; + } + if ((ptr = malloc(size)) == NULL) + errorx2(1, _("unable to allocate memory")); + memset(ptr, 0, size); + return ptr; +} + /* * erealloc() calls the system realloc(3) and exits with an error if * realloc(3) fails. You can call erealloc() with a NULL pointer even @@ -146,6 +169,35 @@ erealloc3(void *ptr, size_t nmemb, size_t size) return ptr; } +#ifdef notyet +/* + * erecalloc() realloc(3)s nmemb * msize bytes and exits with an error + * if overflow would occur or if the system malloc(3)/realloc(3) fails. + * On success, the new space is zero-filled. You can call ereallocz() + * with a NULL pointer even if the system realloc(3) does not support this. + */ +void * +erecalloc(void *ptr, size_t onmemb, size_t nmemb, size_t msize) +{ + size_t size; + + if (nmemb == 0 || msize == 0) + errorx2(1, _("internal error, tried to erealloc3(0)")); + if (nmemb > SIZE_MAX / msize) + errorx2(1, _("internal error, erealloc3() overflow")); + + size = nmemb * msize; + ptr = ptr ? realloc(ptr, size) : malloc(size); + if (ptr == NULL) + errorx2(1, _("unable to allocate memory")); + if (nmemb > onmemb) { + size = (nmemb - onmemb) * msize; + memset((char *)ptr + (onmemb * msize), 0, size); + } + return ptr; +} +#endif + /* * estrdup() is like strdup(3) except that it exits with an error if * malloc(3) fails. NOTE: unlike strdup(3), estrdup(NULL) is legal. @@ -173,12 +225,13 @@ char * estrndup(const char *src, size_t maxlen) { char *dst = NULL; - size_t len; + size_t len = 0; if (src != NULL) { - len = strlen(src); - if (len > maxlen) - len = maxlen; + while (maxlen != 0 && src[len] != '\0') { + len++; + maxlen--; + } dst = (char *) emalloc(len + 1); (void) memcpy(dst, src, len); dst[len] = '\0'; diff --git a/include/alloc.h b/include/alloc.h index 912654edc..b5b3e381d 100644 --- a/include/alloc.h +++ b/include/alloc.h @@ -22,10 +22,12 @@ int easprintf(char **, const char *, ...) __printflike(2, 3); int evasprintf(char **, const char *, va_list) __printflike(2, 0); void efree(void *); +void *ecalloc(size_t, size_t); void *emalloc(size_t); void *emalloc2(size_t, size_t); void *erealloc(void *, size_t); void *erealloc3(void *, size_t, size_t); +void *erecalloc(void *, size_t, size_t, size_t); char *estrdup(const char *); char *estrndup(const char *, size_t);