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.