file_util.c: refactor and fix checksum_hex2bin()
[project/opkg-lede.git] / libopkg / file_util.c
index 14ca02e30a727f0daa00a4d23353c9af1e1bd98a..3a1761eea76d331e15d8327bfb20ca8f86e52d92 100644 (file)
@@ -59,17 +59,14 @@ int file_is_dir(const char *file_name)
 */
 char *file_read_line_alloc(FILE * fp)
 {
+       size_t buf_len, line_size;
        char buf[BUFSIZ];
-       unsigned int buf_len;
        char *line = NULL;
-       unsigned int line_size = 0;
        int got_nl = 0;
 
-       buf[0] = '\0';
-
        while (fgets(buf, BUFSIZ, fp)) {
                buf_len = strlen(buf);
-               if (buf[buf_len - 1] == '\n') {
+               if (buf_len > 0 && buf[buf_len - 1] == '\n') {
                        buf_len--;
                        buf[buf_len] = '\0';
                        got_nl = 1;
@@ -125,18 +122,31 @@ int file_mkdir_hier(const char *path, long mode)
        return make_directory(path, mode, FILEUTILS_RECUR);
 }
 
+
+static int hex2bin(unsigned char x)
+{
+       if (x >= 'a' && x <= 'f')
+               return x - 'a' + 10;
+       else if (x >= 'A' && x <= 'F')
+               return x - 'A' + 10;
+       else if (x >= '0' && x <= '9')
+               return x - '0';
+       else
+               return 0;
+}
+
+static const unsigned char bin2hex[16] = {
+       '0', '1', '2', '3',
+       '4', '5', '6', '7',
+       '8', '9', 'a', 'b',
+       'c', 'd', 'e', 'f'
+};
+
 char *file_md5sum_alloc(const char *file_name)
 {
        static const int md5sum_bin_len = 16;
        static const int md5sum_hex_len = 32;
 
-       static const unsigned char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        int i, len;
        char *md5sum_hex;
        unsigned char md5sum_bin[md5sum_bin_len];
@@ -165,13 +175,6 @@ char *file_sha256sum_alloc(const char *file_name)
        static const int sha256sum_bin_len = 32;
        static const int sha256sum_hex_len = 64;
 
-       static const unsigned char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        int i, err;
        FILE *file;
        char *sha256sum_hex;
@@ -212,13 +215,6 @@ char *checksum_bin2hex(const char *src, size_t len)
        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',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        if (!s || len > 32)
                return NULL;
 
@@ -234,35 +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 = (unsigned char *)src;
        static unsigned char buf[32];
+       size_t n = 0;
 
-       if (!src) {
-               *len = 0;
+       *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;
-       }
 
-#define hex(c) \
-       (c >= 'a' ? (c - 'a') : (c >= 'A' ? (c - 'A') : (c - '0')))
+       while (*src) {
+               if (n >= sizeof(buf) || !isxdigit(src[0]) || !isxdigit(src[1]))
+                       return NULL;
 
-       for (p = buf, *len = 0;
-            slen > 0 && isxdigit(s[0]) && isxdigit(s[1]);
-            slen--, s += 2, (*len)++)
-               *p++ = hex(s[0]) * 16 + hex(s[1]);
+               buf[n++] = hex2bin(src[0]) * 16 + hex2bin(src[1]);
+               src += 2;
+       }
 
-       return (char *)buf;
+       *len = n;
+       return n ? (char *)buf : NULL;
 }
 
 int rm_r(const char *path)
@@ -377,23 +368,16 @@ static int urlencode_is_specialchar(char c)
 
 char *urlencode_path(const char *filename)
 {
-       static const char bin2hex[16] = {
-               '0', '1', '2', '3',
-               '4', '5', '6', '7',
-               '8', '9', 'a', 'b',
-               'c', 'd', 'e', 'f'
-       };
-
        size_t len = 0;
-       const char *in;
-       char *copy, *out;
+       const unsigned char *in;
+       unsigned char *copy, *out;
 
-       for (in = filename; *in != 0; in++)
+       for (in = (unsigned char *)filename; *in != 0; in++)
                len += urlencode_is_specialchar(*in) ? 3 : 1;
 
        copy = xcalloc(1, len + 1);
 
-       for (in = filename, out = copy; *in != 0; in++) {
+       for (in = (unsigned char *)filename, out = copy; *in != 0; in++) {
                if (urlencode_is_specialchar(*in)) {
                        *out++ = '%';
                        *out++ = bin2hex[*in / 16];
@@ -404,5 +388,25 @@ char *urlencode_path(const char *filename)
                }
        }
 
-       return copy;
+       return (char *)copy;
+}
+
+char *urldecode_path(const char *filename)
+{
+       unsigned char *copy = (unsigned char *)xstrdup(filename);
+       unsigned char *in, *out;
+
+       for (in = copy, out = copy; *in != 0; in++) {
+               if (*in == '%' && isxdigit(in[1]) && isxdigit(in[2])) {
+                       *out++ = hex2bin(in[1]) * 16 + hex2bin(in[2]);
+                       in += 2;
+               }
+               else {
+                       *out++ = *in;
+               }
+       }
+
+       *out = 0;
+
+       return (char *)copy;
 }