grep: fix -x -v with certain pattern orders

We found out that busybox -x -v is a bit broken:

ari@ari-thinkpad:~/busybox$ echo '  aa bb cc' | ./busybox grep -x -e 'aa.*' -e '.*bb.*'
  aa bb cc
ari@ari-thinkpad:~/busybox$ echo '  aa bb cc' | ./busybox grep -x -v -e 'aa.*' -e '.*bb.*'
ari@ari-thinkpad:~/busybox$ echo '  aa bb cc' | ./busybox grep -x -e '.*aa.*' -e 'bb.*'
  aa bb cc
ari@ari-thinkpad:~/busybox$ echo '  aa bb cc' | ./busybox grep -x -v -e '.*aa.*' -e 'bb.*'
  aa bb cc

Last one is wrong.

This patch fixes the issue by making sure that the variable 'found'
never makes a transition from 1 to 0, as this would mean that
grep previously found a match on this input line.

Signed-off-by: Ari Sundholm <ari@tuxera.com>
Signed-off-by: Niko Vähäsarja <niko@tuxera.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ari Sundholm 2019-01-29 14:42:57 +01:00 committed by Denys Vlasenko
parent 53799506ac
commit 9a9c6e39ba
2 changed files with 8 additions and 1 deletions

View File

@ -404,7 +404,7 @@ static int grep_file(FILE *file)
#endif #endif
) { ) {
if (option_mask32 & OPT_x) { if (option_mask32 & OPT_x) {
found = (gl->matched_range.rm_so == 0 found |= (gl->matched_range.rm_so == 0
&& match_at[gl->matched_range.rm_eo] == '\0'); && match_at[gl->matched_range.rm_eo] == '\0');
} else } else
if (!(option_mask32 & OPT_w)) { if (!(option_mask32 & OPT_w)) {

View File

@ -177,6 +177,13 @@ testing "grep -w word match second word" \
"bword,word\n""wordb,word\n""bwordb,word\n" \ "bword,word\n""wordb,word\n""bwordb,word\n" \
"" ""
testing "grep -x -v -e EXP1 -e EXP2 finds nothing if either EXP matches" \
"grep -x -v -e '.*aa.*' -e 'bb.*'; echo \$?" \
"1\n" \
"" \
" aa bb cc\n"
# -r on symlink to dir should recurse into dir # -r on symlink to dir should recurse into dir
mkdir -p grep.testdir/foo mkdir -p grep.testdir/foo
echo bar > grep.testdir/foo/file echo bar > grep.testdir/foo/file