diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2018-05-11 14:36:22 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2018-05-11 14:36:22 +0900 |
commit | 4937b81a7b183d3c0e5c15aac5ac0834a3246b8f (patch) | |
tree | a0520ecc4df81826f28c1547300cf549b4f7dd7d /src/basic/hexdecoct.c | |
parent | b6887d7ae470cf6dfa9ba1b33840628362d9d0fc (diff) | |
download | systemd-4937b81a7b183d3c0e5c15aac5ac0834a3246b8f.tar.gz |
hexdecoct: ignore whitespace within the input hexadecimal text of unhexmem()
Diffstat (limited to 'src/basic/hexdecoct.c')
-rw-r--r-- | src/basic/hexdecoct.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 7ab5c5f70b..1c1949f1f0 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -77,33 +77,69 @@ char *hexmem(const void *p, size_t l) { return r; } -int unhexmem(const char *p, size_t l, void **mem, size_t *len) { - _cleanup_free_ uint8_t *r = NULL; - uint8_t *z; +static int unhex_next(const char **p, size_t *l) { + int r; + + assert(p); + assert(l); + + /* Find the next non-whitespace character, and decode it. We + * greedily skip all preceeding and all following whitespace. */ + + for (;;) { + if (*l == 0) + return -EPIPE; + + if (!strchr(WHITESPACE, **p)) + break; + + /* Skip leading whitespace */ + (*p)++, (*l)--; + } + + r = unhexchar(**p); + if (r < 0) + return r; + + for (;;) { + (*p)++, (*l)--; + + if (*l == 0 || !strchr(WHITESPACE, **p)) + break; + + /* Skip following whitespace */ + } + + return r; +} + +int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) { + _cleanup_free_ uint8_t *buf = NULL; const char *x; + uint8_t *z; - assert(mem); - assert(len); + assert(ret); + assert(ret_len); assert(p || l == 0); if (l == (size_t) -1) l = strlen(p); - if (l % 2 != 0) - return -EINVAL; - - z = r = malloc((l + 1) / 2 + 1); - if (!r) + /* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */ + buf = malloc((l + 1) / 2 + 1); + if (!buf) return -ENOMEM; - for (x = p; x < p + l; x += 2) { + for (x = p, z = buf;;) { int a, b; - a = unhexchar(x[0]); + a = unhex_next(&x, &l); + if (a == -EPIPE) /* End of string */ + break; if (a < 0) return a; - b = unhexchar(x[1]); + b = unhex_next(&x, &l); if (b < 0) return b; @@ -112,8 +148,8 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) { *z = 0; - *mem = TAKE_PTR(r); - *len = (l + 1) / 2; + *ret_len = (size_t) (z - buf); + *ret = TAKE_PTR(buf); return 0; } |