Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Aug 2017 00:12:22 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r322555 - in stable/11: contrib/netbsd-tests/usr.bin/grep usr.bin/grep usr.bin/grep/tests
Message-ID:  <201708160012.v7G0CMMl024686@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Wed Aug 16 00:12:22 2017
New Revision: 322555
URL: https://svnweb.freebsd.org/changeset/base/322555

Log:
  bsdgrep: Fix matching behavior and add regression tests
  
  MFC r316477: bsdgrep: fix matching behaviour
  
  - Set REG_NOTBOL if we've already matched beginning of line and we're
    examining later parts
  
  - For each pattern we examine, apply it to the remaining bits of the
    line rather than (potentially) smaller subsets
  
  - Check for REG_NOSUB after we've looked at all patterns initially
    matching the line
  
  - Keep track of the last match we made to later determine if we're
    simply not matching any longer or if we need to proceed another byte
    because we hit a zero-length match
  
  - Match the earliest and longest bit of each line before moving the
    beginning of what we match to further in the line, past the end of the
    longest match; this generally matches how gnugrep(1) seems to behave,
    and seems like pretty good behavior to me
  
  - Finally, bail out of printing any matches if we were set to print all
    (empty pattern) but -o (output matches) was set
  
  MFC r316489: bsdgrep: Initialize vars to avoid a false positive GCC warning
  
  MFC r316491: bsdgrep: revert color changes from r316477
  
  r316477 changed the color output to match exactly the in-tree GNU grep,
  but introduces unnecessary escape sequences.
  
  MFC r316536: bsdgrep: create additional tests for coverage on recent fixes
  
  Create additional tests to cover regressions that were discovered by
  PRs linked to reviews D10098, D10102, and D10104.
  
  It is worth noting that neither bsdgrep(1) nor gnugrep(1) in the base
  system currently pass all of these tests, and gnugrep(1) not quite being
  up to snuff was also noted in at least one of the PRs.
  
  MFC r317052: bsdgrep: fix zero-length matches without the -o flag
  
  r316477 broke zero-length matches when not using the -o flag, by
  skipping over them entirely.
  
  Add a regression test so that it doesn't break again in the future.
  
  PR:		175314, 180990, 181263, 195763, 197531, 197555, 202022, 209116
  Approved by:	emaste (mentor, blanket MFC)
  Relnotes:	yes

Added:
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_c.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_c.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_escmap.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_escmap.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in
  stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out
     - copied unchanged from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out
Modified:
  stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
  stable/11/usr.bin/grep/tests/Makefile
  stable/11/usr.bin/grep/util.c
Directory Properties:
  stable/11/   (props changed)

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.in)
@@ -0,0 +1 @@
+abcd*

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_a.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_a.out)
@@ -0,0 +1 @@
+abcd*

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.in)
@@ -0,0 +1,5 @@
+fojeiwuroiuwet
+ljfajsljkfabcdddjlfkajlkj
+abcaaa
+zzzabc
+

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_b.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_b.out)
@@ -0,0 +1,3 @@
+ljfajsljkfabcdddjlfkajlkj
+abcaaa
+zzzabc

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_c.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_c.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_color_c.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_color_c.out)
@@ -0,0 +1,3 @@
+ljfajsljkfabcdddjlfkajlkj
+abcaaa
+zzzabc

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_escmap.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_escmap.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_escmap.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_escmap.in)
@@ -0,0 +1 @@
+f.oo

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_f_file_empty.in)
@@ -0,0 +1,2 @@
+Fish zebra monkey suits
+

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.in)
@@ -0,0 +1 @@
+01:1:01

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_a.out)
@@ -0,0 +1,3 @@
+0
+:
+:0

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.in)
@@ -0,0 +1 @@
+1:1:01

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_b.out)
@@ -0,0 +1,2 @@
+:
+:0

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.in)
@@ -0,0 +1 @@
+bla bla

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_c.out)
@@ -0,0 +1,2 @@
+bla
+bla

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_d.in)
@@ -0,0 +1,3 @@
+bla
+bla
+

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.in)
@@ -0,0 +1 @@
+abcdef

