Introduce rstrscat()
authorJindrich Novy <jnovy@redhat.com>
Thu, 17 Apr 2008 06:57:43 +0000 (08:57 +0200)
committerJindrich Novy <jnovy@redhat.com>
Thu, 17 Apr 2008 06:57:43 +0000 (08:57 +0200)
- concatenates NULL terminated strings to newly (re)allocated memory
- purpose is to prevent overflows caused by writing unknown-sized stuff
to static arrays

rpmio/rpmstring.c
rpmio/rpmstring.h

index 885bf4b..8b1cd78 100644 (file)
@@ -208,7 +208,7 @@ int rasprintf(char **strp, const char *fmt, ...)
 }
 
 /*
- * Concatenate strings with dynamically (re)allocated
+ * Concatenate two strings with dynamically (re)allocated
  * memory what prevents static buffer overflows by design.
  * *dest is reallocated to the size of strings to concatenate.
  *
@@ -239,3 +239,52 @@ char *rstrcat(char **dest, const char *src)
     return *dest;
 }
 
+/*
+ * Concatenate strings with dynamically (re)allocated
+ * memory what prevents static buffer overflows by design.
+ * *dest is reallocated to the size of strings to concatenate.
+ * List of strings has to be NULL terminated.
+ *
+ * Note:
+ * 1) char *buf = rstrscat(NULL,"string",NULL); is the same like rstrscat(&buf,"string",NULL);
+ * 2) rstrscat(&buf,NULL) returns buf
+ * 3) rstrscat(NULL,NULL) returns NULL
+ * 4) *dest and argument strings can overlap
+ */
+char *rstrscat(char **dest, const char *arg, ...)
+{
+    va_list ap;
+    size_t arg_size, dst_size;
+    const char *s;
+    char *dst, *p;
+
+    dst = dest ? *dest : NULL;
+
+    if ( arg == NULL ) {
+        return dst;
+    }
+
+    va_start(ap, arg);
+    for (arg_size=0, s=arg; s; s = va_arg(ap, const char *))
+        arg_size += strlen(s);
+    va_end(ap);
+
+    dst_size = dst ? strlen(dst) : 0;
+    dst = realloc(dst, dst_size+arg_size+1);    /* include '\0' */
+    p = &dst[dst_size];
+
+    va_start(ap, arg);
+    for (s = arg; s; s = va_arg(ap, const char *)) {
+        size_t size = strlen(s);
+        memmove(p, s, size);
+        p += size;
+    }
+    *p = '\0';
+
+    if ( dest ) {
+        *dest = dst;
+    }
+
+    return dst;
+}
+
index d3f5953..1947da2 100644 (file)
@@ -109,7 +109,7 @@ int rstrncasecmp(const char *s1, const char * s2, size_t n) ;
 int rasprintf(char **strp, const char *fmt, ...) RPM_GNUC_PRINTF(2, 3);
 
 /** \ingroup rpmstring
- * Concatenate strings with dynamically (re)allocated memory.
+ * Concatenate two strings with dynamically (re)allocated memory.
  * @param dest         pointer to destination string
  * @param src          source string
  * @return             realloc'd dest with src appended
@@ -117,6 +117,14 @@ int rasprintf(char **strp, const char *fmt, ...) RPM_GNUC_PRINTF(2, 3);
 char *rstrcat(char **dest, const char *src);
 
 /** \ingroup rpmstring
+ * Concatenate multiple strings with dynamically (re)allocated memory.
+ * @param dest         pointer to destination string
+ * @param arg          NULL terminated list of strings to concatenate
+ * @return             realloc'd dest with strings appended
+ */
+char *rstrscat(char **dest, const char *arg, ...);
+
+/** \ingroup rpmstring
  * Split string into fields separated by a character.
  * @param str          string
  * @param length       length of string