As POSIX pax(1) [1] says, If the <value> field is zero length, it shall delete any header block field, previously entered extended header value, or global extended header value of the same name.
Note that extended attribute removal is not implemented yet. [1] https://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html Signed-off-by: Gao Xiang <[email protected]> --- lib/tar.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/tar.c b/lib/tar.c index c522bc3f21e1..9e53af511c0c 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -487,7 +487,7 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, while (p < buf + size) { char *kv, *key, *value; - int len, n; + int len, n, j; /* extended records are of the format: "LEN NAME=VALUE\n" */ ret = sscanf(p, "%d %n", &len, &n); if (ret < 1 || len <= n || len > buf + size - p) { @@ -514,20 +514,25 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, value++; if (!strncmp(kv, "path=", sizeof("path=") - 1)) { - int j = p - 1 - value; free(eh->path); + if (!*value) { + eh->path = NULL; + continue; + } + j = p - 1 - value; eh->path = strdup(value); while (j && eh->path[j - 1] == '/') eh->path[--j] = '\0'; } else if (!strncmp(kv, "linkpath=", sizeof("linkpath=") - 1)) { free(eh->link); - eh->link = strdup(value); + eh->link = *value ? strdup(value) : NULL; } else if (!strncmp(kv, "mtime=", sizeof("mtime=") - 1)) { - unsigned int ns = 0; - int digits = 0; - + if (!*value) { + eh->use_mtime = false; + continue; + } ret = sscanf(value, "%lld %n", &lln, &n); if(ret < 1) { ret = -EIO; @@ -535,6 +540,9 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, } eh->st.st_mtime = lln; if (value[n] == '.') { + unsigned int ns = 0; + int digits = 0; + while (value[n + 1] >= '0' && value[n + 1] <= '9') { if (digits < 9) @@ -566,6 +574,10 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, eh->use_mtime = true; } else if (!strncmp(kv, "size=", sizeof("size=") - 1)) { + if (!*value) { + eh->use_size = false; + continue; + } ret = sscanf(value, "%lld %n", &lln, &n); if(ret < 1 || value[n] != '\0') { ret = -EIO; @@ -580,6 +592,10 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, eh->st.st_size = lln; eh->use_size = true; } else if (!strncmp(kv, "uid=", sizeof("uid=") - 1)) { + if (!*value) { + eh->use_uid = false; + continue; + } ret = sscanf(value, "%lld %n", &lln, &n); if(ret < 1 || value[n] != '\0') { ret = -EIO; @@ -588,6 +604,10 @@ int tarerofs_parse_pax_header(struct erofs_iostream *ios, eh->st.st_uid = lln; eh->use_uid = true; } else if (!strncmp(kv, "gid=", sizeof("gid=") - 1)) { + if (!*value) { + eh->use_gid = false; + continue; + } ret = sscanf(value, "%lld %n", &lln, &n); if(ret < 1 || value[n] != '\0') { ret = -EIO; -- 2.43.5
