diff options
author | Ori Bernstein <ori@eigenstate.org> | 2019-11-05 10:48:51 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2019-11-05 10:48:51 -0800 |
commit | d72a4043993d02b56873dfe40767cef9336685fc (patch) | |
tree | 907e6e585a28dfc756e50b5c92ba02387cd61513 /sys/src/cmd/tar.c | |
parent | 8b79ad59f14c4ced6ae2af6277d94b3265bd211d (diff) |
Fix directory heuristic for long file names.
Tar specifies that a filename ending with '/' is a directory. We were
incorrectly looking at the short name. This meant that when we have long
filenames with a '/' at the 100th character, we would decide it was a
directory.
This change uses the long name when deciding the size for extraction,
and trusts the header size when just skipping forward in the stream.
Diffstat (limited to 'sys/src/cmd/tar.c')
-rw-r--r-- | sys/src/cmd/tar.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/sys/src/cmd/tar.c b/sys/src/cmd/tar.c index af2b5625a..c1e623596 100644 --- a/sys/src/cmd/tar.c +++ b/sys/src/cmd/tar.c @@ -516,11 +516,11 @@ name(Hdr *hp) } static int -isdir(Hdr *hp) +isdir(Hdr *hp, char *name) { /* the mode test is ugly but sometimes necessary */ return hp->linkflag == LF_DIR || - strrchr(name(hp), '\0')[-1] == '/' || + strrchr(name, '\0')[-1] == '/' || (strtoul(hp->mode, nil, 8)&0170000) == 040000; } @@ -605,9 +605,9 @@ hdrsize(Hdr *hp) * return the number of bytes recorded in the archive. */ static Off -arsize(Hdr *hp) +arsize(Hdr *hp, char *fname) { - if(isdir(hp) || islink(hp->linkflag)) + if(isdir(hp, fname) || islink(hp->linkflag)) return 0; return hdrsize(hp); } @@ -651,7 +651,7 @@ readhdr(int ar) } while (hdrcksum == -1 || chksum(hp) != hdrcksum); fprint(2, "found %s\n", name(hp)); } - nexthdr += Tblock*(1 + BYTES2TBLKS(arsize(hp))); + nexthdr += Tblock*(1 + BYTES2TBLKS(hdrsize(hp))); return hp; } @@ -670,7 +670,7 @@ putfullname(Hdr *hp, char *name) char *sl, *osl; String *slname = nil; - if (isdir(hp)) { + if (isdir(hp, name)) { slname = s_new(); s_append(slname, name); s_append(slname, "/"); /* posix requires this */ @@ -898,7 +898,7 @@ replace(char **argv) if (usefile && !docreate) { /* skip quickly to the end */ while ((hp = readhdr(ar)) != nil) { - bytes = arsize(hp); + bytes = hdrsize(hp); for (blksleft = BYTES2TBLKS(bytes); blksleft > 0 && getblkrd(ar, Justnxthdr) != nil; blksleft -= blksread) { @@ -1147,10 +1147,10 @@ extract1(int ar, Hdr *hp, char *fname) long mtime = strtol(hp->mtime, nil, 8); ulong mode = strtoul(hp->mode, nil, 8) & 0777; Off bytes = hdrsize(hp); /* for printing */ - ulong blksleft = BYTES2TBLKS(arsize(hp)); + ulong blksleft = BYTES2TBLKS(arsize(hp, fname)); /* fiddle name, figure out mode and blocks */ - if (isdir(hp)) { + if (isdir(hp, fname)) { mode |= DMDIR|0700; dir = 1; } @@ -1200,7 +1200,7 @@ skip(int ar, Hdr *hp, char *fname) ulong blksleft, blksread; Hdr *hbp; - for (blksleft = BYTES2TBLKS(arsize(hp)); blksleft > 0; + for (blksleft = BYTES2TBLKS(arsize(hp, fname)); blksleft > 0; blksleft -= blksread) { hbp = getblkrd(ar, Justnxthdr); if (hbp == nil) @@ -1226,7 +1226,7 @@ getname(int ar, Hdr *hp) fname = name(hp); if(hp->linkflag == LF_LONGNAME){ p = namebuf; - for (blksleft = BYTES2TBLKS(arsize(hp)); blksleft > 0; + for (blksleft = BYTES2TBLKS(hdrsize(hp)); blksleft > 0; blksleft -= blksread) { hp = getblkrd(ar, Alldata); if (hp == nil) |