bug-grep
[Top][All Lists]
Advanced

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

bug#15307: minor fix to dfa.c


From: Jim Meyering
Subject: bug#15307: minor fix to dfa.c
Date: Sun, 8 Sep 2013 11:01:08 -0700

On Sun, Sep 8, 2013 at 2:53 AM, Aharon Robbins <address@hidden> wrote:
> The following fix to dfa.c was suggested by a static checking tool.
> I'm applying it in the gawk code base.
>
> Basically, it's theoretically possible for len to have run off the end
> of the `str' array.
...
> diff --git a/dfa.c b/dfa.c
> index 8b79eb7..490a075 100644
> --- a/dfa.c
> +++ b/dfa.c
> @@ -1038,7 +1038,8 @@ parse_bracket_exp (void)
>                      /* This is in any case an invalid class name.  */
>                      str[0] = '\0';
>                  }
> -              str[len] = '\0';
> +              if (len < BRACKET_BUFFER_SIZE)
> +                 str[len] = '\0';
>
>                /* Fetch bracket.  */
>                FETCH_WC (c, wc, _("unbalanced ["));

Hi Arnold,

Thanks, but that makes it look like "str" will instead fail to be
NUL-terminated,
in which case the following strcmp (aka STREQ) would overrun the buffer.
Yes, this is all theoretical, but still...

I see that the current limit is 31:

  $ for i in 30 31 32 33; do printf "$i "; src/grep -E '[[:'$(perl -e
'print "a"x'$i)':]]'; done
  30 src/grep: Invalid character class name
  31 src/grep: Invalid character class name
  32 src/grep: Unmatched [ or [^
  33 src/grep: Unmatched [ or [^

So I propose this patch instead:

>From f1e1fb2c5c1538c313f8488ef687b9a96684f54e Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sun, 8 Sep 2013 10:49:52 -0700
Subject: [PATCH] dfa: appease a static analyzer, and save 95 stack bytes

* src/dfa.c (MAX_BRACKET_STRING_LEN): Rename from BRACKET_BUFFER_SIZE
and decrease from 128 to 32.
(parse_bracket_exp): Add one byte more than MAX_BRACKET_STRING_LEN
to the length of "str" buffer, to avoid appearance that we may store
the trailing NUL beyond the end of buffer.  A string of length 32
or greater is rejected by earlier processing, so would never reach
this code.  Addresses http://bugs.gnu.org/15307
---
 src/dfa.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/dfa.c b/src/dfa.c
index ad38d3b..b447a8a 100644
--- a/src/dfa.c
+++ b/src/dfa.c
@@ -975,8 +975,8 @@ parse_bracket_exp (void)
          dfa is ever called.  */
       if (c == '[' && (syntax_bits & RE_CHAR_CLASSES))
         {
-#define BRACKET_BUFFER_SIZE 128
-          char str[BRACKET_BUFFER_SIZE];
+#define MAX_BRACKET_STRING_LEN 32
+          char str[MAX_BRACKET_STRING_LEN + 1];
           FETCH_WC (c1, wc1, _("unbalanced ["));

           /* If pattern contains '[[:', '[[.', or '[[='.  */
@@ -990,7 +990,7 @@ parse_bracket_exp (void)
                   FETCH_WC (c, wc, _("unbalanced ["));
                   if ((c == c1 && *lexptr == ']') || lexleft == 0)
                     break;
-                  if (len < BRACKET_BUFFER_SIZE)
+                  if (len < MAX_BRACKET_STRING_LEN)
                     str[len++] = c;
                   else
                     /* This is in any case an invalid class name.  */
-- 
1.8.4.99.gd2dbd39





reply via email to

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