Avoid buffer text relocations in calls to STRING_CHAR_* macros.
authorEli Zaretskii <eliz@gnu.org>
Mon, 28 May 2012 16:50:10 +0000 (19:50 +0300)
committerEli Zaretskii <eliz@gnu.org>
Mon, 28 May 2012 16:50:10 +0000 (19:50 +0300)
 src/charset.c (maybe_unify_char): Inhibit relocation of buffer text
 for the duration of call to load_charset, to avoid problems with
 callers of maybe_unify_char that access buffer text through C
 pointers.
 src/ralloc.c (r_alloc_inhibit_buffer_relocation): Increment and
 decrement the inhibition flag, instead of just setting or
 resetting it.

Fixes: debbugs:11519

src/ChangeLog
src/charset.c
src/ralloc.c

index 0b1ef22..ec5725a 100644 (file)
@@ -1,3 +1,14 @@
+2012-05-23  Eli Zaretskii  <eliz@gnu.org>
+
+       * charset.c (maybe_unify_char): Inhibit relocation of buffer text
+       for the duration of call to load_charset, to avoid problems with
+       callers of maybe_unify_char that access buffer text through C
+       pointers.
+
+       * ralloc.c (r_alloc_inhibit_buffer_relocation): Increment and
+       decrement the inhibition flag, instead of just setting or
+       resetting it.
+
 2012-05-24  Ken Brown  <kbrown@cornell.edu>
 
        * callproc.c (Fcall_process): Restore a line that was accidentally
index 57e1603..d287fc0 100644 (file)
@@ -1641,6 +1641,12 @@ maybe_unify_char (int c, Lisp_Object val)
     return c;
 
   CHECK_CHARSET_GET_CHARSET (val, charset);
+#ifdef REL_ALLOC
+  /* The call to load_charset below can allocate memory, whcih screws
+     callers of this function through STRING_CHAR_* macros that hold C
+     pointers to buffer text, if REL_ALLOC is used.  */
+  r_alloc_inhibit_buffer_relocation (1);
+#endif
   load_charset (charset, 1);
   if (! inhibit_load_charset_map)
     {
@@ -1656,6 +1662,9 @@ maybe_unify_char (int c, Lisp_Object val)
       if (unified > 0)
        c = unified;
     }
+#ifdef REL_ALLOC
+  r_alloc_inhibit_buffer_relocation (0);
+#endif
   return c;
 }
 
index db3638a..2e4823d 100644 (file)
@@ -1204,7 +1204,12 @@ r_alloc_reset_variable (POINTER *old, POINTER *new)
 void
 r_alloc_inhibit_buffer_relocation (int inhibit)
 {
-  use_relocatable_buffers = !inhibit;
+  if (use_relocatable_buffers < 0)
+    use_relocatable_buffers = 0;
+  if (inhibit)
+    use_relocatable_buffers++;
+  else if (use_relocatable_buffers > 0)
+    use_relocatable_buffers--;
 }
 
 \f