---
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.1
Received 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