[PATCH:mkcomposecache] Replace manual calculations of memory allocations with asprintf calls

Alan Coopersmith alan.coopersmith at oracle.com
Tue Feb 18 22:23:29 PST 2014


Includes fallback asprintf() for pre-Unix08 platforms

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 configure.ac     |    7 +++++-
 mkcomposecache.c |   66 +++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 727f100..aff0a49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,6 +8,11 @@ AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
 
+# Set common system defines for POSIX extensions, such as _GNU_SOURCE
+# Must be called before any macros that run the compiler (like those in
+# XORG_DEFAULT_OPTIONS) to avoid autoconf errors.
+AC_USE_SYSTEM_EXTENSIONS
+
 # Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
 m4_ifndef([XORG_MACROS_VERSION],
           [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
@@ -18,7 +23,7 @@ PKG_CHECK_MODULES(XLIB, x11)
 
 AC_CHECK_HEADERS([stdio.h stdlib.h string.h unistd.h locale.h], , [AC_MSG_FAILURE("cannot find essential header")])
 AC_CHECK_FUNCS([setlocale], , [AC_MSG_FAILURE("cannot find essential function")])
-AC_CHECK_FUNCS([unsetenv])
+AC_CHECK_FUNCS([unsetenv asprintf])
 
 AC_CONFIG_FILES([
 	Makefile
diff --git a/mkcomposecache.c b/mkcomposecache.c
index c65951c..3b94e77 100644
--- a/mkcomposecache.c
+++ b/mkcomposecache.c
@@ -27,11 +27,55 @@
 #include <unistd.h>
 #include <locale.h>
 
+#ifndef HAVE_ASPRINTF
+#include <stdarg.h>
+
+/* sprintf variant found in newer libc's which allocates string to print to */
+static int _X_ATTRIBUTE_PRINTF(2,3)
+asprintf(char ** ret, const char *format, ...)
+{
+    char buf[256];
+    int len;
+    va_list ap;
+
+    va_start(ap, format);
+    len = vsnprintf(buf, sizeof(buf), format, ap);
+    va_end(ap);
+
+    if (len < 0)
+	return -1;
+
+    if (len < sizeof(buf))
+    {
+	*ret = strdup(buf);
+    }
+    else
+    {
+	*ret = malloc(len + 1); /* vsnprintf doesn't count trailing '\0' */
+	if (*ret != NULL)
+	{
+	    va_start(ap, format);
+	    len = vsnprintf(*ret, len + 1, format, ap);
+	    va_end(ap);
+	    if (len < 0) {
+		free(*ret);
+		*ret = NULL;
+	    }
+	}
+    }
+
+    if (*ret == NULL)
+	return -1;
+
+    return len;
+}
+#endif /* HAVE_ASPRINTF */
+
 int main (int argc, char *argv[]) {
     Display *disp;
     XIM      im;
     char    *src, *dest;
-    int      len;
+    int      ret;
 
     if (argc != 4 && argc != 5) {
 	fprintf (stderr, "Usage: %s <Locale> <ComposeFile> <CacheDir> [<InternalName>]\n", argv[0]);
@@ -53,20 +97,20 @@ int main (int argc, char *argv[]) {
 	return 1;
     }
 
-    src  = malloc (strlen (argv[2]) + 14);
-    len  = strlen (argv[3]) + 15;
-    if (argc == 5)
-	len += strlen (argv[4]) + 1;
-    dest = malloc (len);
-    if (! src || ! dest) {
-	perror ("* malloc");
+    if (asprintf (&src, "XCOMPOSEFILE=%s", argv[2]) == -1) {
+	perror ("* asprintf");
 	return 1;
     }
-    sprintf (src,  "XCOMPOSEFILE=%s", argv[2]);
+
     if (argc == 4)
-        sprintf (dest, "XCOMPOSECACHE=%s", argv[3]);
+	ret = asprintf (&dest, "XCOMPOSECACHE=%s", argv[3]);
     else
-        sprintf (dest, "XCOMPOSECACHE=%s=%s", argv[3], argv[4]);
+	ret = asprintf (&dest, "XCOMPOSECACHE=%s=%s", argv[3], argv[4]);
+    if (ret == -1) {
+	perror ("* asprintf");
+	return 1;
+    }
+
     putenv  (src);
     putenv  (dest);
 #if HAVE_UNSETENV
-- 
1.7.9.2



More information about the xorg-devel mailing list