From 3c2a6d3622707d53b254b71df5b73e8a465d03b5 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 9 Dec 2018 21:14:04 -0600 Subject: Support embedded NUL bytes in grep output, and free memory leaked per-file. --- toys/posix/grep.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'toys') diff --git a/toys/posix/grep.c b/toys/posix/grep.c index 5daccabc..3b3b674e 100644 --- a/toys/posix/grep.c +++ b/toys/posix/grep.c @@ -79,8 +79,11 @@ static void outline(char *line, char dash, char *name, long lcount, long bcount, if (!line || (lcount && (toys.optflags&FLAG_n))) printf("%ld%c", lcount, line ? dash : TT.outdelim); if (bcount && (toys.optflags&FLAG_b)) printf("%ld%c", bcount-1, dash); -// Support embedded NUL bytes in output - if (line) xprintf("%.*s%c", trim, line, TT.outdelim); + if (line) { + // support embedded NUL bytes in output + fwrite(line, 1, trim, stdout); + xputc(TT.outdelim); + } } // Show matches in one file @@ -234,15 +237,15 @@ static void do_grep(int fd, char *name) else if (!(toys.optflags & FLAG_o)) { while (dlb) { struct double_list *dl = dlist_pop(&dlb); + unsigned *uu = (void *)(dl->data+((strlen(dl->data)+1)|3)+1); - outline(dl->data, '-', name, lcount-before, - *(unsigned *)(dl->data+((strlen(dl->data)+1)|3)+1)+1, -1); + outline(dl->data, '-', name, lcount-before, uu[0]+1, uu[1]); free(dl->data); free(dl); before--; } - outline(line, ':', name, lcount, bcount, -1); + outline(line, ':', name, lcount, bcount, ulen); if (TT.A) after = TT.A+1; } else outline(start+matches.rm_so, ':', name, lcount, bcount, matches.rm_eo-matches.rm_so); @@ -258,14 +261,16 @@ static void do_grep(int fd, char *name) int discard = (after || TT.B); if (after && --after) { - outline(line, '-', name, lcount, 0, -1); + outline(line, '-', name, lcount, 0, ulen); discard = 0; } if (discard && TT.B) { - if (FLAG(b)) { - line = xrealloc(line, (ulen|3)+4); - *(unsigned *)(line+(ulen|3)+1) = offset-len; - } + unsigned *uu, ul = (ulen+1)|3; + + line = xrealloc(line, ul+8); + uu = (void *)(line+ul+1); + uu[0] = offset-len; + uu[1] = ulen; dlist_add(&dlb, line); line = 0; if (++before>TT.B) { @@ -290,6 +295,12 @@ static void do_grep(int fd, char *name) // loopfiles will also close the fd, but this frees an (opaque) struct. fclose(file); + while (dlb) { + struct double_list *dl = dlist_pop(&dlb); + + free(dl->data); + free(dl); + } } static void parse_regex(void) -- cgit v1.2.3