git: 9front

Download patch

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;
+}
--