From 52c55cc7d2bec9795533f58e15c61f7a7b51d1b0 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 23 May 2012 20:32:28 +0300 Subject: [PATCH] Fix bug #11519 with relocation of buffer text during regex search. src/lisp.h [REL_ALLOC]: Add prototypes for external functions defined on ralloc.c. src/buffer.c [REL_ALLOC]: Remove prototypes of r_alloc_reset_variable, r_alloc, r_re_alloc, and r_alloc_free, they are now on lisp.h. src/ralloc.c (r_alloc_inhibit_buffer_relocation): New function. src/search.c (search_buffer): Use it to inhibit relocation of buffer text while re_search_2 is doing its job, because re_search_2 is passed C pointers to buffer text. --- src/ChangeLog | 15 +++++++++++++++ src/buffer.c | 11 ----------- src/lisp.h | 9 +++++++++ src/ralloc.c | 6 ++++++ src/search.c | 22 ++++++++++++++++++++++ 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d97c313e465..cbfd6631892 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2012-05-23 Eli Zaretskii + + * lisp.h [REL_ALLOC]: Add prototypes for external functions + defined on ralloc.c. + + * buffer.c [REL_ALLOC]: Remove prototypes of + r_alloc_reset_variable, r_alloc, r_re_alloc, and r_alloc_free, + they are now on lisp.h. + + * ralloc.c (r_alloc_inhibit_buffer_relocation): New function. + + * search.c (search_buffer): Use it to inhibit relocation of buffer + text while re_search_2 is doing its job, because re_search_2 is + passed C pointers to buffer text. (Bug#11519) + 2012-05-21 Eli Zaretskii * msdos.c (internal_terminal_init) : diff --git a/src/buffer.c b/src/buffer.c index 1fea19b0d65..ac14ec9c37c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2014,10 +2014,6 @@ advance_to_char_boundary (EMACS_INT byte_pos) return byte_pos; } -#ifdef REL_ALLOC -extern void r_alloc_reset_variable (POINTER_TYPE *, POINTER_TYPE *); -#endif /* REL_ALLOC */ - DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, 1, 1, 0, doc: /* Swap the text between current buffer and BUFFER. */) @@ -4779,13 +4775,6 @@ mmap_realloc (POINTER_TYPE **var, size_t nbytes) Buffer-text Allocation ***********************************************************************/ -#ifdef REL_ALLOC -extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t); -extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t); -extern void r_alloc_free (POINTER_TYPE **ptr); -#endif /* REL_ALLOC */ - - /* Allocate NBYTES bytes for buffer B's text buffer. */ static void diff --git a/src/lisp.h b/src/lisp.h index bd19da55b2a..aee5b0b1ec2 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3565,6 +3565,15 @@ void syms_of_dbusbind (void); /* Defined in msdos.c, w32.c */ extern char *emacs_root_dir (void); #endif /* DOS_NT */ + +#ifdef REL_ALLOC +/* Defined in ralloc.c */ +extern void r_alloc_reset_variable (POINTER_TYPE **, POINTER_TYPE **); +extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t); +extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t); +extern void r_alloc_free (POINTER_TYPE **ptr); +extern void r_alloc_inhibit_buffer_relocation (int); +#endif /* REL_ALLOC */ /* Nonzero means Emacs has already been initialized. Used during startup to detect startup of dumped Emacs. */ diff --git a/src/ralloc.c b/src/ralloc.c index 896ad9f3155..db3638a54e6 100644 --- a/src/ralloc.c +++ b/src/ralloc.c @@ -1201,6 +1201,12 @@ r_alloc_reset_variable (POINTER *old, POINTER *new) bloc->variable = new; } +void +r_alloc_inhibit_buffer_relocation (int inhibit) +{ + use_relocatable_buffers = !inhibit; +} + /*********************************************************************** Initialization diff --git a/src/search.c b/src/search.c index 1f3ccc25dc8..67f9e505fad 100644 --- a/src/search.c +++ b/src/search.c @@ -1158,12 +1158,25 @@ search_buffer (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte, while (n < 0) { EMACS_INT val; + +#ifdef REL_ALLOC + /* re_search_2 below is passed C pointers to buffer text. + If some code called by it causes memory (re)allocation, + buffer text could be relocated on platforms that use + REL_ALLOC, which invalidates those C pointers. So we + inhibit relocation of buffer text for as long as + re_search_2 runs. */ + r_alloc_inhibit_buffer_relocation (1); +#endif val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), /* Don't allow match past current point */ pos_byte - BEGV_BYTE); +#ifdef REL_ALLOC + r_alloc_inhibit_buffer_relocation (0); +#endif if (val == -2) { matcher_overflow (); @@ -1202,11 +1215,20 @@ search_buffer (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte, while (n > 0) { EMACS_INT val; + +#ifdef REL_ALLOC + /* See commentary above for the reasons for inhibiting + buffer text relocation here. */ + r_alloc_inhibit_buffer_relocation (1); +#endif val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), lim_byte - BEGV_BYTE); +#ifdef REL_ALLOC + r_alloc_inhibit_buffer_relocation (0); +#endif if (val == -2) { matcher_overflow (); -- 2.39.2