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.
This commit is contained in:
parent
8b79ad59f1
commit
d72a404399
1 changed files with 11 additions and 11 deletions
|
@ -516,11 +516,11 @@ name(Hdr *hp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isdir(Hdr *hp)
|
isdir(Hdr *hp, char *name)
|
||||||
{
|
{
|
||||||
/* the mode test is ugly but sometimes necessary */
|
/* the mode test is ugly but sometimes necessary */
|
||||||
return hp->linkflag == LF_DIR ||
|
return hp->linkflag == LF_DIR ||
|
||||||
strrchr(name(hp), '\0')[-1] == '/' ||
|
strrchr(name, '\0')[-1] == '/' ||
|
||||||
(strtoul(hp->mode, nil, 8)&0170000) == 040000;
|
(strtoul(hp->mode, nil, 8)&0170000) == 040000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,9 +605,9 @@ hdrsize(Hdr *hp)
|
||||||
* return the number of bytes recorded in the archive.
|
* return the number of bytes recorded in the archive.
|
||||||
*/
|
*/
|
||||||
static Off
|
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 0;
|
||||||
return hdrsize(hp);
|
return hdrsize(hp);
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ readhdr(int ar)
|
||||||
} while (hdrcksum == -1 || chksum(hp) != hdrcksum);
|
} while (hdrcksum == -1 || chksum(hp) != hdrcksum);
|
||||||
fprint(2, "found %s\n", name(hp));
|
fprint(2, "found %s\n", name(hp));
|
||||||
}
|
}
|
||||||
nexthdr += Tblock*(1 + BYTES2TBLKS(arsize(hp)));
|
nexthdr += Tblock*(1 + BYTES2TBLKS(hdrsize(hp)));
|
||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ putfullname(Hdr *hp, char *name)
|
||||||
char *sl, *osl;
|
char *sl, *osl;
|
||||||
String *slname = nil;
|
String *slname = nil;
|
||||||
|
|
||||||
if (isdir(hp)) {
|
if (isdir(hp, name)) {
|
||||||
slname = s_new();
|
slname = s_new();
|
||||||
s_append(slname, name);
|
s_append(slname, name);
|
||||||
s_append(slname, "/"); /* posix requires this */
|
s_append(slname, "/"); /* posix requires this */
|
||||||
|
@ -898,7 +898,7 @@ replace(char **argv)
|
||||||
if (usefile && !docreate) {
|
if (usefile && !docreate) {
|
||||||
/* skip quickly to the end */
|
/* skip quickly to the end */
|
||||||
while ((hp = readhdr(ar)) != nil) {
|
while ((hp = readhdr(ar)) != nil) {
|
||||||
bytes = arsize(hp);
|
bytes = hdrsize(hp);
|
||||||
for (blksleft = BYTES2TBLKS(bytes);
|
for (blksleft = BYTES2TBLKS(bytes);
|
||||||
blksleft > 0 && getblkrd(ar, Justnxthdr) != nil;
|
blksleft > 0 && getblkrd(ar, Justnxthdr) != nil;
|
||||||
blksleft -= blksread) {
|
blksleft -= blksread) {
|
||||||
|
@ -1147,10 +1147,10 @@ extract1(int ar, Hdr *hp, char *fname)
|
||||||
long mtime = strtol(hp->mtime, nil, 8);
|
long mtime = strtol(hp->mtime, nil, 8);
|
||||||
ulong mode = strtoul(hp->mode, nil, 8) & 0777;
|
ulong mode = strtoul(hp->mode, nil, 8) & 0777;
|
||||||
Off bytes = hdrsize(hp); /* for printing */
|
Off bytes = hdrsize(hp); /* for printing */
|
||||||
ulong blksleft = BYTES2TBLKS(arsize(hp));
|
ulong blksleft = BYTES2TBLKS(arsize(hp, fname));
|
||||||
|
|
||||||
/* fiddle name, figure out mode and blocks */
|
/* fiddle name, figure out mode and blocks */
|
||||||
if (isdir(hp)) {
|
if (isdir(hp, fname)) {
|
||||||
mode |= DMDIR|0700;
|
mode |= DMDIR|0700;
|
||||||
dir = 1;
|
dir = 1;
|
||||||
}
|
}
|
||||||
|
@ -1200,7 +1200,7 @@ skip(int ar, Hdr *hp, char *fname)
|
||||||
ulong blksleft, blksread;
|
ulong blksleft, blksread;
|
||||||
Hdr *hbp;
|
Hdr *hbp;
|
||||||
|
|
||||||
for (blksleft = BYTES2TBLKS(arsize(hp)); blksleft > 0;
|
for (blksleft = BYTES2TBLKS(arsize(hp, fname)); blksleft > 0;
|
||||||
blksleft -= blksread) {
|
blksleft -= blksread) {
|
||||||
hbp = getblkrd(ar, Justnxthdr);
|
hbp = getblkrd(ar, Justnxthdr);
|
||||||
if (hbp == nil)
|
if (hbp == nil)
|
||||||
|
@ -1226,7 +1226,7 @@ getname(int ar, Hdr *hp)
|
||||||
fname = name(hp);
|
fname = name(hp);
|
||||||
if(hp->linkflag == LF_LONGNAME){
|
if(hp->linkflag == LF_LONGNAME){
|
||||||
p = namebuf;
|
p = namebuf;
|
||||||
for (blksleft = BYTES2TBLKS(arsize(hp)); blksleft > 0;
|
for (blksleft = BYTES2TBLKS(hdrsize(hp)); blksleft > 0;
|
||||||
blksleft -= blksread) {
|
blksleft -= blksread) {
|
||||||
hp = getblkrd(ar, Alldata);
|
hp = getblkrd(ar, Alldata);
|
||||||
if (hp == nil)
|
if (hp == nil)
|
||||||
|
|
Loading…
Reference in a new issue