hgfs: strip metadata header, bogus .n walks
This commit is contained in:
parent
30d54cc055
commit
4b2a1c104b
|
@ -93,6 +93,7 @@ struct Revfile
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
int fd;
|
int fd;
|
||||||
|
int doff; /* length of metadata to skip */
|
||||||
};
|
};
|
||||||
|
|
||||||
uchar nullid[HASHSZ];
|
uchar nullid[HASHSZ];
|
||||||
|
|
|
@ -21,6 +21,7 @@ int revlogextract(Revlog *r, int rev, int ofd);
|
||||||
uchar *revhash(Revlog *r, int rev);
|
uchar *revhash(Revlog *r, int rev);
|
||||||
int hashrev(Revlog *r, uchar hash[]);
|
int hashrev(Revlog *r, uchar hash[]);
|
||||||
int revlogopentemp(Revlog *r, int rev);
|
int revlogopentemp(Revlog *r, int rev);
|
||||||
|
int fmetaheader(int fd);
|
||||||
|
|
||||||
/* info */
|
/* info */
|
||||||
Revinfo *loadrevinfo(Revlog *changelog, int rev);
|
Revinfo *loadrevinfo(Revlog *changelog, int rev);
|
||||||
|
|
|
@ -298,8 +298,15 @@ fsmkdir(Dir *d, int level, void *aux)
|
||||||
if((rl = getrevlog(nd)) == nil)
|
if((rl = getrevlog(nd)) == nil)
|
||||||
break;
|
break;
|
||||||
if((rev = hashrev(rl, nd->hash)) >= 0){
|
if((rev = hashrev(rl, nd->hash)) >= 0){
|
||||||
if(level == Qtree)
|
if(level == Qtree){
|
||||||
|
/*
|
||||||
|
* BUG: this is not correct. mercurial might
|
||||||
|
* prefix the data log with random \1\n escaped
|
||||||
|
* metadata strings (see fmetaheader()) and the flen
|
||||||
|
* *includes* the metadata part. m(
|
||||||
|
*/
|
||||||
d->length = rl->map[rev].flen;
|
d->length = rl->map[rev].flen;
|
||||||
|
}
|
||||||
ri = getrevinfo(rl->map[rev].linkrev);
|
ri = getrevinfo(rl->map[rev].linkrev);
|
||||||
}
|
}
|
||||||
closerevlog(rl);
|
closerevlog(rl);
|
||||||
|
@ -490,7 +497,13 @@ fswalk1(Fid *fid, char *name, Qid *qid)
|
||||||
sname += 3;
|
sname += 3;
|
||||||
}
|
}
|
||||||
snprint(buf, sizeof(buf), "%.*s", i, name);
|
snprint(buf, sizeof(buf), "%.*s", i, name);
|
||||||
i = atoi(sname);
|
if(*sname == 0)
|
||||||
|
i = 0;
|
||||||
|
else {
|
||||||
|
i = strtol(sname, &sname, 10);
|
||||||
|
if(i < 0 || *sname != '\0')
|
||||||
|
goto Notfound;
|
||||||
|
}
|
||||||
sname = buf;
|
sname = buf;
|
||||||
goto Searchtree;
|
goto Searchtree;
|
||||||
}
|
}
|
||||||
|
@ -680,6 +693,7 @@ fsread(Req *r)
|
||||||
responderror(r);
|
responderror(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
rf->doff = fmetaheader(rf->fd);
|
||||||
goto Fdgen;
|
goto Fdgen;
|
||||||
case Qwho:
|
case Qwho:
|
||||||
s = rf->info->who;
|
s = rf->info->who;
|
||||||
|
@ -706,8 +720,9 @@ fsread(Req *r)
|
||||||
responderror(r);
|
responderror(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
rf->doff = fmetaheader(rf->fd);
|
||||||
Fdgen:
|
Fdgen:
|
||||||
if((n = pread(rf->fd, r->ofcall.data, len, off)) < 0){
|
if((n = pread(rf->fd, r->ofcall.data, len, off + rf->doff)) < 0){
|
||||||
responderror(r);
|
responderror(r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,3 +281,31 @@ revlogopentemp(Revlog *r, int rev)
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fmetaheader(int fd)
|
||||||
|
{
|
||||||
|
static char magic[2] = { 0x01, 0x0A, };
|
||||||
|
char buf[4096], *s, *p;
|
||||||
|
int o, n;
|
||||||
|
|
||||||
|
o = 0;
|
||||||
|
while(o < sizeof(buf)){
|
||||||
|
if((n = pread(fd, buf+o, sizeof(buf)-o, o)) <= 0)
|
||||||
|
break;
|
||||||
|
o += n;
|
||||||
|
if(o < sizeof(magic))
|
||||||
|
continue;
|
||||||
|
if(memcmp(buf, magic, sizeof(magic)) != 0)
|
||||||
|
break;
|
||||||
|
s = buf + sizeof(magic);
|
||||||
|
while((s - buf) <= (o - sizeof(magic))){
|
||||||
|
if((p = memchr(s, magic[0], o - (s - buf))) == nil)
|
||||||
|
break;
|
||||||
|
if(memcmp(p, magic, sizeof(magic)) == 0)
|
||||||
|
return (p - buf) + sizeof(magic);
|
||||||
|
s = p+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue