core: New helper function _gpgme_strconcat.
authorWerner Koch <wk@gnupg.org>
Thu, 22 Sep 2016 10:41:55 +0000 (12:41 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 22 Sep 2016 10:42:10 +0000 (12:42 +0200)
* src/conversion.c: Include stdarg.h.
(do_strconcat): New.
(_gpgme_strconcat): New.
* src/util.h: Provide fallback for GPGRT_ATTR_SENTINEL.
(_gpgme_strconcat): New with sentinel.

* src/w32-util.c (find_program_in_dir): Replace malloc and stpcpy by
_gpgme_strconcat.
(find_program_at_standard_place): Ditto.
(_gpgme_set_default_gpg_name): Ditto.
(_gpgme_set_default_gpgconf_name): Ditto.
(_gpgme_mkstemp): Ditto.
(_gpgme_set_override_inst_dir): Repalce malloc and strcpy by strdup.
--

The function has been taken from gnupg/common/stringhelp.c and license
changed to LPGLv2.1+.  I am the original author of that code.

Signed-off-by: Werner Koch <wk@gnupg.org>
src/conversion.c
src/util.h
src/w32-util.c

index 3df8fe5..6dfabe7 100644 (file)
@@ -31,6 +31,7 @@
 #endif
 #include <time.h>
 #include <errno.h>
+#include <stdarg.h>
 
 #include "gpgme.h"
 #include "util.h"
 
 
 \f
+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;
+}
+
+
+
+\f
 /* Convert two hexadecimal digits from STR to the value they
    represent.  Returns -1 if one of the characters is not a
    hexadecimal digit.  */
index 88e7750..1474b41 100644 (file)
 # define GPG_ERR_FALSE 256
 #endif
 
+#ifndef GPGRT_ATTR_SENTINEL
+# define GPGRT_ATTR_SENTINEL(a)  /* */
+#endif
+
 
 \f
 /*-- {posix,w32}-util.c --*/
@@ -102,6 +106,12 @@ int _gpgme_ttyname_r (int fd, char *buf, size_t buflen);
 
 \f
 /*-- 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.  */
index 0086fe3..edac750 100644 (file)
@@ -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)
     {