diff options
author | Jamey Sharp <jamey@minilop.net> | 2005-12-12 23:40:47 +0000 |
---|---|---|
committer | Jamey Sharp <jamey@minilop.net> | 2005-12-12 23:40:47 +0000 |
commit | 4378513ba0f21fe7e67c75e285ce988253a6f09e (patch) | |
tree | bb3ef8945b27734d940b772d5ee92f5be5beaa4e | |
parent | 8609adb635a1560d9220de4ed3f7b81b7c058981 (diff) |
Rewrite XCBParseDisplay to handle all error cases correctly. Thanks to
Travis Spencer for pointing out a problem with the previous sscanf
call; turns out that sscanf won't do what I want anyway, so this
version just uses strtoul.
-rw-r--r-- | xcb/ChangeLog | 8 | ||||
-rw-r--r-- | xcb/src/xcb_util.c | 48 |
2 files changed, 39 insertions, 17 deletions
diff --git a/xcb/ChangeLog b/xcb/ChangeLog index d2cdefc..db531fb 100644 --- a/xcb/ChangeLog +++ b/xcb/ChangeLog @@ -1,5 +1,13 @@ 2005-12-12 Jamey Sharp <jamey@minilop.net> + * src/xcb_util.c: + Rewrite XCBParseDisplay to handle all error cases correctly. + Thanks to Travis Spencer for pointing out a problem with + the previous sscanf call; turns out that sscanf won't do what + I want anyway, so this version just uses strtoul. + +2005-12-12 Jamey Sharp <jamey@minilop.net> + * tests/check_public.c: Fix segfault in fail_unless calls and provide more useful error messages. Also remove DISPLAY from the environment and test diff --git a/xcb/src/xcb_util.c b/xcb/src/xcb_util.c index 07201ef..661a2c3 100644 --- a/xcb/src/xcb_util.c +++ b/xcb/src/xcb_util.c @@ -49,31 +49,45 @@ int XCBPopcount(CARD32 mask) return ((y + (y >> 3)) & 030707070707) % 077; } -int XCBParseDisplay(const char *name, char **host, int *display, int *screen) +int XCBParseDisplay(const char *name, char **host, int *displayp, int *screenp) { - char *colon; - int dummy_screen; - if(!screen) - screen = &dummy_screen; - *screen = *display = 0; + int len, display, screen; + char *colon, *dot, *end; if(!name || !*name) name = getenv("DISPLAY"); if(!name) return 0; - *host = malloc(strlen(name) + 1); - if(!*host) - return 0; - strcpy(*host, name); - colon = strchr(*host, ':'); + colon = strrchr(name, ':'); if(!colon) - { - free(*host); - *host = 0; return 0; - } - *colon = '\0'; + len = colon - name; ++colon; - return sscanf(colon, "%d.%d", display, screen); + display = strtoul(colon, &dot, 10); + if(dot == colon) + return 0; + if(*dot == '\0') + screen = 0; + else + { + if(*dot != '.') + return 0; + ++dot; + screen = strtoul(dot, &end, 10); + if(end == dot || *end != '\0') + return 0; + } + /* At this point, the display string is fully parsed and valid, but + * the caller's memory is untouched. */ + + *host = malloc(len + 1); + if(!*host) + return 0; + memcpy(*host, name, len); + (*host)[len] = '\0'; + *displayp = display; + if(screenp) + *screenp = screen; + return 1; } int XCBOpen(const char *host, const int display) |