]> git.ipfire.org Git - pakfire.git/commitdiff
util: Refactor unhexlify without using scanf
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 13:41:36 +0000 (13:41 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 13:41:36 +0000 (13:41 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/util.c

index 3584f58e0f2525ad1b2113f13fd780762d982a44..5c18f02eaf91552f1d2e9ba8c27e21b1550466fe 100644 (file)
@@ -639,15 +639,44 @@ char* __pakfire_hexlify(const char* digest, const size_t length) {
        return s;
 }
 
+static int parse_nibble(char nibble) {
+       // Handle digits
+       if (nibble >= '0' && nibble <= '9')
+               return nibble - '0';
+
+       // Handle lowercase letters
+       if (nibble >= 'a' && nibble <= 'f')
+               return 10 + nibble - 'a';
+
+       // Handle uppercase letters
+       if (nibble >= 'A' && nibble <= 'F')
+               return 10 + nibble - 'A';
+
+       // Error
+       return -1;
+}
+
 int __pakfire_unhexlify(unsigned char* dst, const size_t l, const char* src) {
-       const char* p = src;
+       if (!src) {
+               errno = EINVAL;
+               return 1;
+       }
 
-       for (unsigned int i = 0; i < l && *p; i++) {
-               int r = sscanf(p, "%02X", (unsigned int*)&dst[i]);
-               if (r != 1)
+       // Determine input length
+       const size_t length = strlen(src);
+
+       for (unsigned int i = 0, j = 0; i < length && j < l; i += 2, j++) {
+               int h = parse_nibble(src[i]);
+               int l = parse_nibble(src[i+1]);
+
+               // Check for invalid input
+               if (h < 0 || l < 0) {
+                       errno = EINVAL;
                        return 1;
+               }
 
-               p += 2;
+               // Store result
+               dst[j] = h << 4 | l;
        }
 
        return 0;