grep-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] grep: make echo .|grep '\.' match once again


From: Jim Meyering
Subject: [PATCH] grep: make echo .|grep '\.' match once again
Date: Fri, 18 Sep 2020 12:56:07 -0700

I have just fixed a pretty bad bug.
I'll publish another snapshot soon.

  grep: make echo .|grep '\.' match once again

  The same applied for many other backslash-escaped bytes, not just
  metacharacters.  The switch to rawmemchr in v3.4-almost-10-g9393b97
  made some parts of the code require the usually-guaranteed newline
  sentinel at the end of each pattern. Before, some consumers used a
  (correct) pattern length and did not care that try_fgrep_pattern could
  transform a pattern (with sentinel) like "\\.\n" to "..\n", thus
  violating that assumption.
  * src/grep.c (try_fgrep_pattern): Preserve the invariant
  that each regexp is newline-terminated.
  * tests/backslash-dot: New file. Test for this.
  * tests/Makefile.am (TESTS): Add it.

>From 203ad5b718ce349efa6bfa847b356d47dc5c584e Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@fb.com>
Date: Fri, 18 Sep 2020 12:37:17 -0700
Subject: [PATCH] grep: make echo .|grep '\.' match once again

The same applied for many other backslash-escaped bytes, not just
metacharacters.  The switch to rawmemchr in v3.4-almost-10-g9393b97
made some parts of the code require the usually-guaranteed newline
sentinel at the end of each pattern. Before, some consumers used a
(correct) pattern length and did not care that try_fgrep_pattern could
transform a pattern (with sentinel) like "\\.\n" to "..\n", thus
violating that assumption.
* src/grep.c (try_fgrep_pattern): Preserve the invariant
that each regexp is newline-terminated.
* tests/backslash-dot: New file. Test for this.
* tests/Makefile.am (TESTS): Add it.
---
 src/grep.c          |  3 +++
 tests/Makefile.am   |  1 +
 tests/backslash-dot | 20 ++++++++++++++++++++
 3 files changed, 24 insertions(+)
 create mode 100755 tests/backslash-dot

diff --git a/src/grep.c b/src/grep.c
index ba6b15d..497780e 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -2471,6 +2471,9 @@ try_fgrep_pattern (int matcher, char *keys, size_t *len_p)
     {
       *len_p = p - new_keys;
       memcpy (keys, new_keys, p - new_keys);
+      /* We have just shortened this pattern.
+         Preserve the invariant that it is newline-terminated.  */
+      keys[*len_p] = '\n';
     }
   result = F_MATCHER_INDEX;

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3ee2915..b29f26a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -66,6 +66,7 @@ TESTS =                                               \
   backref-alt                                  \
   backref-multibyte-slow                       \
   backref-word                                 \
+  backslash-dot                                        \
   backslash-s-and-repetition-operators         \
   backslash-s-vs-invalid-multibyte             \
   big-hole                                     \
diff --git a/tests/backslash-dot b/tests/backslash-dot
new file mode 100755
index 0000000..3fddda5
--- /dev/null
+++ b/tests/backslash-dot
@@ -0,0 +1,20 @@
+#! /bin/sh
+# This once failed to match: echo . | grep '\.'
+#
+# Copyright (C) 2020 Free Software Foundation, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+fail=0
+
+echo . > in || framework_failure_
+
+grep '\.' in > out 2> err || fail=1
+compare in out || fail=1
+compare /dev/null err || fail=1
+
+Exit $fail
-- 
2.28.0.497.g54e85e7af1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]