mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.4029: debugging NFA regexp my crash, cached indent may be wrong
Problem: Debugging NFA regexp my crash, cached indent may be wrong. Solution: Fix some debug warnings in the NFA regexp code. Make sure log_fd is set when used. Fix breakindent and indent caching. (Christian Brabandt, closes #9482)
This commit is contained in:
55
src/indent.c
55
src/indent.c
@@ -915,13 +915,15 @@ get_breakindent_win(
|
|||||||
win_T *wp,
|
win_T *wp,
|
||||||
char_u *line) // start of the line
|
char_u *line) // start of the line
|
||||||
{
|
{
|
||||||
static int prev_indent = 0; // cached indent value
|
static int prev_indent = 0; // cached indent value
|
||||||
static long prev_ts = 0L; // cached tabstop value
|
static long prev_ts = 0L; // cached tabstop value
|
||||||
static char_u *prev_line = NULL; // cached pointer to line
|
static char_u *prev_line = NULL; // cached pointer to line
|
||||||
static varnumber_T prev_tick = 0; // changedtick of cached value
|
static varnumber_T prev_tick = 0; // changedtick of cached value
|
||||||
# ifdef FEAT_VARTABS
|
# ifdef FEAT_VARTABS
|
||||||
static int *prev_vts = NULL; // cached vartabs values
|
static int *prev_vts = NULL; // cached vartabs values
|
||||||
# endif
|
# endif
|
||||||
|
static int prev_list = 0; // cached list value
|
||||||
|
static int prev_listopt = 0; // cached w_p_briopt_list value
|
||||||
int bri = 0;
|
int bri = 0;
|
||||||
// window width minus window margin space, i.e. what rests for text
|
// window width minus window margin space, i.e. what rests for text
|
||||||
const int eff_wwidth = wp->w_width
|
const int eff_wwidth = wp->w_width
|
||||||
@@ -929,9 +931,10 @@ get_breakindent_win(
|
|||||||
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
|
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
|
||||||
? number_width(wp) + 1 : 0);
|
? number_width(wp) + 1 : 0);
|
||||||
|
|
||||||
// used cached indent, unless pointer or 'tabstop' changed
|
// used cached indent, unless line, 'tabstop' or briopt_list changed
|
||||||
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
||||||
|| prev_tick != CHANGEDTICK(wp->w_buffer)
|
|| prev_tick != CHANGEDTICK(wp->w_buffer)
|
||||||
|
|| prev_listopt != wp->w_briopt_list
|
||||||
# ifdef FEAT_VARTABS
|
# ifdef FEAT_VARTABS
|
||||||
|| prev_vts != wp->w_buffer->b_p_vts_array
|
|| prev_vts != wp->w_buffer->b_p_vts_array
|
||||||
# endif
|
# endif
|
||||||
@@ -949,6 +952,28 @@ get_breakindent_win(
|
|||||||
prev_indent = get_indent_str(line,
|
prev_indent = get_indent_str(line,
|
||||||
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
||||||
# endif
|
# endif
|
||||||
|
prev_listopt = wp->w_briopt_list;
|
||||||
|
// add additional indent for numbered lists
|
||||||
|
if (wp->w_briopt_list != 0)
|
||||||
|
{
|
||||||
|
regmatch_T regmatch;
|
||||||
|
|
||||||
|
regmatch.regprog = vim_regcomp(curbuf->b_p_flp,
|
||||||
|
RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT);
|
||||||
|
|
||||||
|
if (regmatch.regprog != NULL)
|
||||||
|
{
|
||||||
|
regmatch.rm_ic = FALSE;
|
||||||
|
if (vim_regexec(®match, line, 0))
|
||||||
|
{
|
||||||
|
if (wp->w_briopt_list > 0)
|
||||||
|
prev_list = wp->w_briopt_list;
|
||||||
|
else
|
||||||
|
prev_list = (*regmatch.endp - *regmatch.startp);
|
||||||
|
}
|
||||||
|
vim_regfree(regmatch.regprog);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bri = prev_indent + wp->w_briopt_shift;
|
bri = prev_indent + wp->w_briopt_shift;
|
||||||
|
|
||||||
@@ -958,22 +983,10 @@ get_breakindent_win(
|
|||||||
// add additional indent for numbered lists
|
// add additional indent for numbered lists
|
||||||
if (wp->w_briopt_list != 0)
|
if (wp->w_briopt_list != 0)
|
||||||
{
|
{
|
||||||
regmatch_T regmatch;
|
if (wp->w_briopt_list > 0)
|
||||||
|
bri += prev_list;
|
||||||
regmatch.regprog = vim_regcomp(curbuf->b_p_flp,
|
else
|
||||||
RE_MAGIC + RE_STRING + RE_AUTO + RE_STRICT);
|
bri = prev_list;
|
||||||
if (regmatch.regprog != NULL)
|
|
||||||
{
|
|
||||||
regmatch.rm_ic = FALSE;
|
|
||||||
if (vim_regexec(®match, line, 0))
|
|
||||||
{
|
|
||||||
if (wp->w_briopt_list > 0)
|
|
||||||
bri += wp->w_briopt_list;
|
|
||||||
else
|
|
||||||
bri = (*regmatch.endp - *regmatch.startp);
|
|
||||||
}
|
|
||||||
vim_regfree(regmatch.regprog);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// indent minus the length of the showbreak string
|
// indent minus the length of the showbreak string
|
||||||
|
@@ -756,6 +756,9 @@ did_set_string_option(
|
|||||||
{
|
{
|
||||||
if (briopt_check(curwin) == FAIL)
|
if (briopt_check(curwin) == FAIL)
|
||||||
errmsg = e_invalid_argument;
|
errmsg = e_invalid_argument;
|
||||||
|
// list setting requires a redraw
|
||||||
|
if (curwin->w_briopt_list)
|
||||||
|
redraw_all_later(NOT_VALID);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2610,6 +2613,14 @@ ambw_end:
|
|||||||
update_package_paths_in_lua();
|
update_package_paths_in_lua();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_LINEBREAK)
|
||||||
|
// Changing Formatlistpattern when briopt includes the list setting:
|
||||||
|
// redraw
|
||||||
|
if ((varp == &p_flp || varp == &(curbuf->b_p_flp))
|
||||||
|
&& curwin->w_briopt_list)
|
||||||
|
redraw_all_later(NOT_VALID);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (curwin->w_curswant != MAXCOL
|
if (curwin->w_curswant != MAXCOL
|
||||||
&& (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0)
|
&& (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0)
|
||||||
curwin->w_set_curswant = TRUE;
|
curwin->w_set_curswant = TRUE;
|
||||||
|
@@ -2885,7 +2885,7 @@ nfa_print_state2(FILE *debugf, nfa_state_T *state, garray_T *indent)
|
|||||||
char_u save[2];
|
char_u save[2];
|
||||||
|
|
||||||
STRNCPY(save, &p[last], 2);
|
STRNCPY(save, &p[last], 2);
|
||||||
STRNCPY(&p[last], "+-", 2);
|
memcpy(&p[last], "+-", 2);
|
||||||
fprintf(debugf, " %s", p);
|
fprintf(debugf, " %s", p);
|
||||||
STRNCPY(&p[last], save, 2);
|
STRNCPY(&p[last], save, 2);
|
||||||
}
|
}
|
||||||
@@ -4291,6 +4291,23 @@ sub_equal(regsub_T *sub1, regsub_T *sub2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_LOG
|
#ifdef ENABLE_LOG
|
||||||
|
static void
|
||||||
|
open_debug_log(int result)
|
||||||
|
{
|
||||||
|
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
||||||
|
if (log_fd == NULL)
|
||||||
|
{
|
||||||
|
emsg(_(e_log_open_failed));
|
||||||
|
log_fd = stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(log_fd, "****************************\n");
|
||||||
|
fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
|
||||||
|
fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : result == MAYBE
|
||||||
|
? "MAYBE" : "FALSE");
|
||||||
|
fprintf(log_fd, "****************************\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
report_state(char *action,
|
report_state(char *action,
|
||||||
regsub_T *sub,
|
regsub_T *sub,
|
||||||
@@ -4307,6 +4324,9 @@ report_state(char *action,
|
|||||||
else
|
else
|
||||||
col = (int)(sub->list.line[0].start - rex.line);
|
col = (int)(sub->list.line[0].start - rex.line);
|
||||||
nfa_set_code(state->c);
|
nfa_set_code(state->c);
|
||||||
|
if (log_fd == NULL)
|
||||||
|
open_debug_log(MAYBE);
|
||||||
|
|
||||||
fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n",
|
fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n",
|
||||||
action, abs(state->id), lid, state->c, code, col,
|
action, abs(state->id), lid, state->c, code, col,
|
||||||
pim_info(pim));
|
pim_info(pim));
|
||||||
@@ -5430,19 +5450,7 @@ recursive_regmatch(
|
|||||||
nfa_endp = save_nfa_endp;
|
nfa_endp = save_nfa_endp;
|
||||||
|
|
||||||
#ifdef ENABLE_LOG
|
#ifdef ENABLE_LOG
|
||||||
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
open_debug_log(result);
|
||||||
if (log_fd != NULL)
|
|
||||||
{
|
|
||||||
fprintf(log_fd, "****************************\n");
|
|
||||||
fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
|
|
||||||
fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
|
|
||||||
fprintf(log_fd, "****************************\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
emsg(_(e_log_open_failed));
|
|
||||||
log_fd = stderr;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -5775,19 +5783,16 @@ nfa_regmatch(
|
|||||||
|
|
||||||
#ifdef ENABLE_LOG
|
#ifdef ENABLE_LOG
|
||||||
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
||||||
if (log_fd != NULL)
|
if (log_fd == NULL)
|
||||||
{
|
|
||||||
fprintf(log_fd, "**********************************\n");
|
|
||||||
nfa_set_code(start->c);
|
|
||||||
fprintf(log_fd, " RUNNING nfa_regmatch() starting with state %d, code %s\n",
|
|
||||||
abs(start->id), code);
|
|
||||||
fprintf(log_fd, "**********************************\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
emsg(_(e_log_open_failed));
|
emsg(_(e_log_open_failed));
|
||||||
log_fd = stderr;
|
log_fd = stderr;
|
||||||
}
|
}
|
||||||
|
fprintf(log_fd, "**********************************\n");
|
||||||
|
nfa_set_code(start->c);
|
||||||
|
fprintf(log_fd, " RUNNING nfa_regmatch() starting with state %d, code %s\n",
|
||||||
|
abs(start->id), code);
|
||||||
|
fprintf(log_fd, "**********************************\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thislist = &list[0];
|
thislist = &list[0];
|
||||||
@@ -6919,7 +6924,7 @@ nfa_regmatch(
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
siemsg("INTERNAL: Negative state char: %ld", c);
|
siemsg("INTERNAL: Negative state char: %ld", (long)c);
|
||||||
#endif
|
#endif
|
||||||
result = (c == curc);
|
result = (c == curc);
|
||||||
|
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4029,
|
||||||
/**/
|
/**/
|
||||||
4028,
|
4028,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user