From b9ff0728e1bab018dd888c173151dba35e40ef3b Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Wed, 30 Jul 2014 06:53:02 -0500 Subject: harmonize asprintf with OpenSSH * use the original name for the file from OpenSSH (remove duplicate version) * add va_copy/__va_copy checks to configure * incorporate proposed fixes to openssh version: + include more system headers directly for various definitions + limit the scope of va_copy/va_end to their affected vsnprintf calls + simplify error handling, removing a dead assignment --- configure.ac.tpl | 25 ++++++++++++ crypto/Makefile.am.tpl | 2 +- crypto/compat/asprintf.c | 94 -------------------------------------------- crypto/compat/bsd-asprintf.c | 29 ++++++-------- 4 files changed, 39 insertions(+), 111 deletions(-) delete mode 100644 crypto/compat/asprintf.c diff --git a/configure.ac.tpl b/configure.ac.tpl index de3995c..b557687 100644 --- a/configure.ac.tpl +++ b/configure.ac.tpl @@ -117,6 +117,31 @@ AC_CHECK_FUNC(explicit_bzero, AC_DEFINE(NO_EXPLICIT_BZERO) AM_CONDITIONAL(NO_EXPLICIT_BZERO, true)) +AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ va_copy(x,y); ]])], + [ ac_cv_have_va_copy="yes" ], + [ ac_cv_have_va_copy="no" + ]) +]) +if test "x$ac_cv_have_va_copy" = "xyes" ; then + AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists]) +fi + +AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +va_list x,y; + ]], [[ __va_copy(x,y); ]])], + [ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no" + ]) +]) +if test "x$ac_cv_have___va_copy" = "xyes" ; then + AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists]) +fi + AC_CHECK_FUNC(getauxval, AC_DEFINE(HAVE_GETAUXVAL)) AC_CHECK_FUNC(funopen, AC_DEFINE(HAVE_FUNOPEN)) diff --git a/crypto/Makefile.am.tpl b/crypto/Makefile.am.tpl index bb30aa2..d203b7b 100644 --- a/crypto/Makefile.am.tpl +++ b/crypto/Makefile.am.tpl @@ -39,7 +39,7 @@ libcompat_la_SOURCES += compat/strnlen.c endif if NO_ASPRINTF -libcompat_la_SOURCES += compat/asprintf.c +libcompat_la_SOURCES += compat/bsd-asprintf.c endif if NO_REALLOCARRAY diff --git a/crypto/compat/asprintf.c b/crypto/compat/asprintf.c deleted file mode 100644 index 45a539d..0000000 --- a/crypto/compat/asprintf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2004 Darren Tucker. - * - * Based originally on asprintf.c from OpenBSD: - * Copyright (c) 1997 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include - -#ifndef VA_COPY -# ifdef HAVE_VA_COPY -# define VA_COPY(dest, src) va_copy(dest, src) -# else -# ifdef HAVE___VA_COPY -# define VA_COPY(dest, src) __va_copy(dest, src) -# else -# define VA_COPY(dest, src) (dest) = (src) -# endif -# endif -#endif - -#define INIT_SZ 128 - -int -vasprintf(char **str, const char *fmt, va_list ap) -{ - int ret = -1; - va_list ap2; - char *string, *newstr; - size_t len; - - VA_COPY(ap2, ap); - if ((string = malloc(INIT_SZ)) == NULL) - goto fail; - - ret = vsnprintf(string, INIT_SZ, fmt, ap2); - if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ - *str = string; - } else if (ret == INT_MAX || ret < 0) { /* Bad length */ - free(string); - goto fail; - } else { /* bigger than initial, realloc allowing for nul */ - len = (size_t)ret + 1; - if ((newstr = realloc(string, len)) == NULL) { - free(string); - goto fail; - } else { - va_end(ap2); - VA_COPY(ap2, ap); - ret = vsnprintf(newstr, len, fmt, ap2); - if (ret >= 0 && (size_t)ret < len) { - *str = newstr; - } else { /* failed with realloc'ed string, give up */ - free(newstr); - goto fail; - } - } - } - va_end(ap2); - return (ret); - -fail: - *str = NULL; - errno = ENOMEM; - va_end(ap2); - return (-1); -} - -int asprintf(char **str, const char *fmt, ...) -{ - va_list ap; - int ret; - - *str = NULL; - va_start(ap, fmt); - ret = vasprintf(str, fmt, ap); - va_end(ap); - - return ret; -} diff --git a/crypto/compat/bsd-asprintf.c b/crypto/compat/bsd-asprintf.c index 3368195..8ccfa22 100644 --- a/crypto/compat/bsd-asprintf.c +++ b/crypto/compat/bsd-asprintf.c @@ -17,12 +17,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "includes.h" - #ifndef HAVE_VASPRINTF #include +#include /* for INT_MAX */ #include +#include /* for vsnprintf */ #include #ifndef VA_COPY @@ -42,16 +42,17 @@ int vasprintf(char **str, const char *fmt, va_list ap) { - int ret = -1; + int ret; va_list ap2; char *string, *newstr; size_t len; - VA_COPY(ap2, ap); if ((string = malloc(INIT_SZ)) == NULL) goto fail; + VA_COPY(ap2, ap); ret = vsnprintf(string, INIT_SZ, fmt, ap2); + va_end(ap2); if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ *str = string; } else if (ret == INT_MAX || ret < 0) { /* Bad length */ @@ -62,25 +63,21 @@ vasprintf(char **str, const char *fmt, va_list ap) if ((newstr = realloc(string, len)) == NULL) { free(string); goto fail; - } else { - va_end(ap2); - VA_COPY(ap2, ap); - ret = vsnprintf(newstr, len, fmt, ap2); - if (ret >= 0 && (size_t)ret < len) { - *str = newstr; - } else { /* failed with realloc'ed string, give up */ - free(newstr); - goto fail; - } } + VA_COPY(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + va_end(ap2); + if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */ + free(newstr); + goto fail; + } + *str = newstr; } - va_end(ap2); return (ret); fail: *str = NULL; errno = ENOMEM; - va_end(ap2); return (-1); } #endif -- cgit v1.2.3-55-g6feb