diff --git a/src/conversion.c b/src/conversion.c index 3df8fe59..6dfabe7e 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -31,6 +31,7 @@ #endif #include #include +#include #include "gpgme.h" #include "util.h" @@ -41,6 +42,61 @@ #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) + +static char * +do_strconcat (const char *s1, va_list arg_ptr) +{ + const char *argv[16]; + size_t argc; + size_t needed; + char *buffer, *p; + + argc = 0; + argv[argc++] = s1; + needed = strlen (s1); + while (((argv[argc] = va_arg (arg_ptr, const char *)))) + { + needed += strlen (argv[argc]); + if (argc >= DIM (argv)-1) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + argc++; + } + needed++; + buffer = malloc (needed); + if (buffer) + { + for (p = buffer, argc=0; argv[argc]; argc++) + p = stpcpy (p, argv[argc]); + } + return buffer; +} + + +/* Concatenate the string S1 with all the following strings up to a + * NULL. Returns a malloced buffer with the new string or NULL on a + malloc error or if too many arguments are given. */ +char * +_gpgme_strconcat (const char *s1, ...) +{ + va_list arg_ptr; + char *result; + + if (!s1) + result = strdup (""); + else + { + va_start (arg_ptr, s1); + result = do_strconcat (s1, arg_ptr); + va_end (arg_ptr); + } + return result; +} + + + /* Convert two hexadecimal digits from STR to the value they represent. Returns -1 if one of the characters is not a diff --git a/src/util.h b/src/util.h index 88e77508..1474b411 100644 --- a/src/util.h +++ b/src/util.h @@ -49,6 +49,10 @@ # define GPG_ERR_FALSE 256 #endif +#ifndef GPGRT_ATTR_SENTINEL +# define GPGRT_ATTR_SENTINEL(a) /* */ +#endif + /*-- {posix,w32}-util.c --*/ @@ -102,6 +106,12 @@ int _gpgme_ttyname_r (int fd, char *buf, size_t buflen); /*-- conversion.c --*/ + +/* Concatenate the string S1 with all the following strings up to a + NULL. Returns a malloced buffer with the new string or NULL on a + malloc error or if too many arguments are given. */ +char *_gpgme_strconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0); + /* Convert two hexadecimal digits from STR to the value they represent. Returns -1 if one of the characters is not a hexadecimal digit. */ diff --git a/src/w32-util.c b/src/w32-util.c index 0086fe39..edac750e 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -388,11 +388,10 @@ find_program_in_dir (const char *dir, const char *name) { char *result; - result = malloc (strlen (dir) + 1 + strlen (name) + 1); + result = _gpgme_strconcat (dir, "\\", strlen (name), NULL); if (!result) return NULL; - strcpy (stpcpy (stpcpy (result, dir), "\\"), name); if (access (result, F_OK)) { free (result); @@ -417,15 +416,11 @@ find_program_at_standard_place (const char *name) if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0) || SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0)) { - result = malloc (strlen (path) + 1 + strlen (name) + 1); - if (result) + result = _gpgme_strconcat (path, "\\", name, NULL); + if (result && access (result, F_OK)) { - strcpy (stpcpy (stpcpy (result, path), "\\"), name); - if (access (result, F_OK)) - { - free (result); - result = NULL; - } + free (result); + result = NULL; } } return result; @@ -439,12 +434,9 @@ _gpgme_set_default_gpg_name (const char *name) { if (!default_gpg_name) { - default_gpg_name = malloc (strlen (name) + 5); + default_gpg_name = _gpgme_strconcat (name, ".exe", NULL); if (default_gpg_name) - { - strcpy (stpcpy (default_gpg_name, name), ".exe"); - replace_slashes (default_gpg_name); - } + replace_slashes (default_gpg_name); } return !default_gpg_name; } @@ -456,12 +448,9 @@ _gpgme_set_default_gpgconf_name (const char *name) { if (!default_gpgconf_name) { - default_gpgconf_name = malloc (strlen (name) + 5); + default_gpgconf_name = _gpgme_strconcat (name, ".exe", NULL); if (default_gpgconf_name) - { - strcpy (stpcpy (default_gpgconf_name, name), ".exe"); - replace_slashes (default_gpgconf_name); - } + replace_slashes (default_gpgconf_name); } return !default_gpgconf_name; } @@ -474,10 +463,9 @@ _gpgme_set_override_inst_dir (const char *dir) { if (!override_inst_dir) { - override_inst_dir = malloc (strlen (dir) + 1); + override_inst_dir = strdup (dir); if (override_inst_dir) { - strcpy (override_inst_dir, dir); replace_slashes (override_inst_dir); /* Remove a trailing slash. */ if (*override_inst_dir @@ -762,10 +750,9 @@ _gpgme_mkstemp (int *fd, char **name) } } - tmpname = malloc (strlen (tmp) + 13 + 1); + tmpname = _gpgme_strconcat (tmp, "\\gpgme-XXXXXX", NULL); if (!tmpname) return -1; - strcpy (stpcpy (tmpname, tmp), "\\gpgme-XXXXXX"); *fd = my_mkstemp (tmpname); if (fd < 0) {