svn commit: r317704 - head/usr.bin/grep/regex

Ed Maste emaste at FreeBSD.org
Tue May 2 20:44:07 UTC 2017


Author: emaste
Date: Tue May  2 20:44:06 2017
New Revision: 317704
URL: https://svnweb.freebsd.org/changeset/base/317704

Log:
  bsdgrep: fix escape map building for multibyte strings
  
  In BSD grep, fix escape map building in the regex parser. It was
  previously using memory not explicitly initialized, and the MBS escape
  map was being built based on a version of the pattern with escapes
  already parsed out.
  
  This is Kyle's change, but I restored the broken style that already
  exists in this file.
  
  Submitted by:	Kyle Evans <kevans91 at ksu.edu>
  Reviewed by:	cem, Kyle Evans (my style changes)
  Differential Revision:	https://reviews.freebsd.org/D10098

Modified:
  head/usr.bin/grep/regex/tre-fastmatch.c

Modified: head/usr.bin/grep/regex/tre-fastmatch.c
==============================================================================
--- head/usr.bin/grep/regex/tre-fastmatch.c	Tue May  2 20:39:33 2017	(r317703)
+++ head/usr.bin/grep/regex/tre-fastmatch.c	Tue May  2 20:44:06 2017	(r317704)
@@ -98,6 +98,18 @@ static int	fastcmp(const fastmatch_t *fg
     fg->pattern[siz] = '\0';						\
   }									\
 
+#define CONV_MBS_PAT(src, dest, destsz)					\
+  {									\
+    destsz = wcstombs(NULL, src, 0);					\
+    if (destsz == (size_t)-1)						\
+      return REG_BADPAT;						\
+    dest = malloc(destsz + 1);						\
+    if (dest == NULL)							\
+      return REG_ESPACE;						\
+    wcstombs(dest, src, destsz);					\
+    dest[destsz] = '\0';						\
+  }									\
+
 #define IS_OUT_OF_BOUNDS						\
   ((!fg->reversed							\
     ? ((type == STR_WIDE) ? ((j + fg->wlen) > len)			\
@@ -723,15 +735,29 @@ badpat:
 	}
 
       escaped = false;
-      for (unsigned int i = 0; i < fg->len; i++)
-	if (fg->pattern[i] == '\\')
-	  escaped = !escaped;
-	else if (fg->pattern[i] == '.' && fg->escmap && escaped)
+      char *_checkpat = NULL;
+      size_t _checklen = 0;
+      unsigned int escofs = 0;
+      /*
+       * Make a copy here of the original pattern, because fg->pattern has
+       * already been stripped of all escape sequences in the above processing.
+       * This is necessary if we wish to later treat fg->escmap as an actual,
+       * functional replacement of fg->wescmap.
+       */
+      CONV_MBS_PAT(pat, _checkpat, _checklen);
+      for (unsigned int i = 0; i < n; i++)
+	if (_checkpat[i] == '\\')
+	  {
+	    escaped = !escaped;
+	    if (escaped)
+	      ++escofs;
+	  }
+	else if (_checkpat[i] == '.' && fg->escmap != NULL && escaped)
 	  {
-	    fg->escmap[i] = true;
+	    fg->escmap[i - escofs] = true;
 	    escaped = false;
 	  }
-	else if (fg->pattern[i] == '.' && !escaped)
+	else if (_checkpat[i] == '.' && !escaped)
 	  {
 	    hasdot = i;
 	    if (firstdot == -1)
@@ -739,6 +765,7 @@ badpat:
 	  }
 	else
 	  escaped = false;
+      free(_checkpat);
     }
 #else
   SAVE_PATTERN(tmp, pos, fg->pattern, fg->len);


More information about the svn-src-all mailing list