ref: 43447ff04506c0b72faa21016fccc80614ff1d0f
parent: 40edc7d89d922e038d9b5422ecf9dc94b6e447f0
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Oct 31 23:42:24 EDT 2012
hgfs: strip metadata header, bogus .n walks
--- a/sys/src/cmd/hgfs/dat.h
+++ b/sys/src/cmd/hgfs/dat.h
@@ -93,6 +93,7 @@
char *buf;
int fd;
+ int doff; /* length of metadata to skip */
};
uchar nullid[HASHSZ];
--- a/sys/src/cmd/hgfs/fns.h
+++ b/sys/src/cmd/hgfs/fns.h
@@ -21,6 +21,7 @@
uchar *revhash(Revlog *r, int rev);
int hashrev(Revlog *r, uchar hash[]);
int revlogopentemp(Revlog *r, int rev);
+int fmetaheader(int fd);
/* info */
Revinfo *loadrevinfo(Revlog *changelog, int rev);
--- a/sys/src/cmd/hgfs/fs.c
+++ b/sys/src/cmd/hgfs/fs.c
@@ -298,8 +298,15 @@
if((rl = getrevlog(nd)) == nil)
break;
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;
+ }
ri = getrevinfo(rl->map[rev].linkrev);
}
closerevlog(rl);
@@ -490,7 +497,13 @@
sname += 3;
}
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;
goto Searchtree;
}
@@ -680,6 +693,7 @@
responderror(r);
return;
}
+ rf->doff = fmetaheader(rf->fd);
goto Fdgen;
case Qwho:
s = rf->info->who;
@@ -706,8 +720,9 @@
responderror(r);
return;
}
+ rf->doff = fmetaheader(rf->fd);
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);
return;
}
--- a/sys/src/cmd/hgfs/revlog.c
+++ b/sys/src/cmd/hgfs/revlog.c
@@ -281,3 +281,31 @@
}
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;
+}
--
⑨