Fix bug in decoding emacs-mule encoding.
authorEli Zaretskii <eliz@gnu.org>
Tue, 2 Mar 2010 20:35:44 +0000 (22:35 +0200)
committerEli Zaretskii <eliz@gnu.org>
Tue, 2 Mar 2010 20:35:44 +0000 (22:35 +0200)
 coding.c (decode_coding_emacs_mule): Fixup pointers to buffer
 text that could be relocated inside the call to emacs_mule_char.
 (emacs_mule_char): Use CODING_DECODE_CHAR instead of DECODE_CHAR.
 (CODING_DECODE_CHAR): Add a comment describing its purpose.

src/ChangeLog
src/coding.c

index aec692b..761beb2 100644 (file)
@@ -1,3 +1,10 @@
+2010-03-02  Eli Zaretskii  <eliz@gnu.org>
+
+       * coding.c (decode_coding_emacs_mule): Fixup pointers to buffer
+       text that could be relocated inside the call to emacs_mule_char.
+       (emacs_mule_char): Use CODING_DECODE_CHAR instead of DECODE_CHAR.
+       (CODING_DECODE_CHAR): Add a comment describing its purpose.
+
 2010-03-02  Kenichi Handa  <handa@m17n.org>
 
        * character.c (parse_str_as_multibyte): Fix handling of the
index 2144fe5..27931c1 100644 (file)
@@ -1005,6 +1005,10 @@ record_conversion_result (struct coding_system *coding,
     }
 }
 
+/* This wrapper macro is used to preserve validity of pointers into
+   buffer text across calls to decode_char, which could cause
+   relocation of buffers if it loads a charset map, because loading a
+   charset map allocates large structures.  */
 #define CODING_DECODE_CHAR(coding, src, src_base, src_end, charset, code, c) \
   do {                                                                      \
     charset_map_loaded = 0;                                                 \
@@ -2178,7 +2182,7 @@ emacs_mule_char (coding, src, nbytes, nchars, id, cmp_status)
        default:
          abort ();
        }
-      c = DECODE_CHAR (charset, code);
+      CODING_DECODE_CHAR (coding, src, src_base, src_end, charset, code, c);
       if (c < 0)
        goto invalid_code;
     }
@@ -2525,9 +2529,23 @@ decode_coding_emacs_mule (coding)
       else
        {
          int nchars, nbytes;
+         /* emacs_mule_char can load a charset map from a file, which
+            allocates a large structure and might cause buffer text
+            to be relocated as result.  Thus, we need to remember the
+            original pointer to buffer text, and fixup all related
+            pointers after the call.  */
+         const unsigned char *orig = coding->source;
+         EMACS_INT offset;
 
          c = emacs_mule_char (coding, src_base, &nbytes, &nchars, &id,
                               cmp_status);
+         offset = coding->source - orig;
+         if (offset)
+           {
+             src += offset;
+             src_base += offset;
+             src_end += offset;
+           }
          if (c < 0)
            {
              if (c == -1)