Patch 8.0.0645
Problem:    The new regexp engine does not give an error for using a back
            reference where it is not allowed. (Dominique Pelle)
Solution:   Check the back reference like the old engine. (closes #1774)
Files:      src/regexp.c, src/regexp_nfa.c, src/testdir/test_hlsearch.vim,
            src/testdir/test_statusline.vim, 
            src/testdir/test_regexp_latin.vim


*** ../vim-8.0.0644/src/regexp.c        2017-06-17 18:44:16.994000979 +0200
--- src/regexp.c        2017-06-17 19:27:53.054788101 +0200
***************
*** 1294,1299 ****
--- 1294,1327 ----
      return p;
  }
  
+ /*
+  * Return TRUE if the back reference is legal. We must have seen the close
+  * brace.
+  * TODO: Should also check that we don't refer to something that is repeated
+  * (+*=): what instance of the repetition should we match?
+  */
+     static int
+ seen_endbrace(int refnum)
+ {
+     if (!had_endbrace[refnum])
+     {
+       char_u *p;
+ 
+       /* Trick: check if "@<=" or "@<!" follows, in which case
+        * the \1 can appear before the referenced match. */
+       for (p = regparse; *p != NUL; ++p)
+           if (p[0] == '@' && p[1] == '<' && (p[2] == '!' || p[2] == '='))
+               break;
+       if (*p == NUL)
+       {
+           EMSG(_("E65: Illegal back reference"));
+           rc_did_emsg = TRUE;
+           return FALSE;
+       }
+     }
+     return TRUE;
+ }
+ 
  static regprog_T  *bt_regcomp(char_u *expr, int re_flags);
  static void bt_regfree(regprog_T *prog);
  
***************
*** 2099,2122 ****
                int                 refnum;
  
                refnum = c - Magic('0');
!               /*
!                * Check if the back reference is legal. We must have seen the
!                * close brace.
!                * TODO: Should also check that we don't refer to something
!                * that is repeated (+*=): what instance of the repetition
!                * should we match?
!                */
!               if (!had_endbrace[refnum])
!               {
!                   /* Trick: check if "@<=" or "@<!" follows, in which case
!                    * the \1 can appear before the referenced match. */
!                   for (p = regparse; *p != NUL; ++p)
!                       if (p[0] == '@' && p[1] == '<'
!                                             && (p[2] == '!' || p[2] == '='))
!                           break;
!                   if (*p == NUL)
!                       EMSG_RET_NULL(_("E65: Illegal back reference"));
!               }
                ret = regnode(BACKREF + refnum);
            }
            break;
--- 2127,2134 ----
                int                 refnum;
  
                refnum = c - Magic('0');
!               if (!seen_endbrace(refnum))
!                   return NULL;
                ret = regnode(BACKREF + refnum);
            }
            break;
*** ../vim-8.0.0644/src/regexp_nfa.c    2017-06-17 18:44:16.998000950 +0200
--- src/regexp_nfa.c    2017-06-17 19:44:06.203622096 +0200
***************
*** 1446,1453 ****
        case Magic('7'):
        case Magic('8'):
        case Magic('9'):
!           EMIT(NFA_BACKREF1 + (no_Magic(c) - '1'));
!           nfa_has_backref = TRUE;
            break;
  
        case Magic('z'):
--- 1446,1459 ----
        case Magic('7'):
        case Magic('8'):
        case Magic('9'):
!           {
!               int refnum = no_Magic(c) - '1';
! 
!               if (!seen_endbrace(refnum + 1))
!                   return FAIL;
!               EMIT(NFA_BACKREF1 + refnum);
!               nfa_has_backref = TRUE;
!           }
            break;
  
        case Magic('z'):
*** ../vim-8.0.0644/src/testdir/test_hlsearch.vim       2017-06-17 
19:13:44.284958880 +0200
--- src/testdir/test_hlsearch.vim       2017-06-17 19:53:48.139310968 +0200
***************
*** 38,48 ****
      return
    endif
  
!   " This pattern takes forever to match, it should timeout.
    help
    let start = reltime()
    set hlsearch nolazyredraw redrawtime=101
!   let @/ = '\%#=2\v(a|\1)*'
    redraw
    let elapsed = reltimefloat(reltime(start))
    call assert_true(elapsed > 0.1)
--- 38,48 ----
      return
    endif
  
!   " This pattern takes a long time to match, it should timeout.
    help
    let start = reltime()
    set hlsearch nolazyredraw redrawtime=101
!   let @/ = '\%#=1a*.*X\@<=b*'
    redraw
    let elapsed = reltimefloat(reltime(start))
    call assert_true(elapsed > 0.1)
*** ../vim-8.0.0644/src/testdir/test_statusline.vim     2017-03-06 
20:28:05.978797725 +0100
--- src/testdir/test_statusline.vim     2017-06-17 19:48:15.909786928 +0200
***************
*** 223,229 ****
    set statusline=ab%(cd%q%)de
    call assert_match('^abde\s*$', s:get_statusline())
    copen
!   call assert_match('^abcd\[Quickfix List\1]de\s*$', s:get_statusline())
    cclose
  
    " %#: Set highlight group. The name must follow and then a # again.
--- 223,229 ----
    set statusline=ab%(cd%q%)de
    call assert_match('^abde\s*$', s:get_statusline())
    copen
!   call assert_match('^abcd\[Quickfix List]de\s*$', s:get_statusline())
    cclose
  
    " %#: Set highlight group. The name must follow and then a # again.
*** ../vim-8.0.0644/src/testdir/test_regexp_latin.vim   2016-09-09 
20:18:47.000000000 +0200
--- src/testdir/test_regexp_latin.vim   2017-06-17 20:05:45.626002851 +0200
***************
*** 62,64 ****
--- 62,74 ----
      call assert_equal(expected, actual)
    endfor
  endfunc
+ 
+ func Test_backref()
+   new
+   call setline(1, ['one', 'two', 'three', 'four', 'five'])
+   call assert_equal(3, search('\%#=1\(e\)\1'))
+   call assert_equal(3, search('\%#=2\(e\)\1'))
+   call assert_fails('call search("\\%#=1\\(e\\1\\)")', 'E65:')
+   call assert_fails('call search("\\%#=2\\(e\\1\\)")', 'E65:')
+   bwipe!
+ endfunc
*** ../vim-8.0.0644/src/version.c       2017-06-17 19:13:44.292958822 +0200
--- src/version.c       2017-06-17 20:04:12.582686258 +0200
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     645,
  /**/

-- 
Everybody lies, but it doesn't matter since nobody listens.
                                -- Lieberman's Law

 /// 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui