This is very annoing bug. Grep is base package - very important - is used in many shell scripts. After upgrade debian from woody to sarge many my shell scripts stopped working. And this bug is in stable release!

This bug is addressed in several Linux distros, fe. Fedora Core 2.
There is also available patch which seems to work well:

diff -Naur src/search.c.orig src/search.c
--- src/search.c.orig   2005-07-23 15:07:45.000000000 +0200
+++ src/search.c        2005-07-23 15:20:13.000000000 +0200
@@ -375,17 +375,7 @@
              /* Find a possible match using the KWset matcher. */
              size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
              if (offset == (size_t) -1)
-               {
-#ifdef MBS_SUPPORT
-                 if (MB_CUR_MAX > 1)
-                    {
-                      if (match_icase)
-                        free ((char*)buf);
-                      free(mb_properties);
-                    }
-#endif /* MBS_SUPPORT */
-                 return (size_t)-1;
-               }
+                     goto failure;
              beg += offset;
              /* Narrow down to the line containing the candidate, and
                 run it through DFA. */
@@ -398,7 +388,7 @@
              while (beg > buf && beg[-1] != eol)
                --beg;
              if (kwsm.index < kwset_exact_matches)
-               goto success;
+               goto success_in_beg_and_end;
              if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
                continue;
            }
@@ -417,7 +407,7 @@
            }
          /* Successful, no backreferences encountered! */
          if (!backref)
-           goto success;
+           goto success_in_beg_and_end;
        }
       else
        end = beg + size;
@@ -432,14 +422,11 @@
                                       end - beg - 1, &(patterns[i].regs))))
            {
              len = patterns[i].regs.end[0] - start;
-             if (exact)
-               {
-                 *match_size = len;
-                 return start;
-               }
+             if (exact && !match_words)
+               goto success_in_start_and_len;
              if ((!match_lines && !match_words)
                  || (match_lines && len == end - beg - 1))
-               goto success;
+               goto success_in_beg_and_end;
              /* If -w, check if the match aligns with word boundaries.
                 We do this iteratively because:
                 (a) the line may contain more than one occurence of the
@@ -453,7 +440,7 @@
                    if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1]))
                        && (len == end - beg - 1
                            || !WCHAR ((unsigned char) beg[start + len])))
-                     goto success;
+                     goto success_in_start_and_len;
                    if (len > 0)
                      {
                        /* Try a shorter length anchored at the same place. */
@@ -480,6 +467,7 @@
            }
        } /* for Regex patterns.  */
     } /* for (beg = end ..) */
+ failure:
 #ifdef MBS_SUPPORT
   if (MB_CUR_MAX > 1)
     {
@@ -491,8 +479,12 @@
 #endif /* MBS_SUPPORT */
   return (size_t) -1;

- success:
-  ret_val = beg - buf;
+ success_in_beg_and_end:
+  len = end - beg;
+  start = beg - buf;
+  /* FALLTHROUGH */
+
+ success_in_start_and_len:
 #ifdef MBS_SUPPORT
   if (MB_CUR_MAX > 1)
     {
@@ -502,8 +494,8 @@
         free(mb_properties);
     }
 #endif /* MBS_SUPPORT */
-  *match_size = end - beg;
-  return ret_val;
+  *match_size = len;
+  return start;
 }

 static void
@@ -555,37 +547,15 @@
     {
       size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
       if (offset == (size_t) -1)
-       {
-#ifdef MBS_SUPPORT
-          if (MB_CUR_MAX > 1)
-            {
-              if (match_icase)
-                free ((char*)buf);
-              free(mb_properties);
-            }
-#endif /* MBS_SUPPORT */
-         return offset;
-       }
+       goto failure;
 #ifdef MBS_SUPPORT
       if (MB_CUR_MAX > 1 && mb_properties[offset+beg-buf] == 0)
        continue; /* It is a part of multibyte character.  */
 #endif /* MBS_SUPPORT */
       beg += offset;
       len = kwsmatch.size[0];
-      if (exact)
-       {
-         *match_size = len;
-          ret_val = beg - buf;
-#ifdef MBS_SUPPORT
-          if (MB_CUR_MAX > 1)
-            {
-              if (match_icase)
-                free ((char*)buf);
-              free(mb_properties);
-            }
-#endif /* MBS_SUPPORT */
-         return ret_val;
-       }
+      if (exact && !match_words)
+      goto success_in_beg_and_len;
       if (match_lines)
        {
          if (beg > buf && beg[-1] != eol)
@@ -595,35 +565,37 @@
          goto success;
        }
       else if (match_words)
-       for (try = beg; len; )
-         {
-           if (try > buf && WCHAR((unsigned char) try[-1]))
-             break;
-           if (try + len < buf + size && WCHAR((unsigned char) try[len]))
-             {
-               offset = kwsexec (kwset, beg, --len, &kwsmatch);
-               if (offset == (size_t) -1)
-                 {
-#ifdef MBS_SUPPORT
-                    if (MB_CUR_MAX > 1)
-                      {
-                        if (match_icase)
-                          free ((char*)buf);
-                        free(mb_properties);
-                      }
-#endif /* MBS_SUPPORT */
-                   return offset;
-                 }
-               try = beg + offset;
-               len = kwsmatch.size[0];
-             }
-           else
-             goto success;
-         }
+       {
+         while (offset >= 0)
+           {
+             if ((offset == 0 || !WCHAR ((unsigned char) beg[-1]))
+                 && (len == end - beg - 1 || !WCHAR ((unsigned char) 
beg[len])))
+               {
+                 if (!exact)
+                   /* Returns the whole line now we know there's a word match. 
*/
+                   goto success;
+                 else
+                   /* Returns just this word match. */
+                   goto success_in_beg_and_len;
+               }
+             if (len > 0)
+               {
+                 /* Try a shorter length anchored at the same place. */
+                 --len;
+                 offset = kwsexec (kwset, beg, len, &kwsmatch);
+                 if (offset == -1) {
+                   break; /* Try a different anchor. */
+                 }
+                 beg += offset;
+                 len = kwsmatch.size[0];
+               }
+           }
+       }
       else
        goto success;
     }

+ failure:
 #ifdef MBS_SUPPORT
   if (MB_CUR_MAX > 1)
     {
@@ -640,7 +612,11 @@
   end++;
   while (buf < beg && beg[-1] != eol)
     --beg;
-  *match_size = end - beg;
+  len = end - beg;
+  /* FALLTHROUGH */
+
+ success_in_beg_and_len:
+  *match_size = len;
   ret_val = beg - buf;
 #ifdef MBS_SUPPORT
   if (MB_CUR_MAX > 1)

--
Grzegorz Janoszka


--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to