<div dir="ltr">Can I also suggest that we don't make this public API? These are internal helpers for libwayland, not designed for any consumers. We've been burned by making too much internal helper API public before.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 27, 2014 at 2:42 AM, Marek Chalupa <span dir="ltr"><<a href="mailto:mchqwerty@gmail.com" target="_blank">mchqwerty@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On 22 October 2014 13:32, Imran Zaman <span dir="ltr"><<a href="mailto:imran.zaman@gmail.com" target="_blank">imran.zaman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">strtol/strtoul utility functions are used extensively in<br>
weston/wayland, and are not bug-free in their current form.<br>
To avoid definition in weston and wayland, its wrapped<br>
in functions with appropriate input and output checks.<br>
Test cases are also updated.<br>
<br>
Signed-off-by: Imran Zaman <<a href="mailto:imran.zaman@gmail.com" target="_blank">imran.zaman@gmail.com</a>><br>
---<br>
 src/scanner.c        |   5 +-<br>
 src/wayland-client.c |   5 +-<br>
 src/wayland-util.c   |  55 ++++++++++++++++++++<br>
 src/wayland-util.h   |   4 ++<br>
 tests/fixed-test.c   | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++<br>
 5 files changed, 204 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/src/scanner.c b/src/scanner.c<br>
index 809130b..165b12b 100644<br>
--- a/src/scanner.c<br>
+++ b/src/scanner.c<br>
@@ -315,7 +315,6 @@ start_element(void *data, const char *element_name, const char **atts)<br>
        struct description *description;<br>
        const char *name, *type, *interface_name, *value, *summary, *since;<br>
        const char *allow_null;<br>
-       char *end;<br>
        int i, version;<br>
<br>
        ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);<br>
@@ -404,9 +403,7 @@ start_element(void *data, const char *element_name, const char **atts)<br>
                        message->destructor = 0;<br>
