libopkg: fix hex encoding/decoding, add checksum getter/setter
authorJo-Philipp Wich <jo@mein.io>
Mon, 13 Feb 2017 17:07:04 +0000 (18:07 +0100)
committerJo-Philipp Wich <jo@mein.io>
Thu, 16 Feb 2017 16:00:40 +0000 (17:00 +0100)
Fix broken hex encoding/decoding due to the use of signed chars and introduce
new convenience getters and setters to simplify the checksum usage.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
libopkg/file_util.c
libopkg/opkg_install.c
libopkg/pkg.c
libopkg/pkg.h
libopkg/pkg_parse.c

index 912b147ad306766f6275e93a3b9860de81b29242..155d73b52be1ac81d88ebfd851c50c98ede6f012 100644 (file)
@@ -231,8 +231,9 @@ char *file_sha256sum_alloc(const char *file_name)
 
 char *checksum_bin2hex(const char *src, size_t len)
 {
-       char *p;
-       static char buf[65];
+       unsigned char *p;
+       static unsigned char buf[65];
+       const unsigned char *s = (unsigned char *)src;
        static const unsigned char bin2hex[16] = {
                '0', '1', '2', '3',
                '4', '5', '6', '7',
@@ -243,21 +244,22 @@ char *checksum_bin2hex(const char *src, size_t len)
        if (len > 32)
                return NULL;
 
-       for (p = buf; len > 0; src++, len--) {
-               *p++ = bin2hex[*src / 16];
-               *p++ = bin2hex[*src % 16];
+       for (p = buf; len > 0; s++, len--) {
+               *p++ = bin2hex[*s / 16];
+               *p++ = bin2hex[*s % 16];
        }
 
        *p = 0;
 
-       return buf;
+       return (char *)buf;
 }
 
 char *checksum_hex2bin(const char *src, size_t *len)
 {
-       char *p;
        size_t slen;
-       static char buf[32];
+       unsigned char *p;
+       const unsigned char *s = (unsigned char *)src;
+       static unsigned char buf[32];
 
        while (isspace(*src))
                src++;
@@ -273,11 +275,11 @@ char *checksum_hex2bin(const char *src, size_t *len)
        (c >= 'a' ? (c - 'a') : (c >= 'A' ? (c - 'A') : (c - '0')))
 
        for (p = buf, *len = 0;
-            slen > 0 && isxdigit(src[0]) && isxdigit(src[1]);
-            slen--, src += 2, (*len)++)
-               *p++ = hex(src[0]) * 16 + hex(src[1]);
+            slen > 0 && isxdigit(s[0]) && isxdigit(s[1]);
+            slen--, s += 2, (*len)++)
+               *p++ = hex(s[0]) * 16 + hex(s[1]);
 
-       return buf;
+       return (char *)buf;
 }
 
 int rm_r(const char *path)
index 85159bf207a15cb0e7bc7a883528bf2cb365c4dd..6752e078484051357200ad4e9a18dd45472319f9 100644 (file)
@@ -1388,7 +1388,7 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade)
 
 #ifdef HAVE_MD5
        /* Check for md5 values */
-       pkg_md5 = pkg_get_string(pkg, PKG_MD5SUM);
+       pkg_md5 = pkg_get_md5(pkg);
        if (pkg_md5) {
                file_md5 = file_md5sum_alloc(local_filename);
                if (file_md5 && strcmp(file_md5, pkg_md5)) {
@@ -1411,7 +1411,7 @@ int opkg_install_pkg(pkg_t * pkg, int from_upgrade)
 
 #ifdef HAVE_SHA256
        /* Check for sha256 value */
-       pkg_sha256 = pkg_get_string(pkg, PKG_SHA256SUM);
+       pkg_sha256 = pkg_get_sha256(pkg);
        if (pkg_sha256) {
                file_sha256 = file_sha256sum_alloc(local_filename);
                if (file_sha256 && strcmp(file_sha256, pkg_sha256)) {
index 0731bd0f1972fea8ff290e7b5c7e835c9c8bfbab..1a3eda8167bcaf3700cf2940fcff44627a62a4cc 100644 (file)
@@ -212,6 +212,48 @@ int pkg_get_arch_priority(const pkg_t *pkg)
        return 0;
 }
 
+char *pkg_get_md5(const pkg_t *pkg)
+{
+       char *p = pkg_get_raw(pkg, PKG_MD5SUM);
+
+       if (!p)
+               return NULL;
+
+       return checksum_bin2hex(p, 16);
+}
+
+char *pkg_set_md5(pkg_t *pkg, const char *cksum)
+{
+       size_t len;
+       char *p = checksum_hex2bin(cksum, &len);
+
+       if (!p || len != 16)
+               return NULL;
+
+       return pkg_set_raw(pkg, PKG_MD5SUM, p, len);
+}
+
+char *pkg_get_sha256(const pkg_t *pkg)
+{
+       char *p = pkg_get_raw(pkg, PKG_SHA256SUM);
+
+       if (!p)
+               return NULL;
+
+       return checksum_bin2hex(p, 32);
+}
+
+char *pkg_set_sha256(pkg_t *pkg, const char *cksum)
+{
+       size_t len;
+       char *p = checksum_hex2bin(cksum, &len);
+
+       if (!p || len != 32)
+               return NULL;
+
+       return pkg_set_raw(pkg, PKG_SHA256SUM, p, len);
+}
+
 
 static void compound_depend_deinit(compound_depend_t * depends)
 {
@@ -384,10 +426,10 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
        if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR))
                pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR));