Copied: stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out (from r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out	Wed Aug 16 00:12:22 2017	(r322555, copy of r316536, head/contrib/netbsd-tests/usr.bin/grep/d_oflag_zerolen_e.out)
@@ -0,0 +1 @@
+ab

Modified: stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
==============================================================================
--- stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh	Wed Aug 16 00:04:57 2017	(r322554)
+++ stable/11/contrib/netbsd-tests/usr.bin/grep/t_grep.sh	Wed Aug 16 00:12:22 2017	(r322555)
@@ -226,10 +226,116 @@ context2_body()
 	atf_check -o file:"$(atf_get_srcdir)/d_context2_c.out" \
 	    grep -z -C1 cod test1 test2
 }
+# Begin FreeBSD
+atf_test_case oflag_zerolen
+oflag_zerolen_head()
+{
+	atf_set "descr" "Check behavior of zero-length matches with -o flag (PR 195763)"
+}
+oflag_zerolen_body()
+{
+	atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_a.out" \
+	    grep -Eo '(^|:)0*' "$(atf_get_srcdir)/d_oflag_zerolen_a.in"
 
+	atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_b.out" \
+	    grep -Eo '(^|:)0*' "$(atf_get_srcdir)/d_oflag_zerolen_b.in"
+
+	atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_c.out" \
+	    grep -Eo '[[:alnum:]]*' "$(atf_get_srcdir)/d_oflag_zerolen_c.in"
+
+	atf_check -o empty grep -Eo '' "$(atf_get_srcdir)/d_oflag_zerolen_d.in"
+
+	atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_e.out" \
+	    grep -o -e 'ab' -e 'bc' "$(atf_get_srcdir)/d_oflag_zerolen_e.in"
+
+	atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_e.out" \
+	    grep -o -e 'bc' -e 'ab' "$(atf_get_srcdir)/d_oflag_zerolen_e.in"
+}
+
+atf_test_case xflag
+xflag_head()
+{
+	atf_set "descr" "Check that we actually get a match with -x flag (PR 180990)"
+}
+xflag_body()
+{
+	echo 128 > match_file
+	seq 1 128 > pattern_file
+	grep -xf pattern_file match_file
+}
+
+atf_test_case color
+color_head()
+{
+	atf_set "descr" "Check --color support"
+}
+color_body()
+{
+	echo 'abcd*' > grepfile
+	echo 'abc$' >> grepfile
+	echo '^abc' >> grepfile
+
+	atf_check -o file:"$(atf_get_srcdir)/d_color_a.out" \
+	    grep --color=auto -e '.*' -e 'a' "$(atf_get_srcdir)/d_color_a.in"
+
+	atf_check -o file:"$(atf_get_srcdir)/d_color_b.out" \
+	    grep --color=auto -f grepfile "$(atf_get_srcdir)/d_color_b.in"
+
+	atf_check -o file:"$(atf_get_srcdir)/d_color_c.out" \
+	    grep --color=always -f grepfile "$(atf_get_srcdir)/d_color_b.in"
+}
+
+atf_test_case f_file_empty
+f_file_empty_head()
+{
+	atf_set "descr" "Check for handling of a null byte in empty file, specified by -f (PR 202022)"
+}
+f_file_empty_body()
+{
+	printf "\0\n" > nulpat
+
+	atf_check -s exit:1 grep -f nulpat "$(atf_get_srcdir)/d_f_file_empty.in"
+}
+
+atf_test_case escmap
+escmap_head()
+{
+	atf_set "descr" "Check proper handling of escaped vs. unescaped dot expressions (PR 175314)"
+}
+escmap_body()
+{
+	atf_check -s exit:1 grep -o 'f.o\.' "$(atf_get_srcdir)/d_escmap.in"
+	atf_check -o not-empty grep -o 'f.o.' "$(atf_get_srcdir)/d_escmap.in"
+}
+
+atf_test_case egrep_empty_invalid
+egrep_empty_invalid_head()
+{
+	atf_set "descr" "Check for handling of an invalid empty pattern (PR 194823)"
+}
+egrep_empty_invalid_body()
+{
+	atf_check -s exit:1 egrep '{' /dev/null
+}
+
+atf_test_case zerolen
+zerolen_head()
+{
+	atf_set "descr" "Check for successful zero-length matches with ^$"
+}
+zerolen_body()
+{
+	printf "Eggs\n\nCheese" > test1
+
+	atf_check -o inline:"\n" grep -e "^$" test1
+
+	atf_check -o inline:"Eggs\nCheese\n" grep -v -e "^$" test1
+}
+# End FreeBSD
+
 atf_init_test_cases()
 {
-	atf_add_test_case basic 
+	atf_add_test_case basic
 	atf_add_test_case binary
 	atf_add_test_case recurse
 	atf_add_test_case recurse_symlink
@@ -245,4 +351,13 @@ atf_init_test_cases()
 	atf_add_test_case zgrep
 	atf_add_test_case nonexistent
 	atf_add_test_case context2
+# Begin FreeBSD
+	atf_add_test_case oflag_zerolen
+	atf_add_test_case xflag
+	atf_add_test_case color
+	atf_add_test_case f_file_empty
+	atf_add_test_case escmap
+	atf_add_test_case egrep_empty_invalid
+	atf_add_test_case zerolen
+# End FreeBSD
 }

