| Summary: | /bin/sh buildin echo command have invalid implimentation of command args parser | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Vladimir B.Grebenschikov <vova> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.0-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
On Mon, 17 Dec 2001 18:27:02 +0300, "Vladimir B.Grebenschikov" wrote:
> >Number: 32935
> >Category: bin
> >Synopsis: /bin/sh buildin echo command have invalid implimentation of command args parser
I've asked for review on the freebsd-audit mailing list. Hopefully,
you'll get feedback soon.
Ciao,
Sheldon.
On 30-Dec-2001 Sheldon Hearn wrote:
|
| Hi folks,
|
| Could someone check out PR bin/32935, which contains a patch to fix
| ash's builtin echo command so that it accepts the -e and -n options
| combined?
|
Looks ok, except that I think in the '#define eflag 1' case it should
still accept '-ne' as valid and just ignore the 'e'. How about this:
Index: echo.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/bltin/echo.c,v
retrieving revision 1.10
diff -u -r1.10 echo.c
--- echo.c 26 Jun 2000 22:43:30 -0000 1.10
+++ echo.c 31 Dec 2001 08:00:09 -0000
@@ -64,16 +64,28 @@
ap = argv;
if (argc)
ap++;
- if ((p = *ap) != NULL) {
- if (equal(p, "-n")) {
- nflag++;
- ap++;
- } else if (equal(p, "-e")) {
+ if ((p = *ap) != NULL && *p == '-') {
+ ap++;
+ p++;
+ do {
+ if (*p == 'n')
+ nflag++;
+ else if (*p == 'e')
#ifndef eflag
- eflag++;
+ eflag++;
+#else
+ ;
#endif
- ap++;
- }
+ else {
+ nflag = 0;
+#ifndef eflag
+ eflag = 0;
+#endif
+ ap--;
+ break;
+ }
+ } while (*++p != '\0');
+
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
Mike
--
Mike Heffner <mheffner@[acm.]vt.edu>
Fredericksburg, VA <mikeh@FreeBSD.org>
On Mon, 31 Dec 2001 03:05:51 EST, Mike Heffner wrote:
> Looks ok, except that I think in the '#define eflag 1' case it should
> still accept '-ne' as valid and just ignore the 'e'. How about this:
Thanks, Mike.
But why would you want to accept an option that you don't support?
Personally, I don't think -e support needs to be optional. :-)
Ciao,
Sheldon.
On 31-Dec-2001 Sheldon Hearn wrote: | | | On Mon, 31 Dec 2001 03:05:51 EST, Mike Heffner wrote: | |> Looks ok, except that I think in the '#define eflag 1' case it should |> still accept '-ne' as valid and just ignore the 'e'. How about this: | | Thanks, Mike. | | But why would you want to accept an option that you don't support? | | Personally, I don't think -e support needs to be optional. :-) | Well, I guess I'm not sure as to the context of when the defined eflag override is used. IMO, if a shell script is using 'echo -e blah', then it shouldn't break on an 'echo' that has been compiled with the eflag implicitly enabled. Also, I was just following the original broken code, so that the previous test case would work as before. ;) Mike -- Mike Heffner <mheffner@[acm.]vt.edu> Fredericksburg, VA <mikeh@FreeBSD.org> State Changed From-To: open->patched Manual page has been updated to indicate that only one of -n and -e may be specified. The traditional BSD behaviour will not be changed. Consider using printf(1) instead to print escape sequences or omit the trailing newline, it is much more consistent between operating systems. State Changed From-To: patched->closed Change has been MFC'd. |
According to manpage sh(1): echo [-en] string Print string to the standard output with a newline appended. -n Suppress the output of the trailing newline. -e Process C-style backslash escape sequences. echo under- stands the following character escapes: But in realality echo accepts either -n or -e flag but not both simultaneously. Fix: diff -u src/bin/sh/bltin/echo.c:1.9.2.1 src/bin/sh/bltin/echo.c:1.9.2.1.10000.2 -- SWSoft, Moscow Vladimir B. Grebenschikov vova@sw.ru--aPitJT3o4KGa2V3P9FmY1yAnVu1LjqcvzJXIyNHGkS2gQz1g Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" --- src/bin/sh/bltin/echo.c:1.9.2.1 Fri Jun 30 00:51:59 2000 +++ src/bin/sh/bltin/echo.c Mon Dec 17 18:15:23 2001 @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)echo.c 8.2 (Berkeley) 5/4/95 - * $FreeBSD: src/bin/sh/bltin/echo.c,v 1.9.2.1 2000/06/29 20:51:59 mph Exp $ + * $FreeBSD: src/bin/sh/bltin/echo.c,v 1.9.2.1.10000.2 2001/12/17 15:15:23 kmv Exp $ */ /* @@ -64,16 +64,28 @@ ap = argv; if (argc) ap++; - if ((p = *ap) != NULL) { - if (equal(p, "-n")) { - nflag++; - ap++; - } else if (equal(p, "-e")) { + if ((p = *ap) != NULL && *p == '-') { + ap++; + p++; + do { + if (*p == 'n') { + nflag++; + } +#ifndef eflag + else if (*p == 'e') { + eflag++; + } +#endif + else { + nflag = 0; #ifndef eflag - eflag++; + eflag = 0; #endif - ap++; - } + ap--; + break; + } + p++; + } while (*p); } while ((p = *ap++) != NULL) { while ((c = *p++) != '\0') { How-To-Repeat: $ echo -en "\tGGG\nJJJ\nccc" -en \tGGG\nJJJ\nccc $ but: $ echo -e "\tGGG\nJJJ\nccc" GGG JJJ ccc $ $ echo -n "test" test$