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/gensquashfs | |
| 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/gensquashfs')
| -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; | 