-       if (!pkg_get_string(oldpkg, PKG_MD5SUM))
-               pkg_set_string(oldpkg, PKG_MD5SUM, pkg_get_string(newpkg, PKG_MD5SUM));
-       if (!pkg_get_string(oldpkg, PKG_SHA256SUM))
-               pkg_set_string(oldpkg, PKG_SHA256SUM, pkg_get_string(newpkg, PKG_SHA256SUM));
+       if (!pkg_get_md5(oldpkg))
+               pkg_set_md5(oldpkg, pkg_get_md5(newpkg));
+       if (!pkg_get_sha256(oldpkg))
+               pkg_set_sha256(oldpkg, pkg_get_sha256(newpkg));
        if (!pkg_get_int(oldpkg, PKG_SIZE))
                pkg_set_int(oldpkg, PKG_SIZE, pkg_get_int(newpkg, PKG_SIZE));
        if (!pkg_get_int(oldpkg, PKG_INSTALLED_SIZE))
@@ -716,7 +758,7 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                                fprintf(fp, "Maintainer: %s\n", p);
                        }
                } else if (strcasecmp(field, "MD5sum") == 0) {
-                       p = pkg_get_string(pkg, PKG_MD5SUM);
+                       p = pkg_get_md5(pkg);
                        if (p) {
                                fprintf(fp, "MD5Sum: %s\n", p);
                        }
index df5d7a76086c6709d8dcd63293f3dd30e8123701..eeb75e6f2641316e2e65db7972a179d8935e622f 100644 (file)
@@ -210,6 +210,11 @@ char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len);
 char *pkg_get_architecture(const pkg_t *pkg);
 int pkg_get_arch_priority(const pkg_t *pkg);
 
+char *pkg_get_md5(const pkg_t *pkg);
+char *pkg_set_md5(pkg_t *pkg, const char *cksum);
+
+char *pkg_get_sha256(const pkg_t *pkg);
+char *pkg_set_sha256(pkg_t *pkg, const char *cksum);
 
 abstract_pkg_t *abstract_pkg_new(void);
 
index e0c0069f40ab8a37a1d93743c5cb4908732cadf0..eca0b027c56121a46b2eb4289fd6a83945fcf48e 100644 (file)
@@ -186,12 +186,8 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                break;
 
        case 'M':
-               if ((mask & PFM_MD5SUM) && (is_field("MD5sum:", line) || is_field("MD5Sum:", line))) {
-                       size_t len;
-                       char *cksum = checksum_hex2bin(line + strlen("MD5sum") + 1, &len);
-                       if (cksum && len == 16)
-                               pkg_set_raw(pkg, PKG_MD5SUM, cksum, len);
-               }
+               if ((mask & PFM_MD5SUM) && (is_field("MD5sum:", line) || is_field("MD5Sum:", line)))
+                       pkg_set_md5(pkg, line + strlen("MD5sum") + 1);
                else if ((mask & PFM_MAINTAINER)
                         && is_field("Maintainer", line))
                        pkg_set_string(pkg, PKG_MAINTAINER, line + strlen("Maintainer") + 1);
@@ -220,12 +216,8 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                if ((mask & PFM_SECTION) && is_field("Section", line))
                        pkg_set_string(pkg, PKG_SECTION, line + strlen("Section") + 1);
 #ifdef HAVE_SHA256
-               else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line)) {
-                       size_t len;
-                       char *cksum = checksum_hex2bin(line + strlen("SHA256sum") + 1, &len);
-                       if (cksum && len == 32)
-                               pkg_set_raw(pkg, PKG_SHA256SUM, cksum, len);
-               }
+               else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line))
+                       pkg_set_sha256(pkg, line + strlen("SHA256sum") + 1);
 #endif
                else if ((mask & PFM_SIZE) && is_field("Size", line)) {
                        pkg_set_int(pkg, PKG_SIZE, strtoul(line + strlen("Size") + 1, NULL, 0));