From 75f80e63caa66ef6127738a9cfc875e876a9b5ff Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 2 Mar 2010 22:35:44 +0200 Subject: [PATCH] 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. --- src/ChangeLog | 7 +++++++ src/coding.c | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index aec692b39e..761beb2be5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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 --git a/src/coding.c b/src/coding.c index 2144fe5fcd..27931c123d 100644 --- a/src/coding.c +++ b/src/coding.c @@ -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) -- 2.20.1