file_util.c: refactor and fix checksum_hex2bin()
authorJo-Philipp Wich <jo@mein.io>
Wed, 1 Apr 2020 11:41:37 +0000 (13:41 +0200)
committerJo-Philipp Wich <jo@mein.io>
Wed, 1 Apr 2020 11:41:37 +0000 (13:41 +0200)
 - Simplify function body by reducing the amount of intermediate vars
 - Derive length checks from the size of the buf
 - Replace complex for(;;) by a simple while() advancing the src string
 - Handle edge case of a zero length input not returning NULL

Fixes: c09fe20 ("libopkg: fix skipping of leading whitespace when parsing checksums")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
libopkg/file_util.c

index c0acec3f8f6abaeb4a69507559a28406ba129f82..3a1761eea76d331e15d8327bfb20ca8f86e52d92 100644 (file)
@@ -230,32 +230,30 @@ char *checksum_bin2hex(const char *src, size_t len)
 
 char *checksum_hex2bin(const char *src, size_t *len)
 {
-       size_t slen;
-       unsigned char *p;
-       const unsigned char *s;
        static unsigned char buf[32];
+       size_t n = 0;
+
+       *len = 0;
 
-       if (!src) {
-               *len = 0;
+       if (!src)
                return NULL;
-       }
 
        while (isspace(*src))
                src++;
 
-       slen = strlen(src);
-
-       if (slen > 64) {
-               *len = 0;
+       if (strlen(src) > sizeof(buf) * 2)
                return NULL;
-       }
 
-       for (s = (unsigned char *)src, p = buf, *len = 0;
-            slen > 0 && isxdigit(s[0]) && isxdigit(s[1]);
-            slen--, s += 2, (*len)++)
-               *p++ = hex2bin(s[0]) * 16 + hex2bin(s[1]);
+       while (*src) {
+               if (n >= sizeof(buf) || !isxdigit(src[0]) || !isxdigit(src[1]))
+                       return NULL;
 
-       return (char *)buf;
+               buf[n++] = hex2bin(src[0]) * 16 + hex2bin(src[1]);
+               src += 2;
+       }
+
+       *len = n;
+       return n ? (char *)buf : NULL;
 }
 
 int rm_r(const char *path)