Add xasprintf to avoid use of undefined pointer values
authorJon A. Cruz <jonc@osg.samsung.com>
Fri, 29 May 2015 02:01:01 +0000 (19:01 -0700)
committerPeter Hutterer <peter.hutterer@who-t.net>
Sun, 31 May 2015 22:47:14 +0000 (08:47 +1000)
If asprintf fails for any reason, the contents of the pointer
are undefined. While some platforms set it to NULL, there is no
guarantee that all will.

This change adds a simple wrapper to ensure proper NULL results
on failure.

Signed-off-by: Jon A. Cruz <jonc@osg.samsung.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Added LIBINPUT_PRINTF attribute and the required declaration for it.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/libinput-util.h
test/litest.c
tools/libinput-list-devices.c

index 732f813008101f4730b471166218f9b85289c54c..910406cfef7597ca4c881fe3c90ef3e91cf1ffc3 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <unistd.h>
 #include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 
@@ -230,6 +232,38 @@ matrix_to_farray6(const struct matrix *m, float out[6])
        out[5] = m->val[1][2];
 }
 
+/**
+ * Simple wrapper for asprintf that ensures the passed in-pointer is set
+ * to NULL upon error.
+ * The standard asprintf() call does not guarantee the passed in pointer
+ * will be NULL'ed upon failure, whereas this wrapper does.
+ *
+ * @param strp pointer to set to newly allocated string.
+ * This pointer should be passed to free() to release when done.
+ * @param fmt the format string to use for printing.
+ * @return The number of bytes printed (excluding the null byte terminator)
+ * upon success or -1 upon failure. In the case of failure the pointer is set
+ * to NULL.
+ */
+static inline int
+xasprintf(char **strp, const char *fmt, ...)
+       LIBINPUT_ATTRIBUTE_PRINTF(2, 3);
+
+static inline int
+xasprintf(char **strp, const char *fmt, ...)
+{
+       int rc = 0;
+       va_list args;
+
+       va_start(args, fmt);
+       rc = vasprintf(strp, fmt, args);
+       va_end(args);
+       if ((rc == -1) && strp)
+               *strp = NULL;
+
+       return rc;
+}
+
 enum ratelimit_state {
        RATELIMIT_EXCEEDED,
        RATELIMIT_THRESHOLD,
index 349eca08411653c01d3b9f80b4d0f124446a166f..30d305669984de41003efbfe3f0d8baaa1df5c44 100644 (file)
@@ -876,7 +876,7 @@ litest_init_udev_rules(struct litest_test_device *dev)
                ck_abort_msg("Failed to create udev rules directory (%s)\n",
                             strerror(errno));
 
-       rc = asprintf(&path,
+       rc = xasprintf(&path,
                      "%s/%s%s.rules",
                      UDEV_RULES_D,
                      UDEV_RULE_PREFIX,
index 662517312bf980ff770c86f1868f8c390f521b34..68ddb612eedc59ba359ebd132eac90c555f346eb 100644 (file)
@@ -120,17 +120,17 @@ calibration_default(struct libinput_device *device)
        float calibration[6];
 
        if (!libinput_device_config_calibration_has_matrix(device)) {
-               asprintf(&str, "n/a");
+               xasprintf(&str, "n/a");
                return str;
        }
 
        if (libinput_device_config_calibration_get_default_matrix(device,
                                                  calibration) == 0) {
-               asprintf(&str, "identity matrix");
+               xasprintf(&str, "identity matrix");
                return str;
        }
 
-       asprintf(&str,
+       xasprintf(&str,
                 "%.2f %.2f %.2f %.2f %.2f %.2f",
                 calibration[0],
                 calibration[1],
@@ -150,13 +150,13 @@ scroll_defaults(struct libinput_device *device)
 
        scroll_methods = libinput_device_config_scroll_get_methods(device);
        if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL) {
-               asprintf(&str, "none");
+               xasprintf(&str, "none");
                return str;
        }
 
        method = libinput_device_config_scroll_get_default_method(device);
 
-       asprintf(&str,
+       xasprintf(&str,
                 "%s%s%s%s%s%s",
                 (method == LIBINPUT_CONFIG_SCROLL_2FG) ? "*" : "",
                 (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG) ? "two-finger " : "",
@@ -176,12 +176,12 @@ click_defaults(struct libinput_device *device)
 
        click_methods = libinput_device_config_click_get_methods(device);
        if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE) {
-               asprintf(&str, "none");
+               xasprintf(&str, "none");
                return str;
        }
 
        method = libinput_device_config_click_get_default_method(device);
-       asprintf(&str,
+       xasprintf(&str,
                 "%s%s%s%s",
                 (method == LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "*" : "",
                 (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) ? "button-areas " : "",