diff options
author | 2020-08-30 12:16:04 +0000 | |
---|---|---|
committer | 2020-08-30 12:16:04 +0000 | |
commit | e33a93b366a4785a5c945b221f3b41942da39c59 (patch) | |
tree | 5ca7e4d45fe6928d9597c70f33f96078eaa14add | |
parent | avoid a invalid pointer deref in hvn_stop() (diff) | |
download | wireguard-openbsd-e33a93b366a4785a5c945b221f3b41942da39c59.tar.xz wireguard-openbsd-e33a93b366a4785a5c945b221f3b41942da39c59.zip |
Fix :S with anchors and replacement
gnezdo noticed that :S/old_string/new_string/ variable modifiers such
as :S/^sth/&/ and :S/sth$/&/ with an anchor in the old_string and an &
in the new_string don't work as documented (and expected) since they
replace & with old_string including the anchors.
This is because get_spatternarg() deals with skipping the anchors in
pattern->lhs only after having replaced any '&' in the buffer that will
eventually become new_string with pattern->lhs. Fix this by moving the
logic of skipping the anchors from get_spatternarg() into
common_get_patternarg() so it is done before & is handled.
ok millert
-rw-r--r-- | usr.bin/make/varmodifiers.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/usr.bin/make/varmodifiers.c b/usr.bin/make/varmodifiers.c index df642971ef8..1cbcfe8e7d1 100644 --- a/usr.bin/make/varmodifiers.c +++ b/usr.bin/make/varmodifiers.c @@ -1,4 +1,4 @@ -/* $OpenBSD: varmodifiers.c,v 1.47 2017/07/10 07:10:29 bluhm Exp $ */ +/* $OpenBSD: varmodifiers.c,v 1.48 2020/08/30 12:16:04 tb Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* @@ -1215,21 +1215,7 @@ get_patternarg(const char **p, SymTable *ctxt, bool err, int endc) static void * get_spatternarg(const char **p, SymTable *ctxt, bool err, int endc) { - VarPattern *pattern; - - pattern = common_get_patternarg(p, ctxt, err, endc, true); - if (pattern != NULL && pattern->leftLen > 0) { - if (pattern->lhs[pattern->leftLen-1] == '$') { - pattern->leftLen--; - pattern->flags |= VAR_MATCH_END; - } - if (pattern->lhs[0] == '^') { - pattern->lhs++; - pattern->leftLen--; - pattern->flags |= VAR_MATCH_START; - } - } - return pattern; + return common_get_patternarg(p, ctxt, err, endc, true); } static void @@ -1304,6 +1290,17 @@ common_get_patternarg(const char **p, SymTable *ctxt, bool err, int endc, &pattern->leftLen, NULL); pattern->lbuffer = pattern->lhs; if (pattern->lhs != NULL) { + if (dosubst && pattern->leftLen > 0) { + if (pattern->lhs[pattern->leftLen-1] == '$') { + pattern->leftLen--; + pattern->flags |= VAR_MATCH_END; + } + if (pattern->lhs[0] == '^') { + pattern->lhs++; + pattern->leftLen--; + pattern->flags |= VAR_MATCH_START; + } + } pattern->rhs = VarGetPattern(ctxt, err, &s, delim, delim, &pattern->rightLen, dosubst ? pattern: NULL); if (pattern->rhs != NULL) { |