Modified: stable/11/usr.bin/grep/tests/Makefile
==============================================================================
--- stable/11/usr.bin/grep/tests/Makefile	Wed Aug 16 00:04:57 2017	(r322554)
+++ stable/11/usr.bin/grep/tests/Makefile	Wed Aug 16 00:12:22 2017	(r322555)
@@ -8,6 +8,11 @@ ${PACKAGE}FILES+=		d_basic.out
 ${PACKAGE}FILES+=		d_begin_end_a.out
 ${PACKAGE}FILES+=		d_begin_end_b.out
 ${PACKAGE}FILES+=		d_binary.out
+${PACKAGE}FILES+=		d_color_a.in
+${PACKAGE}FILES+=		d_color_a.out
+${PACKAGE}FILES+=		d_color_b.in
+${PACKAGE}FILES+=		d_color_b.out
+${PACKAGE}FILES+=		d_color_c.out
 ${PACKAGE}FILES+=		d_context2_a.out
 ${PACKAGE}FILES+=		d_context2_b.out
 ${PACKAGE}FILES+=		d_context2_c.out
@@ -18,12 +23,23 @@ ${PACKAGE}FILES+=		d_context_b.out
 ${PACKAGE}FILES+=		d_context_c.out
 ${PACKAGE}FILES+=		d_context_d.out
 ${PACKAGE}FILES+=		d_egrep.out
+${PACKAGE}FILES+=		d_escmap.in
+${PACKAGE}FILES+=		d_f_file_empty.in
 ${PACKAGE}FILES+=		d_file_exp.in
 ${PACKAGE}FILES+=		d_file_exp.out
 ${PACKAGE}FILES+=		d_ignore_case.out
 ${PACKAGE}FILES+=		d_input
 ${PACKAGE}FILES+=		d_invert.in
 ${PACKAGE}FILES+=		d_invert.out
+${PACKAGE}FILES+=		d_oflag_zerolen_a.in
+${PACKAGE}FILES+=		d_oflag_zerolen_a.out
+${PACKAGE}FILES+=		d_oflag_zerolen_b.in
+${PACKAGE}FILES+=		d_oflag_zerolen_b.out
+${PACKAGE}FILES+=		d_oflag_zerolen_c.in
+${PACKAGE}FILES+=		d_oflag_zerolen_c.out
+${PACKAGE}FILES+=		d_oflag_zerolen_d.in
+${PACKAGE}FILES+=		d_oflag_zerolen_e.in
+${PACKAGE}FILES+=		d_oflag_zerolen_e.out
 ${PACKAGE}FILES+=		d_recurse.out
 ${PACKAGE}FILES+=		d_recurse_symlink.err
 ${PACKAGE}FILES+=		d_recurse_symlink.out

