9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Alex Musolino <alex@musolino.id.au>
To: 9front@9front.org
Subject: hgfs(4) loadrevinfo patch
Date: Thu, 5 Dec 2019 19:12:44 +1030	[thread overview]
Message-ID: <B6E80A0E7E51001263231F8A26EDC4FB@musolino.id.au> (raw)

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


                 reply	other threads:[~2019-12-05  8:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=B6E80A0E7E51001263231F8A26EDC4FB@musolino.id.au \
    --to=alex@musolino.id.au \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).