Skip to content

Commit 7bbc9cc

Browse files
committed
updated for version 7.4.519
Problem: Crash when using syntax highlighting. Solution: When regprog is freed and replaced, store the result.
1 parent 18109ff commit 7bbc9cc

File tree

10 files changed

+98
-64
lines changed

10 files changed

+98
-64
lines changed

src/buffer.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
#include "vim.h"
2929

3030
#if defined(FEAT_CMDL_COMPL) || defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL)
31-
static char_u *buflist_match __ARGS((regprog_T *prog, buf_T *buf, int ignore_case));
31+
static char_u *buflist_match __ARGS((regmatch_T *rmp, buf_T *buf, int ignore_case));
3232
# define HAVE_BUFLIST_MATCH
33-
static char_u *fname_match __ARGS((regprog_T *prog, char_u *name, int ignore_case));
33+
static char_u *fname_match __ARGS((regmatch_T *rmp, char_u *name, int ignore_case));
3434
#endif
3535
static void buflist_setfpos __ARGS((buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options));
3636
static wininfo_T *find_wininfo __ARGS((buf_T *buf, int skip_diff_buffer));
@@ -2220,7 +2220,6 @@ buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
22202220
int curtab_only; /* find buffers in current tab only */
22212221
{
22222222
buf_T *buf;
2223-
regprog_T *prog;
22242223
int match = -1;
22252224
int find_listed;
22262225
char_u *pat;
@@ -2265,14 +2264,16 @@ buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
22652264
{
22662265
for (attempt = 0; attempt <= 3; ++attempt)
22672266
{
2267+
regmatch_T regmatch;
2268+
22682269
/* may add '^' and '$' */
22692270
if (toggledollar)
22702271
*patend = (attempt < 2) ? NUL : '$'; /* add/remove '$' */
22712272
p = pat;
22722273
if (*p == '^' && !(attempt & 1)) /* add/remove '^' */
22732274
++p;
2274-
prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
2275-
if (prog == NULL)
2275+
regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
2276+
if (regmatch.regprog == NULL)
22762277
{
22772278
vim_free(pat);
22782279
return -1;
@@ -2283,7 +2284,7 @@ buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
22832284
#ifdef FEAT_DIFF
22842285
&& (!diffmode || diff_mode_buf(buf))
22852286
#endif
2286-
&& buflist_match(prog, buf, FALSE) != NULL)
2287+
&& buflist_match(&regmatch, buf, FALSE) != NULL)
22872288
{
22882289
if (curtab_only)
22892290
{
@@ -2310,7 +2311,7 @@ buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
23102311
match = buf->b_fnum; /* remember first match */
23112312
}
23122313

2313-
vim_regfree(prog);
2314+
vim_regfree(regmatch.regprog);
23142315
if (match >= 0) /* found one match */
23152316
break;
23162317
}
@@ -2352,7 +2353,6 @@ ExpandBufnames(pat, num_file, file, options)
23522353
int round;
23532354
char_u *p;
23542355
int attempt;
2355-
regprog_T *prog;
23562356
char_u *patc;
23572357

23582358
*num_file = 0; /* return values in case of FAIL */
@@ -2376,10 +2376,12 @@ ExpandBufnames(pat, num_file, file, options)
23762376
*/
23772377
for (attempt = 0; attempt <= 1; ++attempt)
23782378
{
2379+
regmatch_T regmatch;
2380+
23792381
if (attempt > 0 && patc == pat)
23802382
break; /* there was no anchor, no need to try again */
2381-
prog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
2382-
if (prog == NULL)
2383+
regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
2384+
if (regmatch.regprog == NULL)
23832385
{
23842386
if (patc != pat)
23852387
vim_free(patc);
@@ -2397,7 +2399,7 @@ ExpandBufnames(pat, num_file, file, options)
23972399
{
23982400
if (!buf->b_p_bl) /* skip unlisted buffers */
23992401
continue;
2400-
p = buflist_match(prog, buf, p_wic);
2402+
p = buflist_match(&regmatch, buf, p_wic);
24012403
if (p != NULL)
24022404
{
24032405
if (round == 1)
@@ -2419,14 +2421,14 @@ ExpandBufnames(pat, num_file, file, options)
24192421
*file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
24202422
if (*file == NULL)
24212423
{
2422-
vim_regfree(prog);
2424+
vim_regfree(regmatch.regprog);
24232425
if (patc != pat)
24242426
vim_free(patc);
24252427
return FAIL;
24262428
}
24272429
}
24282430
}
2429-
vim_regfree(prog);
2431+
vim_regfree(regmatch.regprog);
24302432
if (count) /* match(es) found, break here */
24312433
break;
24322434
}
@@ -2445,17 +2447,17 @@ ExpandBufnames(pat, num_file, file, options)
24452447
* Check for a match on the file name for buffer "buf" with regprog "prog".
24462448
*/
24472449
static char_u *
2448-
buflist_match(prog, buf, ignore_case)
2449-
regprog_T *prog;
2450+
buflist_match(rmp, buf, ignore_case)
2451+
regmatch_T *rmp;
24502452
buf_T *buf;
24512453
int ignore_case; /* when TRUE ignore case, when FALSE use 'fic' */
24522454
{
24532455
char_u *match;
24542456

24552457
/* First try the short file name, then the long file name. */
2456-
match = fname_match(prog, buf->b_sfname, ignore_case);
2458+
match = fname_match(rmp, buf->b_sfname, ignore_case);
24572459
if (match == NULL)
2458-
match = fname_match(prog, buf->b_ffname, ignore_case);
2460+
match = fname_match(rmp, buf->b_ffname, ignore_case);
24592461

24602462
return match;
24612463
}
@@ -2465,27 +2467,25 @@ buflist_match(prog, buf, ignore_case)
24652467
* Return "name" when there is a match, NULL when not.
24662468
*/
24672469
static char_u *
2468-
fname_match(prog, name, ignore_case)
2469-
regprog_T *prog;
2470+
fname_match(rmp, name, ignore_case)
2471+
regmatch_T *rmp;
24702472
char_u *name;
24712473
int ignore_case; /* when TRUE ignore case, when FALSE use 'fic' */
24722474
{
24732475
char_u *match = NULL;
24742476
char_u *p;
2475-
regmatch_T regmatch;
24762477

24772478
if (name != NULL)
24782479
{
2479-
regmatch.regprog = prog;
24802480
/* Ignore case when 'fileignorecase' or the argument is set. */
2481-
regmatch.rm_ic = p_fic || ignore_case;
2482-
if (vim_regexec(&regmatch, name, (colnr_T)0))
2481+
rmp->rm_ic = p_fic || ignore_case;
2482+
if (vim_regexec(rmp, name, (colnr_T)0))
24832483
match = name;
24842484
else
24852485
{
24862486
/* Replace $(HOME) with '~' and try matching again. */
24872487
p = home_replace_save(NULL, name);
2488-
if (p != NULL && vim_regexec(&regmatch, p, (colnr_T)0))
2488+
if (p != NULL && vim_regexec(rmp, p, (colnr_T)0))
24892489
match = name;
24902490
vim_free(p);
24912491
}

src/ex_cmds2.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,6 @@ debuggy_find(file, fname, after, gap, fp)
739739
struct debuggy *bp;
740740
int i;
741741
linenr_T lnum = 0;
742-
regmatch_T regmatch;
743742
char_u *name = fname;
744743
int prev_got_int;
745744

@@ -771,16 +770,14 @@ debuggy_find(file, fname, after, gap, fp)
771770
#endif
772771
(bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))))
773772
{
774-
regmatch.regprog = bp->dbg_prog;
775-
regmatch.rm_ic = FALSE;
776773
/*
777774
* Save the value of got_int and reset it. We don't want a
778775
* previous interruption cancel matching, only hitting CTRL-C
779776
* while matching should abort it.
780777
*/
781778
prev_got_int = got_int;
782779
got_int = FALSE;
783-
if (vim_regexec(&regmatch, name, (colnr_T)0))
780+
if (vim_regexec_prog(&bp->dbg_prog, FALSE, name, (colnr_T)0))
784781
{
785782
lnum = bp->dbg_lnum;
786783
if (fp != NULL)

src/fileio.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7772,6 +7772,9 @@ static int au_get_grouparg __ARGS((char_u **argp));
77727772
static int do_autocmd_event __ARGS((event_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group));
77737773
static int apply_autocmds_group __ARGS((event_T event, char_u *fname, char_u *fname_io, int force, int group, buf_T *buf, exarg_T *eap));
77747774
static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
7775+
#if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN)
7776+
static int match_file_pat __ARGS((char_u *pattern, regprog_T **prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
7777+
#endif
77757778

77767779

77777780
static event_T last_event;
@@ -9640,7 +9643,7 @@ auto_next_pat(apc, stop_at_last)
96409643
{
96419644
/* execution-condition */
96429645
if (ap->buflocal_nr == 0
9643-
? (match_file_pat(NULL, ap->reg_prog, apc->fname,
9646+
? (match_file_pat(NULL, &ap->reg_prog, apc->fname,
96449647
apc->sfname, apc->tail, ap->allow_dirs))
96459648
: ap->buflocal_nr == apc->arg_bufnr)
96469649
{
@@ -9774,7 +9777,7 @@ has_autocmd(event, sfname, buf)
97749777
for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
97759778
if (ap->pat != NULL && ap->cmds != NULL
97769779
&& (ap->buflocal_nr == 0
9777-
? match_file_pat(NULL, ap->reg_prog,
9780+
? match_file_pat(NULL, &ap->reg_prog,
97789781
fname, sfname, tail, ap->allow_dirs)
97799782
: buf != NULL && ap->buflocal_nr == buf->b_fnum
97809783
))
@@ -10035,10 +10038,10 @@ aucmd_restbuf(aco)
1003510038
* Used for autocommands and 'wildignore'.
1003610039
* Returns TRUE if there is a match, FALSE otherwise.
1003710040
*/
10038-
int
10041+
static int
1003910042
match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
1004010043
char_u *pattern; /* pattern to match with */
10041-
regprog_T *prog; /* pre-compiled regprog or NULL */
10044+
regprog_T **prog; /* pre-compiled regprog or NULL */
1004210045
char_u *fname; /* full path of file name */
1004310046
char_u *sfname; /* short file name or NULL */
1004410047
char_u *tail; /* tail of path */
@@ -10093,7 +10096,7 @@ match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
1009310096
#endif
1009410097
{
1009510098
if (prog != NULL)
10096-
regmatch.regprog = prog;
10099+
regmatch.regprog = *prog;
1009710100
else
1009810101
regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
1009910102
}
@@ -10119,7 +10122,9 @@ match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
1011910122
|| (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0)))))
1012010123
result = TRUE;
1012110124

10122-
if (prog == NULL)
10125+
if (prog != NULL)
10126+
*prog = regmatch.regprog;
10127+
else
1012310128
vim_regfree(regmatch.regprog);
1012410129
return result;
1012510130
}

src/os_unix.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,8 +1610,6 @@ x_IOerror_handler(dpy)
16101610
static int
16111611
x_connect_to_server()
16121612
{
1613-
regmatch_T regmatch;
1614-
16151613
#if defined(FEAT_CLIENTSERVER)
16161614
if (x_force_connect)
16171615
return TRUE;
@@ -1622,9 +1620,7 @@ x_connect_to_server()
16221620
/* Check for a match with "exclude:" from 'clipboard'. */
16231621
if (clip_exclude_prog != NULL)
16241622
{
1625-
regmatch.rm_ic = FALSE; /* Don't ignore case */
1626-
regmatch.regprog = clip_exclude_prog;
1627-
if (vim_regexec(&regmatch, T_NAME, (colnr_T)0))
1623+
if (vim_regexec_prog(&clip_exclude_prog, FALSE, T_NAME, (colnr_T)0))
16281624
return FALSE;
16291625
}
16301626
return TRUE;

src/proto/fileio.pro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd)
5959
char_u *get_event_name __ARGS((expand_T *xp, int idx));
6060
int autocmd_supported __ARGS((char_u *name));
6161
int au_exists __ARGS((char_u *arg));
62-
int match_file_pat __ARGS((char_u *pattern, regprog_T *prog, char_u *fname, char_u *sfname, char_u *tail, int allow_dirs));
6362
int match_file_list __ARGS((char_u *list, char_u *sfname, char_u *ffname));
6463
char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end, char *allow_dirs, int no_bslash));
6564
long read_eintr __ARGS((int fd, void *buf, size_t bufsize));

src/proto/regexp.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ char_u *reg_submatch __ARGS((int no));
1313
list_T *reg_submatch_list __ARGS((int no));
1414
regprog_T *vim_regcomp __ARGS((char_u *expr_arg, int re_flags));
1515
void vim_regfree __ARGS((regprog_T *prog));
16+
int vim_regexec_prog __ARGS((regprog_T **prog, int ignore_case, char_u *line, colnr_T col));
1617
int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
1718
int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
1819
long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm));

src/regexp.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8163,6 +8163,7 @@ static int vim_regexec_both __ARGS((regmatch_T *rmp, char_u *line, colnr_T col,
81638163
/*
81648164
* Match a regexp against a string.
81658165
* "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
8166+
* Note: "rmp->regprog" may be freed and changed.
81668167
* Uses curbuf for line count and 'iskeyword'.
81678168
* When "nl" is TRUE consider a "\n" in "line" to be a line break.
81688169
*
@@ -8203,6 +8204,29 @@ vim_regexec_both(rmp, line, col, nl)
82038204
return result;
82048205
}
82058206

8207+
/*
8208+
* Note: "*prog" may be freed and changed.
8209+
*/
8210+
int
8211+
vim_regexec_prog(prog, ignore_case, line, col)
8212+
regprog_T **prog;
8213+
int ignore_case;
8214+
char_u *line;
8215+
colnr_T col;
8216+
{
8217+
int r;
8218+
regmatch_T regmatch;
8219+
8220+
regmatch.regprog = *prog;
8221+
regmatch.rm_ic = ignore_case;
8222+
r = vim_regexec_both(&regmatch, line, col, FALSE);
8223+
*prog = regmatch.regprog;
8224+
return r;
8225+
}
8226+
8227+
/*
8228+
* Note: "rmp->regprog" may be freed and changed.
8229+
*/
82068230
int
82078231
vim_regexec(rmp, line, col)
82088232
regmatch_T *rmp;
@@ -8216,6 +8240,7 @@ vim_regexec(rmp, line, col)
82168240
|| defined(FIND_REPLACE_DIALOG) || defined(PROTO)
82178241
/*
82188242
* Like vim_regexec(), but consider a "\n" in "line" to be a line break.
8243+
* Note: "rmp->regprog" may be freed and changed.
82198244
*/
82208245
int
82218246
vim_regexec_nl(rmp, line, col)
@@ -8230,6 +8255,7 @@ vim_regexec_nl(rmp, line, col)
82308255
/*
82318256
* Match a regexp against multiple lines.
82328257
* "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
8258+
* Note: "rmp->regprog" may be freed and changed.
82338259
* Uses curbuf for line count and 'iskeyword'.
82348260
*
82358261
* Return zero if there is no match. Return number of lines contained in the

0 commit comments

Comments
 (0)