--- tar.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/tar.c b/tar.c index e4701dc..ddc56ea 100644 --- a/tar.c +++ b/tar.c _AT_@ -187,6 +187,8 @@ archive(const char *path) size_t chksum, i; ssize_t l, r; int fd = -1; + char tmp_prefix[PATH_MAX]; + char *bsname; if (lstat(path, &st) < 0) { weprintf("lstat %s:", path); _AT_@ -202,26 +204,22 @@ archive(const char *path) h = (struct header *)b; memset(b, 0, sizeof(b)); - if (strlen(path) > 255) { - const char *reason = "path exceeds 255 character limit"; - eprintf("malformed tar archive: %s\n", reason); - } else if (strlen(path) >= 100) { - size_t prefix_len = 155; - const char *last_slash = strrchr(path, '/'); - - if (last_slash && last_slash < path + prefix_len) { - prefix_len = last_slash - path + 1; + if (strlen(path) >= 100) { + // Cover case where path name is too long (in which case we need + // to split it to prefix and name). + bsname = basename((char *)path); + estrlcpy(tmp_prefix, path, PATH_MAX); + dirname(tmp_prefix); + // Could still be too long to fit in the fields. + if (strlen(bsname) >= sizeof(h->name) || + strlen(tmp_prefix) >= sizeof(h->prefix)) { + eprintf("filename too long: %s\n", path); + } else { + estrlcpy(h->name, bsname, sizeof(h->name)); + estrlcpy(h->prefix, tmp_prefix, sizeof(h->prefix)); } - - /* strlcpy is fine here - for path ONLY -, - * since we're splitting the path. - * It's not an issue if the prefix can't hold - * the full path — name will take the rest. */ - strlcpy(h->prefix, path, prefix_len); - estrlcpy(h->name, path + prefix_len, sizeof(h->name)); - } else { - estrlcpy(h->name, path, sizeof(h->name)); - } + } else + estrlcpy(h->name, path, sizeof(h->name)); putoctal(h->mode, (unsigned)st.st_mode & 0777, sizeof(h->mode)); putoctal(h->uid, (unsigned)st.st_uid, sizeof(h->uid)); -- 2.34.1Received on Mon Feb 24 2025 - 19:00:43 CET
This archive was generated by hypermail 2.3.0 : Mon Feb 24 2025 - 21:36:38 CET