Avoid crashes in regex-emacs.c due to GC
* src/regex-emacs.c (re_match_2_internal): Prevent GC from invalidating C pointers to buffer text. (Bug#40661)
This commit is contained in:
parent
175c61c18b
commit
f3b62b6c62
1 changed files with 22 additions and 0 deletions
|
@ -3853,6 +3853,12 @@ re_match_2 (struct re_pattern_buffer *bufp,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unwind_re_match (void *ptr)
|
||||||
|
{
|
||||||
|
struct buffer *b = (struct buffer *) ptr;
|
||||||
|
b->text->inhibit_shrinking = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is a separate function so that we can force an alloca cleanup
|
/* This is a separate function so that we can force an alloca cleanup
|
||||||
afterwards. */
|
afterwards. */
|
||||||
|
@ -3949,6 +3955,19 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
|
||||||
|
|
||||||
INIT_FAIL_STACK ();
|
INIT_FAIL_STACK ();
|
||||||
|
|
||||||
|
ptrdiff_t count = SPECPDL_INDEX ();
|
||||||
|
|
||||||
|
/* Prevent shrinking and relocation of buffer text if GC happens
|
||||||
|
while we are inside this function. The calls to
|
||||||
|
UPDATE_SYNTAX_TABLE_* macros can trigger GC if they call Lisp,
|
||||||
|
and we have C pointers to buffer text that must not become
|
||||||
|
invalid as result of GC. */
|
||||||
|
if (!current_buffer->text->inhibit_shrinking)
|
||||||
|
{
|
||||||
|
record_unwind_protect_ptr (unwind_re_match, current_buffer);
|
||||||
|
current_buffer->text->inhibit_shrinking = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do not bother to initialize all the register variables if there are
|
/* Do not bother to initialize all the register variables if there are
|
||||||
no groups in the pattern, as it takes a fair amount of time. If
|
no groups in the pattern, as it takes a fair amount of time. If
|
||||||
there are groups, we include space for register 0 (the whole
|
there are groups, we include space for register 0 (the whole
|
||||||
|
@ -3965,6 +3984,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
|
||||||
/* The starting position is bogus. */
|
/* The starting position is bogus. */
|
||||||
if (pos < 0 || pos > size1 + size2)
|
if (pos < 0 || pos > size1 + size2)
|
||||||
{
|
{
|
||||||
|
unbind_to (count, Qnil);
|
||||||
SAFE_FREE ();
|
SAFE_FREE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -4179,6 +4199,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
|
||||||
|
|
||||||
DEBUG_PRINT ("Returning %td from re_match_2.\n", dcnt);
|
DEBUG_PRINT ("Returning %td from re_match_2.\n", dcnt);
|
||||||
|
|
||||||
|
unbind_to (count, Qnil);
|
||||||
SAFE_FREE ();
|
SAFE_FREE ();
|
||||||
return dcnt;
|
return dcnt;
|
||||||
}
|
}
|
||||||
|
@ -5025,6 +5046,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp,
|
||||||
if (best_regs_set)
|
if (best_regs_set)
|
||||||
goto restore_best_regs;
|
goto restore_best_regs;
|
||||||
|
|
||||||
|
unbind_to (count, Qnil);
|
||||||
SAFE_FREE ();
|
SAFE_FREE ();
|
||||||
|
|
||||||
return -1; /* Failure to match. */
|
return -1; /* Failure to match. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue