[Xfce4-commits] <exo:master> Fix exo_strndupv.

Nick Schermer nick at xfce.org
Tue Aug 18 22:38:01 CEST 2009


Updating branch refs/heads/master
         to 10d04c4d5bbd1a6a62a5aea2745e3f13dab00400 (commit)
       from 49d214266478cdec15761d7fcb18e3e48138c907 (commit)

commit 10d04c4d5bbd1a6a62a5aea2745e3f13dab00400
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Aug 18 22:33:45 2009 +0200

    Fix exo_strndupv.
    
    Previous implemenation segfaulted and could overflow if
    @num was larger then the number of items in @strv.
    
    Also did a slight API break, making @num an unsigned int.

 exo/exo-string.c |   31 +++++++++++++++++++------------
 exo/exo-string.h |    2 +-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/exo/exo-string.c b/exo/exo-string.c
index 2f90b73..1ab9818 100644
--- a/exo/exo-string.c
+++ b/exo/exo-string.c
@@ -356,29 +356,36 @@ exo_strdup_strftime (const gchar     *format,
 /**
  * exo_strndupv:
  * @strv  : String vector to duplicate.
- * @num   : Number of strings in @strv to
- *          duplicate.
+ * @num   : Number of strings in @strv to duplicate.
  *
- * Creates a new string vector containing the
- * first @n elements of @strv.
+ * Creates a new string vector containing the first @n elements
+ * of @strv. If called on a %NULL value or @num is 0, exo_strndupv()
+ * simply returns %NULL.
  *
- * Return value: The new string vector. Should be
- *               freed using g_strfreev() when no
+ * Return value: A new NULL-terminated array of strings or %NULL.
+ *               Should be freed using g_strfreev() when no
  *               longer needed.
  **/
 gchar**
 exo_strndupv (gchar **strv,
-              gint    num)
+              guint   num)
 {
   gchar **result;
+  guint   i;
 
-  g_return_val_if_fail (strv != NULL, NULL);
-  g_return_val_if_fail (num >= 0, NULL);
+  /* return null when there is nothing to copy */
+  if (G_UNLIKELY (strv == NULL || num == 0))
+    return NULL;
 
+  /* duplicate the first @num string */
   result = g_new (gchar *, num + 1);
-  result[num--] = NULL;
-  for (; num >= 0; --num)
-    result[num] = g_strdup (strv[num]);
+  for (i = 0; strv[i] != NULL && i < num; i++)
+    result[i] = g_strdup (strv[i]);
+  result[i] = NULL;
+
+  /* resize the string if we allocated too much space */
+  if (G_UNLIKELY (num > i))
+    result = g_renew (gchar *, result, i + 1);
 
   return result;
 }
diff --git a/exo/exo-string.h b/exo/exo-string.h
index 40a7689..1ac075a 100644
--- a/exo/exo-string.h
+++ b/exo/exo-string.h
@@ -44,7 +44,7 @@ gchar                *exo_strdup_strftime        (const gchar     *format,
                                                   const struct tm *tm) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 gchar               **exo_strndupv               (gchar          **strv,
-                                                  gint             num) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+                                                  guint            num) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 
 #define I_(string) (g_intern_static_string ((string)))
 



More information about the Xfce4-commits mailing list