From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Thu, 5 May 2011 03:48:50 -0700 From: Anthony Martin To: 9fans@9fans.net Message-ID: <20110505104850.GA31074@dinah> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="tKW2IUtsqtDRztdT" Content-Disposition: inline Subject: [9fans] Two bugs in ar Topicbox-Message-UUID: dd65e70a-ead6-11e9-9d60-3106f5b1d025 --tKW2IUtsqtDRztdT Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I was investigating a bug in the Go toolchain's fork of ar(1), called gopack, and I discovered two similar bugs in native ar. 1. With a __.SYMDEF file of size (2*n)+1 bytes, the size given in the header will incorrectly include the padding byte. 2. When writing an archive member file to disk, the odd-size check occurs before the write which will access one byte past the end of the buffer containing the member data. The solution for both errors is to check for an odd size after the write, not before. A patch is attached. I also modified the code to properly insert a newline character between archive members when necessary, in accordance with the ar(6) man page. Anthony --tKW2IUtsqtDRztdT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ar.diff" --- /n/sources/sys/src/cmd/ar.c 2010-01-21 16:16:47.000000000 -0800 +++ ar.c 2011-05-05 03:15:19.000000000 -0700 @@ -827,8 +827,6 @@ Bseek(&b,seek(fd,0,1), 0); len = symdefsize; - if(len&01) - len++; sprint(a.date, "%-12ld", time(0)); sprint(a.uid, "%-6d", 0); sprint(a.gid, "%-6d", 0); @@ -842,6 +840,8 @@ if(HEADER_IO(Bwrite, &b, a)) wrerr(); + if(len&01) + len++; len += Boffset(&b); if (astart) { wrsym(&b, len, astart->sym); @@ -855,7 +855,7 @@ wrsym(&b, len, aend->sym); if(symdefsize&0x01) - Bputc(&b, 0); + Bputc(&b, '\n'); Bterm(&b); } @@ -1121,10 +1121,12 @@ if(HEADER_IO(write, fd, bp->hdr)) return 0; len = bp->size; - if (len & 01) - len++; if (write(fd, bp->member, len) != len) return 0; + if (len & 01) { + if(write(fd, "\n", 1) != 1) + return 0; + } return 1; } --tKW2IUtsqtDRztdT--