aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSören Tempel <soeren+git@soeren-tempel.net>2020-03-30 11:02:08 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2020-04-30 00:20:18 +0200
commit42a8984abc5eed709addac263aab43d64d47257d (patch)
tree94ca67b5972f991b805073ed6aefbac23b36b96c
parentc3295d233b6a7d924814eec9a5c5999a876daf9e (diff)
downloadbusybox-w32-42a8984abc5eed709addac263aab43d64d47257d.tar.gz
busybox-w32-42a8984abc5eed709addac263aab43d64d47257d.tar.bz2
busybox-w32-42a8984abc5eed709addac263aab43d64d47257d.zip
grep: add proper support for pattern_list
From POSIX.1-2008: The pattern_list's value shall consist of one or more patterns separated by <newline> characters; As such, given patterns need to be split at newline characters. Without doing so, busybox grep will interpret the newline as part of the pattern which is not in accordance with POSIX. See also: https://bugs.busybox.net/show_bug.cgi?id=12721 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--findutils/grep.c19
-rwxr-xr-xtestsuite/grep.tests12
2 files changed, 25 insertions, 6 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index 84a6f7b1c..55e9c0a8f 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -650,6 +650,13 @@ static void load_regexes_from_file(llist_t *fopt)
650 } 650 }
651} 651}
652 652
653static void load_pattern_list(llist_t **lst, char *pattern)
654{
655 char *p;
656 while ((p = strsep(&pattern, "\n")) != NULL)
657 llist_add_to(lst, new_grep_list_data(p, 0));
658}
659
653static int FAST_FUNC file_action_grep(const char *filename, 660static int FAST_FUNC file_action_grep(const char *filename,
654 struct stat *statbuf, 661 struct stat *statbuf,
655 void* matched, 662 void* matched,
@@ -754,10 +761,12 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
754#endif 761#endif
755 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ 762 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */
756 763
757 { /* convert char **argv to grep_list_data_t */ 764 { /* convert char **argv to pattern_list */
758 llist_t *cur; 765 llist_t *cur, *new = NULL;
759 for (cur = pattern_head; cur; cur = cur->link) 766 for (cur = pattern_head; cur; cur = cur->link)
760 cur->data = new_grep_list_data(cur->data, 0); 767 load_pattern_list(&new, cur->data);
768 llist_free(pattern_head, NULL);
769 pattern_head = new;
761 } 770 }
762 if (option_mask32 & OPT_f) { 771 if (option_mask32 & OPT_f) {
763 load_regexes_from_file(fopt); 772 load_regexes_from_file(fopt);
@@ -806,11 +815,9 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
806 /* if we didn't get a pattern from -e and no command file was specified, 815 /* if we didn't get a pattern from -e and no command file was specified,
807 * first parameter should be the pattern. no pattern, no worky */ 816 * first parameter should be the pattern. no pattern, no worky */
808 if (pattern_head == NULL) { 817 if (pattern_head == NULL) {
809 char *pattern;
810 if (*argv == NULL) 818 if (*argv == NULL)
811 bb_show_usage(); 819 bb_show_usage();
812 pattern = new_grep_list_data(*argv++, 0); 820 load_pattern_list(&pattern_head, *argv++);
813 llist_add_to(&pattern_head, pattern);
814 } 821 }
815 822
816 /* argv[0..(argc-1)] should be names of file to grep through. If 823 /* argv[0..(argc-1)] should be names of file to grep through. If
diff --git a/testsuite/grep.tests b/testsuite/grep.tests
index 9c1f35499..e38278810 100755
--- a/testsuite/grep.tests
+++ b/testsuite/grep.tests
@@ -190,6 +190,18 @@ testing "grep -x -v -e EXP1 -e EXP2 finds nothing if either EXP matches" \
190 "" \ 190 "" \
191 " aa bb cc\n" 191 " aa bb cc\n"
192 192
193testing "grep PATTERN can be a newline-delimited list" \
194 'grep -Fv "$(printf "foo\nbar\n")"' \
195 "baz\n" \
196 "" \
197 "foo\nbar\nbaz\n"
198
199testing "grep -e PATTERN can be a newline-delimited list" \
200 'grep -Fv -e "$(printf "foo\nbar\n")"' \
201 "baz\n" \
202 "" \
203 "foo\nbar\nbaz\n"
204
193# -r on symlink to dir should recurse into dir 205# -r on symlink to dir should recurse into dir
194mkdir -p grep.testdir/foo 206mkdir -p grep.testdir/foo
195echo bar > grep.testdir/foo/file 207echo bar > grep.testdir/foo/file