diff options
| -rw-r--r-- | include/tar.h | 3 | ||||
| -rw-r--r-- | lib/tar/base64.c | 39 | ||||
| -rw-r--r-- | lib/tar/internal.h | 2 | ||||
| -rw-r--r-- | lib/tar/read_header.c | 9 | ||||
| -rw-r--r-- | lib/tar/write_header.c | 9 | ||||
| -rw-r--r-- | tar/sqfs2tar.c | 3 | ||||
| -rw-r--r-- | tar/tar2sqfs.c | 2 | ||||
| -rw-r--r-- | tests/tar_xattr_bsd.c | 3 | ||||
| -rw-r--r-- | tests/tar_xattr_schily.c | 3 | 
9 files changed, 50 insertions, 23 deletions
| diff --git a/include/tar.h b/include/tar.h index c496095..22563c4 100644 --- a/include/tar.h +++ b/include/tar.h @@ -71,7 +71,8 @@ typedef struct {  typedef struct tar_xattr_t {  	struct tar_xattr_t *next;  	char *key; -	char *value; +	sqfs_u8 *value; +	size_t value_len;  	char data[];  } tar_xattr_t; diff --git a/lib/tar/base64.c b/lib/tar/base64.c index 0ccf3c4..f88444a 100644 --- a/lib/tar/base64.c +++ b/lib/tar/base64.c @@ -23,18 +23,37 @@ static sqfs_u8 convert(char in)  	return 0;  } -void base64_decode(sqfs_u8 *out, const char *in) +size_t base64_decode(sqfs_u8 *out, const char *in, size_t len)  { -	char temp[4]; +	sqfs_u8 *start = out; -	while (*in != '\0' && *in != '=') { -		temp[0] = *in == '\0' ? 0 : convert(*(in++)); -		temp[1] = *in == '\0' ? 0 : convert(*(in++)); -		temp[2] = *in == '\0' ? 0 : convert(*(in++)); -		temp[3] = *in == '\0' ? 0 : convert(*(in++)); +	while (len > 0) { +		unsigned int diff = 0, value = 0; -		*(out++) = ((temp[0] << 2) & 0xFC) | ((temp[1] >> 4) & 0x03); -		*(out++) = ((temp[1] << 4) & 0xF0) | ((temp[2] >> 2) & 0x0F); -		*(out++) = ((temp[2] << 6) & 0xC0) | ( temp[3]       & 0x3F); +		while (diff < 4 && len > 0) { +			if (*in == '=' || *in == '_' || *in == '\0') { +				len = 0; +			} else { +				value = (value << 6) | convert(*(in++)); +				--len; +				++diff; +			} +		} + +		if (diff < 2) +			break; + +		value <<= 6 * (4 - diff); + +		switch (diff) { +		case 4:  out[2] = value & 0xff; /* fall-through */ +		case 3:  out[1] = (value >> 8) & 0xff; /* fall-through */ +		default: out[0] = (value >> 16) & 0xff; +		} + +		out += (diff * 3) / 4;  	} + +	*out = '\0'; +	return out - start;  } diff --git a/lib/tar/internal.h b/lib/tar/internal.h index 055637a..0220f05 100644 --- a/lib/tar/internal.h +++ b/lib/tar/internal.h @@ -61,7 +61,7 @@ void free_sparse_list(sparse_map_t *sparse);  void free_xattr_list(tar_xattr_t *list); -void base64_decode(sqfs_u8 *out, const char *in); +size_t base64_decode(sqfs_u8 *out, const char *in, size_t len);  void urldecode(char *str); diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c index 845afc3..20e7a9f 100644 --- a/lib/tar/read_header.c +++ b/lib/tar/read_header.c @@ -68,7 +68,8 @@ static tar_xattr_t *mkxattr(const char *key, size_t keylen,  		return NULL;  	xattr->key = xattr->data; -	xattr->value = xattr->data + keylen + 1; +	xattr->value = (sqfs_u8 *)xattr->data + keylen + 1; +	xattr->value_len = valuelen;  	memcpy(xattr->key, key, keylen);  	memcpy(xattr->value, value, valuelen);  	return xattr; @@ -201,7 +202,8 @@ static int read_pax_header(FILE *fp, sqfs_u64 entsize, unsigned int *set_by_pax,  			value = ptr + 1; -			xattr = mkxattr(key, ptr - key, value, strlen(value)); +			xattr = mkxattr(key, ptr - key, +					value, len - (value - line) - 1);  			if (xattr == NULL)  				goto fail_errno; @@ -221,7 +223,8 @@ static int read_pax_header(FILE *fp, sqfs_u64 entsize, unsigned int *set_by_pax,  				goto fail_errno;  			urldecode(xattr->key); -			base64_decode((sqfs_u8 *)xattr->value, value); +			xattr->value_len = base64_decode(xattr->value, value, +							 xattr->value_len);  			xattr->next = out->xattr;  			out->xattr = xattr; diff --git a/lib/tar/write_header.c b/lib/tar/write_header.c index c235014..acce280 100644 --- a/lib/tar/write_header.c +++ b/lib/tar/write_header.c @@ -133,7 +133,7 @@ static int write_schily_xattr(FILE *fp, const struct stat *orig,  	struct stat sb;  	for (it = xattr; it != NULL; it = it->next) { -		len = strlen(prefix) + strlen(it->key) + strlen(it->value) + 2; +		len = strlen(prefix) + strlen(it->key) + it->value_len + 2;  		total_size += num_digits(len) + 1 + len;  	} @@ -146,11 +146,12 @@ static int write_schily_xattr(FILE *fp, const struct stat *orig,  		return -1;  	for (it = xattr; it != NULL; it = it->next) { -		len = strlen(prefix) + strlen(it->key) + strlen(it->value) + 2; +		len = strlen(prefix) + strlen(it->key) + it->value_len + 2;  		len += num_digits(len) + 1; -		fprintf(fp, PRI_SZ " %s%s=%s\n", len, -			prefix, it->key, it->value); +		fprintf(fp, PRI_SZ " %s%s=", len, prefix, it->key); +		fwrite(it->value, 1, it->value_len, fp); +		fputc('\n', fp);  	}  	return padd_file(fp, total_size); diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c index 6767b95..58fb611 100644 --- a/tar/sqfs2tar.c +++ b/tar/sqfs2tar.c @@ -267,9 +267,10 @@ static int get_xattrs(const char *name, const sqfs_inode_generic_t *inode,  		ent->key = ent->data;  		strcpy(ent->key, (const char *)key->key); -		ent->value = ent->key + strlen(ent->key) + 1; +		ent->value = (sqfs_u8 *)ent->key + strlen(ent->key) + 1;  		memcpy(ent->value, value->value, value->size + 1); +		ent->value_len = value->size;  		ent->next = list;  		list = ent; diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index 5d40fc5..6be682f 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -334,7 +334,7 @@ static int copy_xattr(tree_node_t *node, const tar_header_decoded_t *hdr)  		}  		ret = sqfs_xattr_writer_add(sqfs.xwr, xattr->key, xattr->value, -					    strlen(xattr->value)); +					    xattr->value_len);  		if (ret) {  			sqfs_perror(hdr->name, "storing xattr key-value pair",  				    ret); diff --git a/tests/tar_xattr_bsd.c b/tests/tar_xattr_bsd.c index dcaba1e..0741511 100644 --- a/tests/tar_xattr_bsd.c +++ b/tests/tar_xattr_bsd.c @@ -54,7 +54,8 @@ int main(void)  	assert(hdr.xattr != NULL);  	assert(strcmp(hdr.xattr->key, "user.mime_type") == 0); -	assert(strcmp(hdr.xattr->value, "text/plain") == 0); +	assert(strcmp((const char *)hdr.xattr->value, "text/plain") == 0); +	assert(hdr.xattr->value_len == 10);  	assert(hdr.xattr->next == NULL);  	clear_header(&hdr); diff --git a/tests/tar_xattr_schily.c b/tests/tar_xattr_schily.c index 6cc31f5..f562b43 100644 --- a/tests/tar_xattr_schily.c +++ b/tests/tar_xattr_schily.c @@ -54,7 +54,8 @@ int main(void)  	assert(hdr.xattr != NULL);  	assert(strcmp(hdr.xattr->key, "user.mime_type") == 0); -	assert(strcmp(hdr.xattr->value, "text/plain") == 0); +	assert(strcmp((const char *)hdr.xattr->value, "text/plain") == 0); +	assert(hdr.xattr->value_len == 10);  	assert(hdr.xattr->next == NULL);  	clear_header(&hdr); | 
