# HG changeset patch # User Eli Zaretskii # Date 1267562144 -7200 # Node ID 9b814b3ee348e9b48cfa5bbe66f4245f91847854 # Parent d2bfe26756ed30f44660e46c252346c77d027bc0 Fix bug in decoding emacs-mule encoding. 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. diff -r d2bfe26756ed -r 9b814b3ee348 src/ChangeLog --- a/src/ChangeLog Tue Mar 02 10:32:45 2010 +0100 +++ b/src/ChangeLog Tue Mar 02 22:35:44 2010 +0200 @@ -1,3 +1,10 @@ +2010-03-02 Eli Zaretskii + + * 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 * character.c (parse_str_as_multibyte): Fix handling of the diff -r d2bfe26756ed -r 9b814b3ee348 src/coding.c --- a/src/coding.c Tue Mar 02 10:32:45 2010 +0100 +++ b/src/coding.c Tue Mar 02 22:35:44 2010 +0200 @@ -1005,6 +1005,10 @@ } } +/* 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 @@ 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 @@ 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)