<br>
                if (since != NULL) {<br>
-                       errno = 0;<br>
-                       version = strtol(since, &end, 0);<br>
-                       if (errno == EINVAL || end == since || *end != '\0')<br>
+                       if (!wl_strtol(since, NULL, 0, (long *)&version))<br></blockquote><div><br></div></div></div><div>This is baad. You cannot use the int version here, because in wl_strol you write sizeof(long) on the address<br></div><div>of version and if sizeof(version) is smaller than sizeof(long) then you overwrite memory. I'm getting ugly SIGSEGV<br></div><div>because of that.<br><br></div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                fail(&ctx->loc,<br>
                                     "invalid integer (%s)\n", since);<br>
                } else {<br>
diff --git a/src/wayland-client.c b/src/wayland-client.c<br>
index b0f77b9..fd98705 100644<br>
--- a/src/wayland-client.c<br>
+++ b/src/wayland-client.c<br>
@@ -824,13 +824,12 @@ wl_display_connect_to_fd(int fd)<br>
 WL_EXPORT struct wl_display *<br>
 wl_display_connect(const char *name)<br>
 {<br>
-       char *connection, *end;<br>
+       char *connection;<br>
        int flags, fd;<br>
<br>
        connection = getenv("WAYLAND_SOCKET");<br>
        if (connection) {<br>
-               fd = strtol(connection, &end, 0);<br>
-               if (*end != '\0')<br>
+               if (!wl_strtol(connection, NULL, 0, (long *)&fd))<br>
                        return NULL;<br>
<br>
                flags = fcntl(fd, F_GETFD);<br>
diff --git a/src/wayland-util.c b/src/wayland-util.c<br>
index b099882..a930364 100644<br>
--- a/src/wayland-util.c<br>
+++ b/src/wayland-util.c<br>
@@ -26,6 +26,8 @@<br>
 #include <stdio.h><br>
 #include <string.h><br>
 #include <stdarg.h><br>
+#include <errno.h><br>
+#include <ctype.h><br>
<br>
 #include "wayland-util.h"<br>
 #include "wayland-private.h"<br>
@@ -361,6 +363,59 @@ wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data)<br>
        for_each_helper(&map->server_entries, func, data);<br>
 }<br>
<br>
+WL_EXPORT bool<br>
+wl_strtol(const char *str, char **endptr, int base, long *val)<br>
+{<br>
+       char *end = NULL;<br>
+       long v;<br>
+<br>
+       if (!str || !val)<br>
+               return false;<br>
+       if (!endptr)<br>
+               endptr = &end;<br>
+<br>
+       errno = 0;<br>
+       v = strtol(str, endptr, base);<br>
+       if (errno != 0 || *endptr == str || **endptr != '\0')<br>
+               return false;<br>
+<br>
+       *val = v;<br>
+       return true;<br>
+}<br>
+<br>
+WL_EXPORT bool<br>
+wl_strtoul(const char *str, char **endptr, int base, unsigned long *val)<br>
+{<br>
+       char *end = NULL;<br>
+       unsigned long v;<br>
+       int i = 0;<br>
+<br>
+       if (!str || !val)<br>
+               return false;<br>
+<br>
+       /* check for negative numbers */<br>
+       while (str[i]) {<br>
+               if (!isspace(str[i])) {<br>
+                       if (str[i] == '-')<br>
+                               return false;<br>
+                       else<br>
+                               break;<br>
+               }<br>
+               i++;<br>
+       }<br>
+<br>
+       if (!endptr)<br>
+               endptr = &end;<br>
+<br>
+       errno = 0;<br>
+       v = strtoul(str, endptr, base);<br>
+       if (errno != 0 || *endptr == str || **endptr != '\0')<br>
+               return false;<br>
+<br>
+       *val = v;<br>
+       return true;<br>
+}<br>
+<br>
 static void<br>
 wl_log_stderr_handler(const char *fmt, va_list arg)<br>
 {<br>
diff --git a/src/wayland-util.h b/src/wayland-util.h<br>
index fd32826..c66cc41 100644<br>
--- a/src/wayland-util.h<br>
+++ b/src/wayland-util.h<br>
@@ -36,6 +36,7 @@ extern "C" {<br>
 #include <stddef.h><br>
 #include <inttypes.h><br>
 #include <stdarg.h><br>
+#include <stdbool.h><br>
<br>
 /* GCC visibility */<br>
 #if defined(__GNUC__) && __GNUC__ >= 4<br>
@@ -243,6 +244,9 @@ static inline wl_fixed_t wl_fixed_from_int(int i)<br>
        return i * 256;<br>
 }<br>
<br>
+bool wl_strtol(const char *str, char **endptr, int base, long *val);<br>
+bool wl_strtoul(const char *str, char **endptr, int base, unsigned long *val);<br>
+<br>
 /**<br>
  * \brief A union representing all of the basic data types that can be passed<br>
  * along the wayland wire format.<br>
diff --git a/tests/fixed-test.c b/tests/fixed-test.c<br>
index 739a3b1..ad40467 100644<br>
--- a/tests/fixed-test.c<br>
+++ b/tests/fixed-test.c<br>
@@ -88,3 +88,145 @@ TEST(fixed_int_conversions)<br>
        i = wl_fixed_to_int(f);<br>
        assert(i == -0x50);<br>
 }<br>
+<br>
+TEST(strtol_conversions)<br>
+{<br>
+       bool ret;<br>
+       long val = -1;<br>
+       char *end = NULL, *str = NULL;<br>
+<br>
+       ret = wl_strtol(NULL, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == -1);<br>
+<br>
+       ret = wl_strtol(NULL, NULL, 10, NULL);<br>
+       assert(ret == false);<br>
+<br>
+       str = "12";<br>
+       ret = wl_strtol(str, NULL, 10, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 12);<br>
+<br>
+       ret = wl_strtol(str, &end, 10, &val);<br>
+       assert(end != NULL);<br>
+       assert(*end == '\0');<br>
+<br>
+       str = "-12"; val = -1;<br>
+       ret = wl_strtol(str, &end, 10, &val);<br>
+       assert(ret == true);<br>
+       assert(val == -12);<br>
+<br>
+       str = "0x12"; val = -1;<br>
+       ret = wl_strtol(str, &end, 16, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 0x12);<br>
+<br>
+       str = "A"; val = -1;<br>
+       ret = wl_strtol(str, &end, 16, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 10);<br>
+<br>
+       str = "-0x20"; val = -1;<br>
+       ret = wl_strtol(str, &end, 16, &val);<br>
+       assert(ret == true);<br>
+       assert(val == -0x20);<br>
+<br>
+       str = "0012"; val = -1;<br>
+       ret = wl_strtol(str, &end, 8, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 10);<br>
+<br>
+       str = "0101"; val = -1;<br>
+       ret = wl_strtol(str, &end, 2, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 5);<br>
+<br>
+       str = "s12"; val = -1;<br>
+       ret = wl_strtol(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == -1);<br>
+<br>
+       ret = wl_strtol(str, &end, 10, &val);<br>
+       assert(end == str);<br>
+<br>
+       str = "214748364789L"; val = -1;<br>
+       ret = wl_strtol(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == -1);<br>
+<br>
+       str = ""; val = -1;<br>
+       ret = wl_strtol(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == -1);<br>
+}<br>
+<br>
+TEST(strtoul_conversions)<br>
+{<br>
+       bool ret;<br>
+       unsigned long val = 0;<br>
+       char *end = NULL, *str = NULL;<br>
+<br>
+       ret = wl_strtoul(NULL, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+<br>
+       ret = wl_strtoul(NULL, NULL, 10, NULL);<br>
+       assert(ret == false);<br>
+<br>
+       str = "15";<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 15);<br>
+<br>
+       ret = wl_strtoul(str, &end, 10, &val);<br>
+       assert(end != NULL);<br>
+       assert(*end == '\0');<br>
+<br>
+       str = "0x12"; val = 0;<br>
+       ret = wl_strtoul(str, &end, 16, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 18);<br>
+<br>
+       str = "A"; val = 0;<br>
+       ret = wl_strtoul(str, &end, 16, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 10);<br>
+<br>
+       str = "0012"; val = 0;<br>
+       ret = wl_strtoul(str, &end, 8, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 10);<br>
+<br>
+       str = "0101"; val = 0;<br>
+       ret = wl_strtoul(str, &end, 2, &val);<br>
+       assert(ret == true);<br>
+       assert(val == 5);<br>
+<br>
+       str = "s15"; val = 0;<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+<br>
+       ret = wl_strtoul(str, &end, 10, &val);<br>
+       assert(end == str);<br>
+<br>
+       str = "429496729533UL"; val = 0;<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+<br>
+       str = "-1"; val = 0;<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+<br>
+       str = "    -1234"; val = 0;<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+<br>
+       str = ""; val = 0;<br>
+       ret = wl_strtoul(str, NULL, 10, &val);<br>
+       assert(ret == false);<br>
+       assert(val == 0);<br>
+}<br></blockquote><div><br></div></div></div><div>Maybe the tests are big enough to deserve it's own binary? fixed-tests has nothing in common with wl_strtol.<br>My opinion only..<br></div><span class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><font color="#888888">--<br>
1.9.1<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org" target="_blank">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br></font></span></blockquote><div><br></div></span><div>Cheers,<br></div><div>Marek <br></div></div><br></div></div>
<br>_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>  Jasper<br>
</div>