Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use archive_mstring_*_l interface in archive_acl_* functions

since archive_mstring knows how to treat UTF-8 characters and
what way is efficient on the platform and what way reduces or
avoid dependence on current locale.

SVN-Revision: 3319
  • Loading branch information...
commit 9f7b99cba5c3b3b8cc2a4ccf717769e00c492f65 1 parent 963e808
@ggcueroad ggcueroad authored
View
120 libarchive/archive_acl.c
@@ -150,10 +150,12 @@ archive_acl_add_entry_w_len(struct archive_acl *acl,
}
int
-archive_acl_add_entry_len(struct archive_acl *acl,
- int type, int permset, int tag, int id, const char *name, size_t len)
+archive_acl_add_entry_len_l(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const char *name, size_t len,
+ struct archive_string_conv *sc)
{
struct archive_acl_entry *ap;
+ int r;
if (acl_special(acl, type, permset, tag) == 0)
return ARCHIVE_OK;
@@ -162,11 +164,13 @@ archive_acl_add_entry_len(struct archive_acl *acl,
/* XXX Error XXX */
return ARCHIVE_FAILED;
}
- if (name != NULL && *name != '\0' && len > 0)
- archive_mstring_copy_mbs_len(&ap->name, name, len);
- else
+ if (name != NULL && *name != '\0' && len > 0) {
+ r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc);
+ } else {
+ r = 0;
archive_mstring_clean(&ap->name);
- return ARCHIVE_OK;
+ }
+ return ((r == 0)? ARCHIVE_OK: ARCHIVE_WARN);
}
/*
@@ -596,8 +600,10 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
**wp = L'\0';
}
-const char *
-archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
+int
+archive_acl_text_l(struct archive_acl *acl, int flags,
+ const char **acl_text, size_t *acl_text_len,
+ struct archive_string_conv *sc)
{
int count;
size_t length;
@@ -605,7 +611,8 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
const char *prefix;
char separator;
struct archive_acl_entry *ap;
- int id;
+ size_t len;
+ int id, r;
char *p;
if (acl->acl_text != NULL) {
@@ -613,6 +620,9 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
acl->acl_text = NULL;
}
+ *acl_text = NULL;
+ if (acl_text_len != NULL)
+ *acl_text_len = 0;
separator = ',';
count = 0;
length = 0;
@@ -625,9 +635,12 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
length += 8; /* "default:" */
length += 5; /* tag name */
length += 1; /* colon */
- if (archive_mstring_get_mbs(a, &ap->name, &name) == 0 &&
- name != NULL)
- length += strlen(name);
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (len > 0 && name != NULL)
+ length += len;
else
length += sizeof(uid_t) * 3 + 1;
length ++; /* colon */
@@ -646,7 +659,7 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
}
if (count == 0)
- return (NULL);
+ return (0);
/* Now, allocate the string and actually populate it. */
p = acl->acl_text = (char *)malloc(length);
@@ -664,20 +677,21 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
acl->mode & 0007, -1);
count += 3;
- ap = acl->acl_head;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 &&
- archive_mstring_get_mbs(a, &ap->name, &name) == 0) {
- *p++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry(&p, NULL, ap->tag, name,
- ap->permset, id);
- count++;
- }
- ap = ap->next;
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, NULL, ap->tag, name,
+ ap->permset, id);
+ count++;
}
}
@@ -687,26 +701,30 @@ archive_acl_text(struct archive *a, struct archive_acl *acl, int flags)
prefix = "default:";
else
prefix = NULL;
- ap = acl->acl_head;
count = 0;
- while (ap != NULL) {
- if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0 &&
- archive_mstring_get_mbs(a, &ap->name, &name) == 0) {
- if (count > 0)
- *p++ = separator;
- if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
- id = ap->id;
- else
- id = -1;
- append_entry(&p, prefix, ap->tag,
- name, ap->permset, id);
- count ++;
- }
- ap = ap->next;
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (count > 0)
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, prefix, ap->tag,
+ name, ap->permset, id);
+ count ++;
}
}
- return (acl->acl_text);
+ *acl_text = acl->acl_text;
+ if (acl_text_len != NULL)
+ *acl_text_len = strlen(acl->acl_text);
+ return (0);
}
static void
@@ -1011,15 +1029,15 @@ prefix_w(const wchar_t *start, const wchar_t *end, const wchar_t *test)
* explicitly marked as "default:".
*/
int
-archive_acl_parse(struct archive_acl *acl,
- const char *text, int default_type)
+archive_acl_parse_l(struct archive_acl *acl,
+ const char *text, int default_type, struct archive_string_conv *sc)
{
struct {
const char *start;
const char *end;
} field[4], name;
- int fields, n;
+ int fields, n, r, ret = ARCHIVE_OK;
int type, tag, permset, id;
char sep;
@@ -1108,10 +1126,14 @@ archive_acl_parse(struct archive_acl *acl,
return (ARCHIVE_WARN);
/* Add entry to the internal list. */
- archive_acl_add_entry_len(acl, type, permset,
- tag, id, name.start, name.end - name.start);
+ r = archive_acl_add_entry_len_l(acl, type, permset,
+ tag, id, name.start, name.end - name.start, sc);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r != ARCHIVE_OK)
+ ret = ARCHIVE_WARN;
}
- return (ARCHIVE_OK);
+ return (ret);
}
/*
View
8 libarchive/archive_acl_private.h
@@ -67,7 +67,8 @@ int archive_acl_add_entry_len(struct archive_acl *,
int, int, int, int, const char *, size_t);
const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
-const char *archive_acl_text(struct archive *, struct archive_acl *, int);
+int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
+ struct archive_string_conv *);
/*
* Private ACL parser. This is private because it handles some
@@ -79,7 +80,8 @@ const char *archive_acl_text(struct archive *, struct archive_acl *, int);
*/
int archive_acl_parse_w(struct archive_acl *,
const wchar_t *, int /* type */);
-int archive_acl_parse(struct archive_acl *,
- const char *, int /* type */);
+int archive_acl_parse_l(struct archive_acl *,
+ const char *, int /* type */,
+ struct archive_string_conv *);
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
View
11 libarchive/archive_entry.c
@@ -1268,7 +1268,16 @@ archive_entry_acl_text_w(struct archive_entry *entry, int flags)
const char *
archive_entry_acl_text(struct archive_entry *entry, int flags)
{
- return archive_acl_text(entry->archive, &entry->acl, flags);
+ const char *p;
+ archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL);
+ return (p);
+}
+
+int
+_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
+ const char **acl_text, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_acl_text_l(&entry->acl, flags, acl_text, len, sc));
}
/*
View
4 libarchive/archive_entry_locale.h
@@ -61,6 +61,10 @@ int _archive_entry_symlink_l(struct archive_entry *,
#define archive_entry_uname_l _archive_entry_uname_l
int _archive_entry_uname_l(struct archive_entry *,
const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_acl_text_l _archive_entry_acl_text_l
+int _archive_entry_acl_text_l(struct archive_entry *, int,
+ const char **, size_t *, struct archive_string_conv *);
+
#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
int _archive_entry_copy_gname_l(struct archive_entry *,
View
49 libarchive/archive_read_support_format_tar.c
@@ -921,14 +921,9 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
if (tar->sconv_acl == NULL)
return (ARCHIVE_FATAL);
}
- if (archive_strncpy_in_locale(&(tar->localname), acl, p - acl,
- tar->sconv_acl) != 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Malformed Solaris ACL attribute (unconvertible)");
- return(ARCHIVE_WARN);
- }
- err = archive_acl_parse(archive_entry_acl(entry),
- tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ archive_strncpy(&(tar->localname), acl, p - acl);
+ err = archive_acl_parse_l(archive_entry_acl(entry),
+ tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
if (err != ARCHIVE_OK)
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unparsable)");
@@ -1636,7 +1631,7 @@ pax_attribute(struct archive_read *a, struct tar *tar,
{
int64_t s;
long n;
- int err = ARCHIVE_OK;
+ int err = ARCHIVE_OK, r;
switch (key[0]) {
case 'G':
@@ -1730,17 +1725,15 @@ pax_attribute(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
- if (archive_strcpy_in_locale(&(tar->localname),
- value, tar->sconv_acl) != 0) {
- err = ARCHIVE_WARN;
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "SCHILY.acl.access can't be converted "
- "from UTF-8 to current locale.");
- } else
- archive_acl_parse(archive_entry_acl(entry),
- tar->localname.s,
- ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.access");
+ }
} else if (strcmp(key, "SCHILY.acl.default")==0) {
if (tar->sconv_acl == NULL) {
tar->sconv_acl =
@@ -1750,17 +1743,15 @@ pax_attribute(struct archive_read *a, struct tar *tar,
return (ARCHIVE_FATAL);
}
- if (archive_strcpy_in_locale(&(tar->localname),
- value, tar->sconv_acl) != 0) {
- err = ARCHIVE_WARN;
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "SCHILY.acl.default can't be converted "
- "from UTF-8 to current locale.");
- } else
- archive_acl_parse(archive_entry_acl(entry),
- tar->localname.s,
- ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.default");
+ }
} else if (strcmp(key, "SCHILY.devmajor")==0) {
archive_entry_set_rdevmajor(entry,
tar_atol10(value, strlen(value)));
View
52 libarchive/archive_write_set_format_pax.c
@@ -54,7 +54,6 @@ struct pax {
uint64_t entry_bytes_remaining;
uint64_t entry_padding;
struct archive_string l_url_encoded_name;
- struct archive_string l_acl_utf8;
struct archive_string pax_header;
struct archive_string sparse_map;
size_t sparse_map_padding;
@@ -922,37 +921,31 @@ archive_write_pax_header(struct archive_write *a,
add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
/* I use star-compatible ACL attributes. */
- p = archive_entry_acl_text(entry_original,
+ r = archive_entry_acl_text_l(entry_original,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID);
- if (p != NULL && *p != '\0') {
- r = archive_strcpy_in_locale(
- &(pax->l_acl_utf8), p, pax->sconv_utf8);
- if (r != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate ACL.access to UTF-8");
- ret = ARCHIVE_WARN;
- } else {
- add_pax_attr(&(pax->pax_header),
- "SCHILY.acl.access", pax->l_acl_utf8.s);
- }
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.access to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.access", p);
}
- p = archive_entry_acl_text(entry_original,
+ r = archive_entry_acl_text_l(entry_original,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
- ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID);
- if (p != NULL && *p != '\0') {
- r = archive_strcpy_in_locale(
- &(pax->l_acl_utf8), p, pax->sconv_utf8);
- if (r != 0) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Can't translate ACL.default to UTF-8");
- ret = ARCHIVE_WARN;
- } else {
- add_pax_attr(&(pax->pax_header),
- "SCHILY.acl.default", pax->l_acl_utf8.s);
- }
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.default to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.default", p);
}
/* We use GNU-tar-compatible sparse attributes. */
@@ -1472,7 +1465,6 @@ archive_write_pax_free(struct archive_write *a)
archive_string_free(&pax->pax_header);
archive_string_free(&pax->sparse_map);
archive_string_free(&pax->l_url_encoded_name);
- archive_string_free(&pax->l_acl_utf8);
sparse_list_clear(pax);
free(pax);
a->format_data = NULL;
Please sign in to comment.
Something went wrong with that request. Please try again.