To: [email protected]
Subject: Patch 7.4b.004
Fcc: outbox
From: Bram Moolenaar <[email protected]>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.4b.004
Problem:    Regexp crash on pattern "@\%[\w\-]*". (Axel Kielhorn)
Solution:   Add \%(\) around \%[] internally.
Files:      src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok


*** ../vim-7.4b.003/src/regexp_nfa.c    2013-08-01 16:21:30.000000000 +0200
--- src/regexp_nfa.c    2013-08-01 18:27:51.000000000 +0200
***************
*** 1166,1171 ****
--- 1166,1180 ----
                                                     reg_magic == MAGIC_ALL);
                       EMIT(NFA_OPT_CHARS);
                       EMIT(n);
+
+                       /* Emit as "\%(\%[abc]\)" to be able to handle
+                        * "\%[abc]*" which would cause the empty string to be
+                        * matched an unlimited number of times. NFA_NOPEN is
+                        * added only once at a position, while NFA_SPLIT is
+                        * added multiple times.  This is more efficient than
+                        * not allowsing NFA_SPLIT multiple times, it is used
+                        * a lot. */
+                       EMIT(NFA_NOPEN);
                       break;
                   }

***************
*** 1641,1647 ****
            * engine interprets the plus as "try matching one more time", and
            * a* matches a second time at the end of the input, the empty
            * string.
!            * The submatch will the empty string.
            *
            * In order to be consistent with the old engine, we replace
            * <atom>+ with <atom><atom>*
--- 1650,1656 ----
            * engine interprets the plus as "try matching one more time", and
            * a* matches a second time at the end of the input, the empty
            * string.
!            * The submatch will be the empty string.
            *
            * In order to be consistent with the old engine, we replace
            * <atom>+ with <atom><atom>*
***************
*** 2242,2254 ****
       else if (retval == OK)
           fprintf(f, ">>> NFA engine succeeded !\n");
       fprintf(f, "Regexp: \"%s\"\nPostfix notation (char): \"", expr);
!       for (p = post_start; *p && p < post_end; p++)
       {
           nfa_set_code(*p);
           fprintf(f, "%s, ", code);
       }
       fprintf(f, "\"\nPostfix notation (int): ");
!       for (p = post_start; *p && p < post_end; p++)
               fprintf(f, "%d ", *p);
       fprintf(f, "\n\n");
       fclose(f);
--- 2251,2263 ----
       else if (retval == OK)
           fprintf(f, ">>> NFA engine succeeded !\n");
       fprintf(f, "Regexp: \"%s\"\nPostfix notation (char): \"", expr);
!       for (p = post_start; *p && p < post_ptr; p++)
       {
           nfa_set_code(*p);
           fprintf(f, "%s, ", code);
       }
       fprintf(f, "\"\nPostfix notation (int): ");
!       for (p = post_start; *p && p < post_ptr; p++)
               fprintf(f, "%d ", *p);
       fprintf(f, "\n\n");
       fclose(f);
***************
*** 3005,3011 ****
         {
           int    n;

!           /* \%[abc] */
           n = *++p; /* get number of characters */
           if (nfa_calc_size == TRUE)
           {
--- 3014,3031 ----
         {
           int    n;

!           /* \%[abc] implemented as:
!            *    NFA_SPLIT
!            *    +-CHAR(a)
!            *    | +-NFA_SPLIT
!            *    |   +-CHAR(b)
!            *    |   | +-NFA_SPLIT
!            *    |   |   +-CHAR(c)
!            *    |   |   | +-next
!            *    |   |   +- next
!            *    |   +- next
!            *    +- next
!            */
           n = *++p; /* get number of characters */
           if (nfa_calc_size == TRUE)
           {
*** ../vim-7.4b.003/src/testdir/test64.in       2013-08-01 15:45:48.000000000 +0200
--- src/testdir/test64.in       2013-08-01 17:45:33.000000000 +0200
***************
*** 373,378 ****
--- 373,379 ----
 :call add(tl, [2, '\%[bar]x', 'xxx', 'x'])
 :call add(tl, [2, 'b\%[[ao]r]', 'bar bor', 'bar'])
 :call add(tl, [2, 'b\%[[]]r]', 'b]r bor', 'b]r'])
+ :call add(tl, [2, '@\%[\w\-]*', '<http://john.net/pandoc/>[@pandoc]', '@pandoc'])
 :"
 :"""" Alternatives, must use first longest match
 :call add(tl, [2, 'goo\|go', 'google', 'goo'])
*** ../vim-7.4b.003/src/testdir/test64.ok       2013-08-01 15:45:48.000000000 +0200
--- src/testdir/test64.ok       2013-08-01 18:28:56.000000000 +0200
***************
*** 857,862 ****
--- 857,865 ----
 OK 0 - b\%[[]]r]
 OK 1 - b\%[[]]r]
 OK 2 - b\%[[]]r]
+ OK 0 - @\%[\w\-]*
+ OK 1 - @\%[\w\-]*
+ OK 2 - @\%[\w\-]*
 OK 0 - goo\|go
 OK 1 - goo\|go
 OK 2 - goo\|go
*** ../vim-7.4b.003/src/version.c       2013-08-01 16:21:30.000000000 +0200
--- src/version.c       2013-08-01 18:33:04.000000000 +0200
***************
*** 729,730 ****
--- 729,732 ----
 {   /* Add new patch number below this line */
+ /**/
+     4,
 /**/

--
hundred-and-one symptoms of being an internet addict:
37. You start looking for hot HTML addresses in public restrooms.

/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
\\\            help me help AIDS victims -- http://ICCF-Holland.org    ///