From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from vultr.musolino.id.au ([45.76.123.158]) by ewsd; Thu Dec 5 03:43:05 EST 2019 Received: from 121.45.60.200 ([121.45.60.200]) by vultr; Thu Dec 5 19:42:48 EST 2019 Message-ID: To: 9front@9front.org Subject: hgfs(4) loadrevinfo patch From: Alex Musolino Date: Thu, 5 Dec 2019 19:12:44 +1030 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: lossless realtime-java out-scaling-oriented DOM CMS callback locator 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 #include #include +#include #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; }