9front - general discussion about 9front
 help / color / mirror / Atom feed
* hgfs(4) loadrevinfo patch
@ 2019-12-05  8:42 Alex Musolino
  0 siblings, 0 replies; only message in thread
From: Alex Musolino @ 2019-12-05  8:42 UTC (permalink / raw)
  To: 9front

Hi all,

Hgfs(4) crashes when the commit message contains lines
longer than BUFSZ (i.e. 1024) bytes.  Here's my attempt
at a fix.  Thoughts?

diff -r 754916eeedf1 sys/src/cmd/hgfs/info.c
--- a/sys/src/cmd/hgfs/info.c	Tue Dec 03 18:32:30 2019 +1030
+++ b/sys/src/cmd/hgfs/info.c	Thu Dec 05 19:08:41 2019 +1030
@@ -1,79 +1,100 @@
 #include <u.h>
 #include <libc.h>
 #include <thread.h>
+#include <bio.h>
 #include "dat.h"
 #include "fns.h"
 
+static int
+walkline(Biobuf *bio)
+{
+	int c, n;
+
+	for(n = 0;;){
+		c = Bgetc(bio);
+		if(c < 0)
+			return -1;
+		n++;
+		if(c == '\n')
+			break;
+	}
+	return n;
+}
+
+static int
+walklog(Biobuf *bio)
+{
+	int n, r;
+
+	for(n = 0;;){
+		r = walkline(bio);
+		if(r < 0)
+			return -1;
+		if(r == 1)
+			break;
+		n += r;
+	}
+	return n;
+}
+
 Revinfo*
 loadrevinfo(Revlog *changelog, int rev)
 {
-	char buf[BUFSZ], *p, *e;
-	int fd, line, eof, inmsg, n;
+	int fd;
+	char *line;
 	Revinfo *ri;
 	vlong off;
+	Biobuf *buf;
 
 	if((fd = revlogopentemp(changelog, rev)) < 0)
 		return nil;
-
 	off = fmetaheader(fd);
 	seek(fd, off, 0);
 
 	ri = malloc(sizeof(*ri));
 	memset(ri, 0, sizeof(*ri));
-
+	ri->logoff = off;
 	memmove(ri->chash, changelog->map[rev].hash, HASHSZ);
 
-	eof = 0;
-	line = 0;
-	inmsg = 0;
-	p = buf;
-	e = buf + BUFSZ;
-	while(eof == 0){
-		if((n = read(fd, p, e - p)) < 0)
-			break;
-		if(n == 0){
-			eof = 1;
-			*p = '\n';
-			n++;
-		}
-		p += n;
-		while((p > buf) && (e = memchr(buf, '\n', p - buf))){
-			*e++ = 0;
+	buf = Bfdopen(fd, OREAD);
+	line = Brdstr(buf, '\n', 1);
+	if(line == nil)
+		goto Error;
+	ri->logoff += Blinelen(buf) + 1;
+	hex2hash(line, ri->mhash);
+	free(line);
 
-			switch(line++){
-			case 0:
-				hex2hash(buf, ri->mhash);
-				break;
-			case 1:
-				ri->who = strdup(buf);
-				break;
-			case 2:
-				ri->when = strtol(buf, nil, 10);
-				break;
-			case 3:
-				ri->logoff = off;
-			default:
-				if(!inmsg){
-					if(*buf == 0){
-						ri->loglen = off - ri->logoff;
-						inmsg = 1;
-					}
-				} else {
-					n = ri->why ? strlen(ri->why) : 0;
-					ri->why = realloc(ri->why, n + strlen(buf)+2);
-					if(n > 0) ri->why[n++] = '\n';
-					strcpy(ri->why + n, buf);
-				}
-			}
-			n = e - buf;
-			p -= n;
-			if(p > buf)
-				memmove(buf, e, p - buf);
-			off += n;
-		}
-		e = buf + BUFSZ;
-	}
+	line = Brdstr(buf, '\n', 1);
+	if(line == nil)
+		goto Error;
+	ri->logoff += Blinelen(buf) + 1;
+	ri->who = line;
+
+	line = Brdstr(buf, '\n', 1);
+	if(line == nil)
+		goto Error;
+	ri->logoff += Blinelen(buf) + 1;
+	ri->when = strtol(line, nil, 10);
+	free(line);
+
+	ri->loglen = walklog(buf);
+	if(ri->loglen < 0)
+		goto Error;
+
+	line = Brdstr(buf, '\0', 1);
+	if(line == nil)
+		goto Error;
+	ri->why = line;
+
+	Bterm(buf);
 	close(fd);
+	return ri;
 
-	return ri;
+Error:
+	Bterm(buf);
+	close(fd);
+	free(ri->who);
+	free(ri->why);
+	free(ri);
+	return nil;
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-12-05  8:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05  8:42 hgfs(4) loadrevinfo patch Alex Musolino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).