diff options
Diffstat (limited to 'xlsatoms.c')
-rw-r--r-- | xlsatoms.c | 51 |
1 files changed, 41 insertions, 10 deletions
@@ -31,6 +31,7 @@ in this Software without prior written authorization from The Open Group. # include "config.h" #endif +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -45,10 +46,10 @@ static const char *ProgramName; static const char *DisplayString; static void do_name ( xcb_connection_t *c, const char *format, char *name ); -static int parse_range ( char *range, long *lowp, long *highp ); +static int parse_range ( char *range, xcb_atom_t *lowp, xcb_atom_t *highp ); static void do_range ( xcb_connection_t *c, const char *format, char *range ); static void list_atoms ( xcb_connection_t *c, const char *format, int mask, - long low, long high ); + xcb_atom_t low, xcb_atom_t high ); static void usage(const char *errmsg) @@ -161,8 +162,23 @@ do_name(xcb_connection_t *c, const char *format, char *name) #define RangeLow (1 << 0) #define RangeHigh (1 << 1) +static int +strtoatom(char *s, xcb_atom_t *atom) +{ + long long value; + char *end; + + value = strtoll(s, &end, 10); + if (s == end || *end != '\0' || value < 0 || value > UINT32_MAX) { + return 1; + } + + *atom = value; + return 0; +} + static int -parse_range(char *range, long *lowp, long *highp) +parse_range(char *range, xcb_atom_t *lowp, xcb_atom_t *highp) { char *dash; int mask = 0; @@ -179,35 +195,46 @@ parse_range(char *range, long *lowp, long *highp) *lowp = 1; } else { /* low-[high] */ *dash = '\0'; - *lowp = atoi (range); + if (strtoatom(range, lowp)) { + *dash = '-'; + goto invalid; + } *dash = '-'; } mask |= RangeLow; dash++; if (*dash) { /* [low]-high */ - *highp = atoi (dash); + if (strtoatom(dash, highp) || *highp < *lowp) { + goto invalid; + } mask |= RangeHigh; } } else { /* number (low == high) */ - *lowp = *highp = atoi (range); + if (strtoatom(range, lowp)) { + goto invalid; + } + *highp = *lowp; mask |= (RangeLow | RangeHigh); } return mask; +invalid: + fprintf(stderr, "%s: invalid range: %s\n", ProgramName, range); + exit(1); } static void do_range(xcb_connection_t *c, const char *format, char *range) { int mask; - long low, high; + xcb_atom_t low, high; mask = parse_range (range, &low, &high); list_atoms (c, format, mask, low, high); } static int -say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, long low, long count) +say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, xcb_atom_t low, long count) { xcb_generic_error_t *e; char atom_name[1024]; @@ -240,7 +267,7 @@ say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *c } static void -list_atoms(xcb_connection_t *c, const char *format, int mask, long low, long high) +list_atoms(xcb_connection_t *c, const char *format, int mask, xcb_atom_t low, xcb_atom_t high) { xcb_get_atom_name_cookie_t *cookie_jar; int done = 0; @@ -250,9 +277,13 @@ list_atoms(xcb_connection_t *c, const char *format, int mask, long low, long hig low = 1; /* fall through */ case (RangeLow | RangeHigh): + if (high - low >= SIZE_MAX / sizeof(xcb_get_atom_name_cookie_t)) { + fprintf(stderr, "Cannot allocate space for %lu atom requests\n", (unsigned long) (high - low)); + return; + } cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); if (!cookie_jar) { - fprintf(stderr, "Out of memory allocating space for %ld atom requests\n", high - low); + fprintf(stderr, "Out of memory allocating space for %lu atom requests\n", (unsigned long) (high - low)); return; } |