diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2022-11-18 00:57:01 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2022-11-18 00:58:13 +0100 |
commit | 844fdd42f03a633f1dbce5d90b2ecf44698cf8b0 (patch) | |
tree | 1255d42327bb297b12dfd4e7adfd81e3fbea6762 /bin | |
parent | da6eadc840716eb29b0175f39b2790bba166db4a (diff) |
Add a single, central base64 decoder
Similar to the hex blob decoder, we need this once for tar and
once for the filemap xattr parser.
Simply add a single, central implementation to libutil, with a
simple unit test, and then use it in both libtar and gensquashfs.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin')
-rw-r--r-- | bin/gensquashfs/filemap_xattr.c | 86 |
1 files changed, 8 insertions, 78 deletions
diff --git a/bin/gensquashfs/filemap_xattr.c b/bin/gensquashfs/filemap_xattr.c index 059ce81..0b73d36 100644 --- a/bin/gensquashfs/filemap_xattr.c +++ b/bin/gensquashfs/filemap_xattr.c @@ -11,25 +11,6 @@ #define NEW_FILE_START "# file: " // Taken from attr-2.5.1/tools/setfattr.c -static int -base64_digit(char c) { - if (c >= 'A' && c <= 'Z') - return c - 'A'; - else if (c >= 'a' && c <= 'z') - return 26 + c - 'a'; - else if (c >= '0' && c <= '9') - return 52 + c - '0'; - else if (c == '+') - return 62; - else if (c == '/') - return 63; - else if (c == '=') - return -2; - else - return -1; -} - -// Taken from attr-2.5.1/tools/setfattr.c static char * decode(const char *value, size_t *size) { char *decoded = NULL; @@ -50,71 +31,20 @@ decode(const char *value, size_t *size) { return NULL; } } else if (value[0] == '0' && (value[1] == 's' || value[1] == 'S')) { - const char *v = value + 2, *end = value + *size; - int d0, d1, d2, d3; - char *d; + size_t input_len = *size - 2; - decoded = realloc(decoded, *size / 4 * 3); + *size = (input_len / 4) * 3; + + decoded = realloc(decoded, *size); if (decoded == NULL) { return NULL; } - d = decoded; - for (;;) { - while (v < end && isspace(*v)) - v++; - if (v == end) { - d0 = d1 = d2 = d3 = -2; - break; - } - if (v + 4 > end) { - bad_base64_encoding: - free(decoded); - fprintf(stderr, "bad input encoding\n"); - return NULL; - } - d0 = base64_digit(*v++); - d1 = base64_digit(*v++); - d2 = base64_digit(*v++); - d3 = base64_digit(*v++); - if (d0 < 0 || d1 < 0 || d2 < 0 || d3 < 0) - break; - *d++ = (char)((d0 << 2) | (d1 >> 4)); - *d++ = (char)((d1 << 4) | (d2 >> 2)); - *d++ = (char)((d2 << 6) | d3); - } - if (d0 == -2) { - if (d1 != -2 || d2 != -2 || d3 != -2) - goto bad_base64_encoding; - goto base64_end; - } - if (d0 == -1 || d1 < 0 || d2 == -1 || d3 == -1) - goto bad_base64_encoding; - *d++ = (char)((d0 << 2) | (d1 >> 4)); - if (d2 != -2) - *d++ = (char)((d1 << 4) | (d2 >> 2)); - else { - if (d1 & 0x0F || d3 != -2) - goto bad_base64_encoding; - goto base64_end; - } - if (d3 != -2) - *d++ = (char)((d2 << 6) | d3); - else if (d2 & 0x03) - goto bad_base64_encoding; - base64_end: - while (v < end && isspace(*v)) - v++; - if (v + 4 <= end && *v == '=') { - if (*++v != '=' || *++v != '=' || *++v != '=') - goto bad_base64_encoding; - v++; + if (base64_decode(value + 2, input_len, decoded, size)) { + free(decoded); + fprintf(stderr, "bad input encoding\n"); + return NULL; } - while (v < end && isspace(*v)) - v++; - if (v < end) - goto bad_base64_encoding; - *size = d - decoded; } else { const char *v = value, *end = value + *size; char *d; |