diff options
author | jilles <jilles@FreeBSD.org> | 2014-01-24 16:40:51 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2014-01-24 16:40:51 +0000 |
commit | 5b4046f60ff315a314f4701a931290673b290ab0 (patch) | |
tree | d6e682f9ba5ef0ef4b1fb8b97f04a0c2e7954236 /bin | |
parent | 2c9e5787396110f19fad35555faec78015a6ffd8 (diff) | |
download | FreeBSD-src-5b4046f60ff315a314f4701a931290673b290ab0.zip FreeBSD-src-5b4046f60ff315a314f4701a931290673b290ab0.tar.gz |
sh: Solve the alias recursion problem in a less hackish way.
Add the space to avoid alias recursion when the alias is expanded, not when
it is added.
As a result, displaying an alias via command -v, command -V or type no
longer erroneously appends a space. Adjust the tests so they now require
this bug to be absent.
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/alias.c | 44 | ||||
-rw-r--r-- | bin/sh/input.c | 9 | ||||
-rw-r--r-- | bin/sh/tests/builtins/command3.0.stdout | 2 | ||||
-rw-r--r-- | bin/sh/tests/builtins/command5.0.stdout | 2 | ||||
-rw-r--r-- | bin/sh/tests/builtins/command6.0.stdout | 2 |
5 files changed, 11 insertions, 48 deletions
diff --git a/bin/sh/alias.c b/bin/sh/alias.c index 044c869..9ebdcb5 100644 --- a/bin/sh/alias.c +++ b/bin/sh/alias.c @@ -68,18 +68,7 @@ setalias(const char *name, const char *val) if (equal(name, ap->name)) { INTOFF; ckfree(ap->val); - /* See HACK below. */ -#ifdef notyet ap->val = savestr(val); -#else - { - size_t len = strlen(val); - ap->val = ckmalloc(len + 2); - memcpy(ap->val, val, len); - ap->val[len] = ' '; - ap->val[len+1] = '\0'; - } -#endif INTON; return; } @@ -88,34 +77,7 @@ setalias(const char *name, const char *val) INTOFF; ap = ckmalloc(sizeof (struct alias)); ap->name = savestr(name); - /* - * XXX - HACK: in order that the parser will not finish reading the - * alias value off the input before processing the next alias, we - * dummy up an extra space at the end of the alias. This is a crock - * and should be re-thought. The idea (if you feel inclined to help) - * is to avoid alias recursions. The mechanism used is: when - * expanding an alias, the value of the alias is pushed back on the - * input as a string and a pointer to the alias is stored with the - * string. The alias is marked as being in use. When the input - * routine finishes reading the string, it marks the alias not - * in use. The problem is synchronization with the parser. Since - * it reads ahead, the alias is marked not in use before the - * resulting token(s) is next checked for further alias sub. The - * H A C K is that we add a little fluff after the alias value - * so that the string will not be exhausted. This is a good - * idea ------- ***NOT*** - */ -#ifdef notyet ap->val = savestr(val); -#else /* hack */ - { - size_t len = strlen(val); - ap->val = ckmalloc(len + 2); - memcpy(ap->val, val, len); - ap->val[len] = ' '; /* fluff */ - ap->val[len+1] = '\0'; - } -#endif ap->flag = 0; ap->next = *app; *app = ap; @@ -207,14 +169,8 @@ comparealiases(const void *p1, const void *p2) static void printalias(const struct alias *a) { - char *p; - out1fmt("%s=", a->name); - /* Don't print the space added above. */ - p = a->val + strlen(a->val) - 1; - *p = '\0'; out1qstr(a->val); - *p = ' '; out1c('\n'); } diff --git a/bin/sh/input.c b/bin/sh/input.c index 94fbd79..da225bc 100644 --- a/bin/sh/input.c +++ b/bin/sh/input.c @@ -226,7 +226,14 @@ preadbuffer(void) int more; char savec; - if (parsefile->strpush) { + while (parsefile->strpush) { + /* + * Add a space to the end of an alias to ensure that the + * alias remains in use while parsing its last word. + * This avoids alias recursions. + */ + if (parsenleft == -1 && parsefile->strpush->ap != NULL) + return ' '; popstring(); if (--parsenleft >= 0) return (*parsenextc++); diff --git a/bin/sh/tests/builtins/command3.0.stdout b/bin/sh/tests/builtins/command3.0.stdout index 239c53f..67b8691 100644 --- a/bin/sh/tests/builtins/command3.0.stdout +++ b/bin/sh/tests/builtins/command3.0.stdout @@ -4,4 +4,4 @@ true fun break if -alias foo='bar ' +alias foo=bar diff --git a/bin/sh/tests/builtins/command5.0.stdout b/bin/sh/tests/builtins/command5.0.stdout index 4cb2b11..523f7b2 100644 --- a/bin/sh/tests/builtins/command5.0.stdout +++ b/bin/sh/tests/builtins/command5.0.stdout @@ -5,4 +5,4 @@ fun is a shell function break is a special shell builtin if is a shell keyword { is a shell keyword -foo is an alias for bar +foo is an alias for bar diff --git a/bin/sh/tests/builtins/command6.0.stdout b/bin/sh/tests/builtins/command6.0.stdout index df4d647..3180207 100644 --- a/bin/sh/tests/builtins/command6.0.stdout +++ b/bin/sh/tests/builtins/command6.0.stdout @@ -4,4 +4,4 @@ fun is a shell function break is a special shell builtin if is a shell keyword { is a shell keyword -foo is an alias for bar +foo is an alias for bar |