bin/95079: [patch] apply(1) dies when there are two %1 in command
Alex Kapranoff
kappa at rambler-co.ru
Wed Mar 29 17:20:19 UTC 2006
>Number: 95079
>Category: bin
>Synopsis: [patch] apply(1) dies when there are two %1 in command
>Confidential: no
>Severity: non-critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Wed Mar 29 17:20:17 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Alex Kapranoff
>Release: FreeBSD 5.2-CURRENT i386
>Organization:
Inner Mongolia
>Environment:
FreeBSD capella.park.rambler.ru 6.1-PRERELEASE FreeBSD 6.1-PRERELEASE #0: Fri Mar 17 16:20:26 MSK 2006 root at capella.park.rambler.ru:/usr/obj/usr/src/sys/CAPELLA2 i386
>Description:
apply(1) was not designed to handle situations when user wants
to use the same argument in the command more than once.
>How-To-Repeat:
% ls
00045qqf.png LinkPotProto.zip
% apply 'echo %1 %1' *
00045qqf.png 00045qqf.png
apply: snprintf() failed: Unknown error: 0
%
>Fix:
manpage patch includes an example.
diff -ru /usr/src/usr.bin/apply/apply.1 ./apply.1
--- /usr/src/usr.bin/apply/apply.1 Mon Jul 25 12:12:13 2005
+++ ./apply.1 Wed Mar 29 21:12:44 2006
@@ -123,7 +123,9 @@
5 times; and
.It Li "apply \'ln %1 /usr/joe\'" *
links all files in the current directory to the directory
-.Pa /usr/joe .
+.Pa /usr/joe ;
+.It Li "apply \'diff %1 %1.bak\'" *
+compares all files in the current directory to their backup copies.
.El
.Sh HISTORY
The
diff -ru /usr/src/usr.bin/apply/apply.c ./apply.c
--- /usr/src/usr.bin/apply/apply.c Wed Apr 28 00:41:25 2004
+++ ./apply.c Wed Mar 29 21:06:28 2006
@@ -66,6 +66,8 @@
size_t clen, cmdsize, l;
char *c, *cmd, *name, *p, *q, *shell, *slashp, *tmpshell;
+ int cn[10];
+
debug = 0;
magic = '%'; /* Default magic char is `%'. */
nargs = -1;
@@ -99,13 +101,15 @@
/*
* The command to run is argv[0], and the args are argv[1..].
* Look for %digit references in the command, remembering the
- * largest one.
+ * largest one and count each %digit.
*/
+ bzero(cn, sizeof cn);
for (n = 0, p = argv[0]; *p != '\0'; ++p)
if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
++p;
if (p[0] - '0' > n)
n = p[0] - '0';
+ ++cn[p[0] - '0'];
}
/*
@@ -187,19 +191,15 @@
* there's enough space to build it.
*/
for (l = strlen(cmd), i = 0; i < nargs; i++)
- l += strlen(argv[i+1]);
+ l += strlen(argv[i+1]) * cn[i];
if (l > clen && (c = realloc(c, clen = l)) == NULL)
err(1, NULL);
/* Expand command argv references. */
for (p = cmd, q = c; *p != '\0'; ++p)
if (p[0] == magic && isdigit(p[1]) && p[1] != '0') {
- offset = snprintf(q, l, "%s",
- argv[(++p)[0] - '0']);
- if ((size_t)offset >= l)
- err(1, "snprintf() failed");
- q += offset;
- l -= offset;
+ strlcpy(q, argv[(++p)[0] - '0'], c + clen - q);
+ q += strlen(q);
} else
*q++ = *p;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list