Modified: stable/11/usr.bin/grep/util.c
==============================================================================
--- stable/11/usr.bin/grep/util.c	Wed Aug 16 00:04:57 2017	(r322554)
+++ stable/11/usr.bin/grep/util.c	Wed Aug 16 00:12:22 2017	(r322555)
@@ -271,28 +271,32 @@ static int
 procline(struct str *l, int nottext)
 {
 	regmatch_t matches[MAX_LINE_MATCHES];
-	regmatch_t pmatch;
-	size_t st = 0;
+	regmatch_t pmatch, lastmatch;
+	size_t st = 0, nst = 0;
 	unsigned int i;
-	int c = 0, m = 0, r = 0;
+	int c = 0, m = 0, r = 0, lastmatches = 0, leflags = eflags;
+	int startm = 0;
 
+	/* Initialize to avoid a false positive warning from GCC. */
+	lastmatch.rm_so = lastmatch.rm_eo = 0;
+
 	/* Loop to process the whole line */
 	while (st <= l->len) {
-		pmatch.rm_so = st;
-		pmatch.rm_eo = l->len;
-
+		lastmatches = 0;
+		startm = m;
+		if (st > 0)
+			leflags |= REG_NOTBOL;
 		/* Loop to compare with all the patterns */
 		for (i = 0; i < patterns; i++) {
+			pmatch.rm_so = st;
+			pmatch.rm_eo = l->len;
 			if (fg_pattern[i].pattern)
 				r = fastexec(&fg_pattern[i],
-				    l->dat, 1, &pmatch, eflags);
+				    l->dat, 1, &pmatch, leflags);
 			else
 				r = regexec(&r_pattern[i], l->dat, 1,
-				    &pmatch, eflags);
+				    &pmatch, leflags);
 			r = (r == 0) ? 0 : REG_NOMATCH;
-			st = (cflags & REG_NOSUB)
-				? (size_t)l->len
-				: (size_t)pmatch.rm_eo;
 			if (r == REG_NOMATCH)
 				continue;
 			/* Check for full match */
@@ -319,10 +323,26 @@ procline(struct str *l, int nottext)
 					r = REG_NOMATCH;
 			}
 			if (r == 0) {
+				lastmatches++;
+				lastmatch = pmatch;
 				if (m == 0)
 					c++;
-				if (m < MAX_LINE_MATCHES)
-					matches[m++] = pmatch;
+
+				if (m < MAX_LINE_MATCHES) {
+					/* Replace previous match if the new one is earlier and/or longer */
+					if (m > startm) {
+						if (pmatch.rm_so < matches[m-1].rm_so ||
+						    (pmatch.rm_so == matches[m-1].rm_so && (pmatch.rm_eo - pmatch.rm_so) > (matches[m-1].rm_eo - matches[m-1].rm_so))) {
+							matches[m-1] = pmatch;
+							nst = pmatch.rm_eo;
+						}
+					} else {
+						/* Advance as normal if not */
+						matches[m++] = pmatch;
+						nst = pmatch.rm_eo;
+					}
+				}
+
 				/* matches - skip further patterns */
 				if ((color == NULL && !oflag) ||
 				    qflag || lflag)
@@ -339,8 +359,19 @@ procline(struct str *l, int nottext)
 		if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag))
 			break;
 
-		if (st == (size_t)pmatch.rm_so)
-			break; 	/* No matches */
+		/* If we didn't have any matches or REG_NOSUB set */
+		if (lastmatches == 0 || (cflags & REG_NOSUB))
+			nst = l->len;
+
+		if (lastmatches == 0)
+			/* No matches */
+			break;
+		else if (st == nst && lastmatch.rm_so == lastmatch.rm_eo)
+			/* Zero-length match -- advance one more so we don't get stuck */
+			nst++;
+
+		/* Advance st based on previous matches */
+		st = nst;
 	}
 
 
@@ -439,6 +470,10 @@ printline(struct str *line, int sep, regmatch_t *match
 	size_t a = 0;
 	int i, n = 0;
 
+	/* If matchall, everything matches but don't actually print for -o */
+	if (oflag && matchall)
+		return;
+
 	if (!hflag) {
 		if (!nullflag) {
 			fputs(line->file, stdout);
@@ -465,6 +500,9 @@ printline(struct str *line, int sep, regmatch_t *match
 	/* --color and -o */
 	if ((oflag || color) && m > 0) {
 		for (i = 0; i < m; i++) {
+			/* Don't output zero length matches */
+			if (matches[i].rm_so == matches[i].rm_eo)
+				continue;
 			if (!oflag)
 				fwrite(line->dat + a, matches[i].rm_so - a, 1,
 				    stdout);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201708160012.v7G0CMMl024686>