Module Name: src Committed By: kre Date: Thu Oct 31 01:50:20 UTC 2024
Modified Files: src/usr.bin/ctags: ctags.c Log Message: PR bin/58786 Partly fix ctags -u processing RVP pointed out that the command in the previous version to remove old entries from the tags file would fail, if some were not there (-u being used to add a new file's tags) as grep exits 1 when the pattern is not found. (The original version would almost never fail, even when it should have, as its status was just from the final "rm" command). So make the command more complex to deal with that. While there, do away with the OTAGS nonsense, and use mktemp(1) instead. Also do away with the absurdly short 100 byte command buffer, and use asprintf() instead. And also properly quote strings being passed to system(3) (why the code needs to use system(3) at all is an entirely different question). There are still oh so many weirdnesses in this program, but when used in the typical way, it should be no worse than it ever was. XXX no pullups intended To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/usr.bin/ctags/ctags.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/ctags/ctags.c diff -u src/usr.bin/ctags/ctags.c:1.17 src/usr.bin/ctags/ctags.c:1.18 --- src/usr.bin/ctags/ctags.c:1.17 Wed Oct 30 11:37:00 2024 +++ src/usr.bin/ctags/ctags.c Thu Oct 31 01:50:20 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ctags.c,v 1.17 2024/10/30 11:37:00 kre Exp $ */ +/* $NetBSD: ctags.c,v 1.18 2024/10/31 01:50:20 kre Exp $ */ /* * Copyright (c) 1987, 1993, 1994, 1995 @@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 19 #if 0 static char sccsid[] = "@(#)ctags.c 8.4 (Berkeley) 2/7/95"; #endif -__RCSID("$NetBSD: ctags.c,v 1.17 2024/10/30 11:37:00 kre Exp $"); +__RCSID("$NetBSD: ctags.c,v 1.18 2024/10/31 01:50:20 kre Exp $"); #endif /* not lint */ #include <err.h> @@ -92,7 +92,9 @@ main(int argc, char **argv) int exit_val; /* exit value */ int step; /* step through args */ int ch; /* getopts char */ - char cmd[100]; /* too ugly to explain */ + char *cmd; /* not nice */ + char tname[128]; /* disgusting */ + size_t sz; aflag = uflag = NO; while ((ch = getopt(argc, argv, "BFadf:tuwvx")) != -1) @@ -139,6 +141,16 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } + if ((sz = shquote(outfile, tname, sizeof tname)) >= sizeof tname) { + /* nb: (size_t)-1 > sizeof tname */ + if (sz == (size_t)-1) + err(EXIT_FAILURE, "Output file name '%s' too long", + outfile); + else + errx(EXIT_FAILURE, "Output file name '%s' too long", + outfile); + } + init(); exit_val = EXIT_SUCCESS; @@ -159,20 +171,46 @@ main(int argc, char **argv) else { if (uflag) { for (step = 0; step < argc; step++) { - if (snprintf(cmd, sizeof(cmd), - "mv %s OTAGS &&\n" - "\tfgrep -v '\t%s\t' OTAGS >%s &&" - "\n\trm OTAGS", - outfile, argv[step], outfile) - >= (int)sizeof(cmd)) - errx(EXIT_FAILURE, + char pattern[140]; + + if (asprintf(&cmd, "\t%s\t", + argv[step]) == -1) + err(EXIT_FAILURE, + "Cannot generate '\\t%s\\t'", + argv[step]); + + if ((sz = shquote(cmd, pattern, + sizeof pattern)) >= sizeof pattern) + { + if (sz == (size_t)-1) + err(EXIT_FAILURE, "'%s': " + "quoting pattern", cmd); + else + errx(EXIT_FAILURE, "'%s': " + "failed to quote", cmd); + } + (void)free(cmd); + + if (asprintf(&cmd, + "OTAGS=$(mktemp -t tags.$$) || exit\n" + "\ttest -n \"${OTAGS}\" || exit\n" + "\ttrap 'rm -f \"${OTAGS}\"' EXIT\n" + "\tmv %s \"${OTAGS}\" || exit\n" + "\tfgrep -v %s \"${OTAGS}\" >%s\n" + "\tX=$? ; " + "test \"$X\" -le 1 || exit $X", + tname, pattern, tname) == -1) + err(EXIT_FAILURE, "Command to update %s for -u" - " %s too long", + " %s", argv[step], outfile); - if (system(cmd) != 0) + + if (system(cmd) != 0) errx(EXIT_FAILURE, "Update (-u) of %s failed. " "Cmd:\n %s", outfile, cmd); + + (void)free(cmd); } ++aflag; } @@ -184,14 +222,15 @@ main(int argc, char **argv) err(EXIT_FAILURE, "output error (%s)", outfile); (void)fclose(outf); if (uflag) { - if (snprintf(cmd, sizeof(cmd), "sort -o %s %s", - outfile, outfile) >= (int)sizeof(cmd)) - errx(EXIT_FAILURE, - "sort command (-u) for %s too long", + if (asprintf(&cmd, "sort -o %s %s", + tname, tname) == -1) + err(EXIT_FAILURE, + "sort command (-u) for %s", outfile); if (system(cmd) != 0) errx(EXIT_FAILURE, "-u: sort %s failed" "\t[ %s ]", outfile, cmd); + (void)free(cmd); } } }