Fix regex abort when it tries to reenter itself
Problem reported by Ken Raeburn. Solution suggested by Stefan Monnier (Bug#21688). * src/regex.c (re_match_2_internal): Use new _FAST functions to avoid regex code reentering itself. * src/syntax.c (update_syntax_table_forward): New arg PROPERTIZE. All callers changed. * src/syntax.h (UPDATE_SYNTAX_TABLE_FORWARD_FAST) (UPDATE_SYNTAX_TABLE_FAST): New inline functions.
This commit is contained in:
parent
3a1a220b02
commit
8121757b3a
3 changed files with 34 additions and 18 deletions
18
src/regex.c
18
src/regex.c
|
@ -5945,12 +5945,12 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
#ifdef emacs
|
||||
ssize_t offset = PTR_TO_OFFSET (d - 1);
|
||||
ssize_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FAST (charpos);
|
||||
#endif
|
||||
GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
|
||||
s1 = SYNTAX (c1);
|
||||
#ifdef emacs
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
|
||||
UPDATE_SYNTAX_TABLE_FORWARD_FAST (charpos + 1);
|
||||
#endif
|
||||
PREFETCH_NOLIMIT ();
|
||||
GET_CHAR_AFTER (c2, d, dummy);
|
||||
|
@ -5987,7 +5987,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
#ifdef emacs
|
||||
ssize_t offset = PTR_TO_OFFSET (d);
|
||||
ssize_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FAST (charpos);
|
||||
#endif
|
||||
PREFETCH ();
|
||||
GET_CHAR_AFTER (c2, d, dummy);
|
||||
|
@ -6032,7 +6032,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
#ifdef emacs
|
||||
ssize_t offset = PTR_TO_OFFSET (d) - 1;
|
||||
ssize_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FAST (charpos);
|
||||
#endif
|
||||
GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
|
||||
s1 = SYNTAX (c1);
|
||||
|
@ -6047,7 +6047,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
PREFETCH_NOLIMIT ();
|
||||
GET_CHAR_AFTER (c2, d, dummy);
|
||||
#ifdef emacs
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FORWARD_FAST (charpos);
|
||||
#endif
|
||||
s2 = SYNTAX (c2);
|
||||
|
||||
|
@ -6076,7 +6076,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
#ifdef emacs
|
||||
ssize_t offset = PTR_TO_OFFSET (d);
|
||||
ssize_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FAST (charpos);
|
||||
#endif
|
||||
PREFETCH ();
|
||||
c2 = RE_STRING_CHAR (d, target_multibyte);
|
||||
|
@ -6119,7 +6119,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
#ifdef emacs
|
||||
ssize_t offset = PTR_TO_OFFSET (d) - 1;
|
||||
ssize_t charpos = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FAST (charpos);
|
||||
#endif
|
||||
GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2);
|
||||
s1 = SYNTAX (c1);
|
||||
|
@ -6134,7 +6134,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
PREFETCH_NOLIMIT ();
|
||||
c2 = RE_STRING_CHAR (d, target_multibyte);
|
||||
#ifdef emacs
|
||||
UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
|
||||
UPDATE_SYNTAX_TABLE_FORWARD_FAST (charpos + 1);
|
||||
#endif
|
||||
s2 = SYNTAX (c2);
|
||||
|
||||
|
@ -6157,7 +6157,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
{
|
||||
ssize_t offset = PTR_TO_OFFSET (d);
|
||||
ssize_t pos1 = SYNTAX_TABLE_BYTE_TO_CHAR (offset);
|
||||
UPDATE_SYNTAX_TABLE (pos1);
|
||||
UPDATE_SYNTAX_TABLE_FAST (pos1);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
|
|
15
src/syntax.c
15
src/syntax.c
|
@ -246,7 +246,7 @@ SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
|
|||
if (parse_sexp_lookup_properties)
|
||||
{
|
||||
if (count > 0)
|
||||
update_syntax_table_forward (from, true, Qnil);
|
||||
update_syntax_table_forward (from, true, true, Qnil);
|
||||
else if (from > BEGV)
|
||||
{
|
||||
update_syntax_table (from - 1, count, true, Qnil);
|
||||
|
@ -502,27 +502,28 @@ parse_sexp_propertize (ptrdiff_t charpos)
|
|||
e_property_truncated, so the e_property_truncated flag may
|
||||
occasionally be left raised spuriously. This should be rare. */
|
||||
gl_state.e_property_truncated = false;
|
||||
update_syntax_table_forward (charpos, false, Qnil);
|
||||
update_syntax_table_forward (charpos, false, true, Qnil);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
update_syntax_table_forward (ptrdiff_t charpos, bool init,
|
||||
update_syntax_table_forward (ptrdiff_t charpos, bool init, bool propertize,
|
||||
Lisp_Object object)
|
||||
{
|
||||
if (gl_state.e_property_truncated)
|
||||
{
|
||||
eassert (NILP (object));
|
||||
eassert (charpos >= gl_state.e_property);
|
||||
parse_sexp_propertize (charpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
update_syntax_table (charpos, 1, init, object);
|
||||
if (gl_state.e_property > syntax_propertize__done
|
||||
&& NILP (object))
|
||||
parse_sexp_propertize (charpos);
|
||||
propertize &= (NILP (object)
|
||||
&& gl_state.e_property > syntax_propertize__done);
|
||||
}
|
||||
|
||||
if (propertize)
|
||||
parse_sexp_propertize (charpos);
|
||||
}
|
||||
|
||||
/* Returns true if char at CHARPOS is quoted.
|
||||
|
|
19
src/syntax.h
19
src/syntax.h
|
@ -27,7 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
INLINE_HEADER_BEGIN
|
||||
|
||||
extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object);
|
||||
extern void update_syntax_table_forward (ptrdiff_t, bool, Lisp_Object);
|
||||
extern void update_syntax_table_forward (ptrdiff_t, bool, bool, Lisp_Object);
|
||||
|
||||
/* The standard syntax table is stored where it will automatically
|
||||
be used in all new buffers. */
|
||||
|
@ -183,7 +183,15 @@ UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos)
|
|||
{ /* Performs just-in-time syntax-propertization. */
|
||||
if (parse_sexp_lookup_properties && charpos >= gl_state.e_property)
|
||||
update_syntax_table_forward (charpos + gl_state.offset,
|
||||
false, gl_state.object);
|
||||
false, true, gl_state.object);
|
||||
}
|
||||
|
||||
INLINE void
|
||||
UPDATE_SYNTAX_TABLE_FORWARD_FAST (ptrdiff_t charpos)
|
||||
{
|
||||
if (parse_sexp_lookup_properties && charpos >= gl_state.e_property)
|
||||
update_syntax_table_forward (charpos + gl_state.offset,
|
||||
false, false, gl_state.object);
|
||||
}
|
||||
|
||||
/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
|
||||
|
@ -205,6 +213,13 @@ UPDATE_SYNTAX_TABLE (ptrdiff_t charpos)
|
|||
UPDATE_SYNTAX_TABLE_FORWARD (charpos);
|
||||
}
|
||||
|
||||
INLINE void
|
||||
UPDATE_SYNTAX_TABLE_FAST (ptrdiff_t charpos)
|
||||
{
|
||||
UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
|
||||
UPDATE_SYNTAX_TABLE_FORWARD_FAST (charpos);
|
||||
}
|
||||
|
||||
/* Set up the buffer-global syntax table. */
|
||||
|
||||
INLINE void
|
||||
|
|
Loading…
Add table
Reference in a new issue