* coding.c: Integer and buffer overflow fixes.
[bpt/emacs.git] / src / coding.c
index 9a6a448..25ac0e9 100644 (file)
@@ -55,8 +55,8 @@ CODING SYSTEM
   character sequence of emacs-utf-8 to a byte sequence of a specific
   coding system.
 
-  In Emacs Lisp, a coding system is represented by a Lisp symbol.  In
-  C level, a coding system is represented by a vector of attributes
+  In Emacs Lisp, a coding system is represented by a Lisp symbol.  On
+  the C level, a coding system is represented by a vector of attributes
   stored in the hash table Vcharset_hash_table.  The conversion from
   coding system symbol to attributes vector is done by looking up
   Vcharset_hash_table by the symbol.
@@ -159,7 +159,7 @@ detect_coding_XXX (struct coding_system *coding,
   const unsigned char *src = coding->source;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   ...;
 
@@ -266,7 +266,7 @@ encode_coding_XXX (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   unsigned char *adjusted_dst_end = dst_end - _MAX_BYTES_PRODUCED_IN_LOOP_;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
 
   for (; charbuf < charbuf_end && dst < adjusted_dst_end; charbuf++)
     {
@@ -300,27 +300,30 @@ encode_coding_XXX (struct coding_system *coding)
 
 Lisp_Object Vcoding_system_hash_table;
 
-Lisp_Object Qcoding_system, Qcoding_aliases, Qeol_type;
+static Lisp_Object Qcoding_system, Qeol_type;
+static Lisp_Object Qcoding_aliases;
 Lisp_Object Qunix, Qdos;
 Lisp_Object Qbuffer_file_coding_system;
-Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
-Lisp_Object Qdefault_char;
+static Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
+static Lisp_Object Qdefault_char;
 Lisp_Object Qno_conversion, Qundecided;
-Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5;
-Lisp_Object Qbig, Qlittle;
-Lisp_Object Qcoding_system_history;
-Lisp_Object Qvalid_codes;
-Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
-Lisp_Object QCdecode_translation_table, QCencode_translation_table;
-Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
-Lisp_Object QCascii_compatible_p;
+Lisp_Object Qcharset, Qutf_8;
+static Lisp_Object Qiso_2022;
+static Lisp_Object Qutf_16, Qshift_jis, Qbig5;
+static Lisp_Object Qbig, Qlittle;
+static Lisp_Object Qcoding_system_history;
+static Lisp_Object Qvalid_codes;
+static Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
+static Lisp_Object QCdecode_translation_table, QCencode_translation_table;
+static Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
+static Lisp_Object QCascii_compatible_p;
 
 Lisp_Object Qcall_process, Qcall_process_region;
 Lisp_Object Qstart_process, Qopen_network_stream;
-Lisp_Object Qtarget_idx;
+static Lisp_Object Qtarget_idx;
 
-Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
-Lisp_Object Qinterrupted, Qinsufficient_memory;
+static Lisp_Object Qinsufficient_source, Qinconsistent_eol, Qinvalid_source;
+static Lisp_Object Qinterrupted, Qinsufficient_memory;
 
 /* If a symbol has this property, evaluate the value to define the
    symbol as a coding system.  */
@@ -351,12 +354,12 @@ struct coding_system safe_terminal_coding;
 
 Lisp_Object Qtranslation_table;
 Lisp_Object Qtranslation_table_id;
-Lisp_Object Qtranslation_table_for_decode;
-Lisp_Object Qtranslation_table_for_encode;
+static Lisp_Object Qtranslation_table_for_decode;
+static Lisp_Object Qtranslation_table_for_encode;
 
 /* Two special coding systems.  */
-Lisp_Object Vsjis_coding_system;
-Lisp_Object Vbig5_coding_system;
+static Lisp_Object Vsjis_coding_system;
+static Lisp_Object Vbig5_coding_system;
 
 /* ISO2022 section */
 
@@ -753,7 +756,7 @@ static struct coding_system coding_categories[coding_category_max];
     produced_chars++;                  \
     if (multibytep)                    \
       {                                        \
-       int ch = (c);                   \
+       unsigned ch = (c);              \
        if (ch >= 0x80)                 \
          ch = BYTE8_TO_CHAR (ch);      \
        CHAR_STRING_ADVANCE (ch, dst);  \
@@ -770,7 +773,7 @@ static struct coding_system coding_categories[coding_category_max];
     produced_chars += 2;               \
     if (multibytep)                    \
       {                                        \
-       int ch;                         \
+       unsigned ch;                    \
                                        \
        ch = (c1);                      \
        if (ch >= 0x80)                 \
@@ -846,37 +849,36 @@ static int encode_coding_raw_text (struct coding_system *);
 
 static void coding_set_source (struct coding_system *);
 static void coding_set_destination (struct coding_system *);
-static void coding_alloc_by_realloc (struct coding_system *, EMACS_INT);
+static void coding_alloc_by_realloc (struct coding_system *, ptrdiff_t);
 static void coding_alloc_by_making_gap (struct coding_system *,
-                                        EMACS_INT, EMACS_INT);
+                                        ptrdiff_t, ptrdiff_t);
 static unsigned char *alloc_destination (struct coding_system *,
-                                         EMACS_INT, unsigned char *);
+                                         ptrdiff_t, unsigned char *);
 static void setup_iso_safe_charsets (Lisp_Object);
 static unsigned char *encode_designation_at_bol (struct coding_system *,
-                                                 int *, int *,
-                                                 unsigned char *);
+                                                 int *, unsigned char *);
 static int detect_eol (const unsigned char *,
-                       EMACS_INT, enum coding_category);
+                       ptrdiff_t, enum coding_category);
 static Lisp_Object adjust_coding_eol_type (struct coding_system *, int);
 static void decode_eol (struct coding_system *);
 static Lisp_Object get_translation_table (Lisp_Object, int, int *);
 static Lisp_Object get_translation (Lisp_Object, int *, int *);
 static int produce_chars (struct coding_system *, Lisp_Object, int);
-static INLINE void produce_charset (struct coding_system *, int *,
-                                    EMACS_INT);
-static void produce_annotation (struct coding_system *, EMACS_INT);
+static inline void produce_charset (struct coding_system *, int *,
+                                    ptrdiff_t);
+static void produce_annotation (struct coding_system *, ptrdiff_t);
 static int decode_coding (struct coding_system *);
-static INLINE int *handle_composition_annotation (EMACS_INT, EMACS_INT,
+static inline int *handle_composition_annotation (ptrdiff_t, ptrdiff_t,
                                                   struct coding_system *,
-                                                  int *, EMACS_INT *);
-static INLINE int *handle_charset_annotation (EMACS_INT, EMACS_INT,
+                                                  int *, ptrdiff_t *);
+static inline int *handle_charset_annotation (ptrdiff_t, ptrdiff_t,
                                               struct coding_system *,
-                                              int *, EMACS_INT *);
+                                              int *, ptrdiff_t *);
 static void consume_chars (struct coding_system *, Lisp_Object, int);
 static int encode_coding (struct coding_system *);
 static Lisp_Object make_conversion_work_buffer (int);
 static Lisp_Object code_conversion_restore (Lisp_Object);
-static INLINE int char_encodable_p (int, Lisp_Object);
+static inline int char_encodable_p (int, Lisp_Object);
 static Lisp_Object make_subsidiaries (Lisp_Object);
 
 static void
@@ -924,7 +926,7 @@ record_conversion_result (struct coding_system *coding,
     if (charset_map_loaded)                                                 \
       {                                                                             \
        const unsigned char *orig = coding->source;                          \
-       EMACS_INT offset;                                                    \
+       ptrdiff_t offset;                                                    \
                                                                             \
        coding_set_source (coding);                                          \
        offset = coding->source - orig;                                      \
@@ -944,7 +946,7 @@ record_conversion_result (struct coding_system *coding,
   do {                                                         \
     if (dst + (bytes) >= dst_end)                              \
       {                                                                \
-       int more_bytes = charbuf_end - charbuf + (bytes);       \
+       ptrdiff_t more_bytes = charbuf_end - charbuf + (bytes); \
                                                                \
        dst = alloc_destination (coding, more_bytes, dst);      \
        dst_end = coding->destination + coding->dst_bytes;      \
@@ -1067,8 +1069,10 @@ coding_set_destination (struct coding_system *coding)
 
 
 static void
-coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
+coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes)
 {
+  if (STRING_BYTES_BOUND - coding->dst_bytes < bytes)
+    string_overflow ();
   coding->destination = (unsigned char *) xrealloc (coding->destination,
                                                    coding->dst_bytes + bytes);
   coding->dst_bytes += bytes;
@@ -1076,7 +1080,7 @@ coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
 
 static void
 coding_alloc_by_making_gap (struct coding_system *coding,
-                           EMACS_INT gap_head_used, EMACS_INT bytes)
+                           ptrdiff_t gap_head_used, ptrdiff_t bytes)
 {
   if (EQ (coding->src_object, coding->dst_object))
     {
@@ -1084,7 +1088,7 @@ coding_alloc_by_making_gap (struct coding_system *coding,
         consumed data at the tail.  To preserve those data, we at
         first make the gap size to zero, then increase the gap
         size.  */
-      EMACS_INT add = GAP_SIZE;
+      ptrdiff_t add = GAP_SIZE;
 
       GPT += gap_head_used, GPT_BYTE += gap_head_used;
       GAP_SIZE = 0; ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
@@ -1105,10 +1109,10 @@ coding_alloc_by_making_gap (struct coding_system *coding,
 
 
 static unsigned char *
-alloc_destination (struct coding_system *coding, EMACS_INT nbytes,
+alloc_destination (struct coding_system *coding, ptrdiff_t nbytes,
                   unsigned char *dst)
 {
-  EMACS_INT offset = dst - coding->destination;
+  ptrdiff_t offset = dst - coding->destination;
 
   if (BUFFERP (coding->dst_object))
     {
@@ -1209,7 +1213,7 @@ detect_coding_utf_8 (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int bom_found = 0;
   int found = 0;
 
@@ -1294,16 +1298,13 @@ decode_coding_utf_8 (struct coding_system *coding)
   const unsigned char *src_base;
   int *charbuf = coding->charbuf + coding->charbuf_used;
   int *charbuf_end = coding->charbuf + coding->charbuf_size;
-  int consumed_chars = 0, consumed_chars_base = 0;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base = 0;
   int multibytep = coding->src_multibyte;
   enum utf_bom_type bom = CODING_UTF_8_BOM (coding);
-  Lisp_Object attr, charset_list;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
-  CODING_GET_INFO (coding, attr, charset_list);
-
   if (bom != utf_without_bom)
     {
       int c1, c2, c3;
@@ -1448,7 +1449,7 @@ encode_coding_utf_8 (struct coding_system *coding)
   int *charbuf_end = charbuf + coding->charbuf_used;
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int c;
 
   if (CODING_UTF_8_BOM (coding) == utf_with_bom)
@@ -1606,18 +1607,15 @@ decode_coding_utf_16 (struct coding_system *coding)
   int *charbuf = coding->charbuf + coding->charbuf_used;
   /* We may produces at most 3 chars in one loop.  */
   int *charbuf_end = coding->charbuf + coding->charbuf_size - 2;
-  int consumed_chars = 0, consumed_chars_base = 0;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base = 0;
   int multibytep = coding->src_multibyte;
   enum utf_bom_type bom = CODING_UTF_16_BOM (coding);
   enum utf_16_endian_type endian = CODING_UTF_16_ENDIAN (coding);
   int surrogate = CODING_UTF_16_SURROGATE (coding);
-  Lisp_Object attr, charset_list;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr1 = -1, byte_after_cr2 = -1;
 
-  CODING_GET_INFO (coding, attr, charset_list);
-
   if (bom == utf_with_bom)
     {
       int c, c1, c2;
@@ -1736,12 +1734,9 @@ encode_coding_utf_16 (struct coding_system *coding)
   int safe_room = 8;
   enum utf_bom_type bom = CODING_UTF_16_BOM (coding);
   int big_endian = CODING_UTF_16_ENDIAN (coding) == utf_16_big_endian;
-  int produced_chars = 0;
-  Lisp_Object attrs, charset_list;
+  ptrdiff_t produced_chars = 0;
   int c;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
-
   if (bom != utf_without_bom)
     {
       ASSURE_DESTINATION (safe_room);
@@ -1873,7 +1868,7 @@ detect_coding_emacs_mule (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int c;
   int found = 0;
 
@@ -2340,24 +2335,25 @@ decode_coding_emacs_mule (struct coding_system *coding)
   /* We may produce two annotations (charset and composition) in one
      loop and one more charset annotation at the end.  */
   int *charbuf_end
-    = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3);
-  int consumed_chars = 0, consumed_chars_base;
+    = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3)
+      /* We can produce up to 2 characters in a loop.  */
+      - 1;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
-  Lisp_Object attrs, charset_list;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
   struct composition_status *cmp_status = &coding->spec.emacs_mule.cmp_status;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
-
   if (cmp_status->state != COMPOSING_NO)
     {
       int i;
 
+      if (charbuf_end - charbuf < cmp_status->length)
+       abort ();
       for (i = 0; i < cmp_status->length; i++)
        *charbuf++ = cmp_status->carryover[i];
       coding->annotated = 1;
@@ -2417,7 +2413,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
             original pointer to buffer text, and fix up all related
             pointers after the call.  */
          const unsigned char *orig = coding->source;
-         EMACS_INT offset;
+         ptrdiff_t offset;
 
          c = emacs_mule_char (coding, src_base, &nbytes, &nchars, &id,
                               cmp_status);
@@ -2598,7 +2594,7 @@ encode_coding_emacs_mule (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 8;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int c;
   int preferred_charset_id = -1;
@@ -2872,7 +2868,7 @@ encode_coding_emacs_mule (struct coding_system *coding)
   COMPOSITION_WITH_RULE_ALTCHARS:
        ESC 4 ALTCHAR [ RULE ALTCHAR ] ESC 0 CHAR [ CHAR ] ESC 1 */
 
-enum iso_code_class_type iso_code_class[256];
+static enum iso_code_class_type iso_code_class[256];
 
 #define SAFE_CHARSET_P(coding, id)     \
   ((id) <= (coding)->max_charset_id    \
@@ -2885,7 +2881,7 @@ setup_iso_safe_charsets (Lisp_Object attrs)
   Lisp_Object request;
   Lisp_Object reg_usage;
   Lisp_Object tail;
-  int reg94, reg96;
+  EMACS_INT reg94, reg96;
   int flags = XINT (AREF (attrs, coding_attr_iso_flags));
   int max_charset_id;
 
@@ -2954,14 +2950,9 @@ detect_coding_iso_2022 (struct coding_system *coding,
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
   int single_shifting = 0;
-
-  /* FIXME: Does ID need to be initialized here?  The "End of composition"
-     code below does not initialize ID even though ID is used
-     afterwards, and perhaps that is a bug.  */
-  int id = 0;
-
+  int id;
   int c, c1;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int i;
   int rejected = 0;
   int found = 0;
@@ -2999,40 +2990,11 @@ detect_coding_iso_2022 (struct coding_system *coding,
            break;
          single_shifting = 0;
          ONE_MORE_BYTE (c);
-         if (c >= '(' && c <= '/')
-           {
-             /* Designation sequence for a charset of dimension 1.  */
-             ONE_MORE_BYTE (c1);
-             if (c1 < ' ' || c1 >= 0x80
-                 || (id = iso_charset_table[0][c >= ','][c1]) < 0)
-               /* Invalid designation sequence.  Just ignore.  */
-               break;
-           }
-         else if (c == '$')
-           {
-             /* Designation sequence for a charset of dimension 2.  */
-             ONE_MORE_BYTE (c);
-             if (c >= '@' && c <= 'B')
-               /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
-               id = iso_charset_table[1][0][c];
-             else if (c >= '(' && c <= '/')
-               {
-                 ONE_MORE_BYTE (c1);
-                 if (c1 < ' ' || c1 >= 0x80
-                     || (id = iso_charset_table[1][c >= ','][c1]) < 0)
-                   /* Invalid designation sequence.  Just ignore.  */
-                   break;
-               }
-             else
-               /* Invalid designation sequence.  Just ignore it.  */
-               break;
-           }
-         else if (c == 'N' || c == 'O')
+         if (c == 'N' || c == 'O')
            {
              /* ESC <Fe> for SS2 or SS3.  */
              single_shifting = 1;
              rejected |= CATEGORY_MASK_ISO_7BIT | CATEGORY_MASK_ISO_8BIT;
-             break;
            }
          else if (c == '1')
            {
@@ -3048,36 +3010,66 @@ detect_coding_iso_2022 (struct coding_system *coding,
            {
              /* ESC <Fp> for start/end composition.  */
              composition_count = 0;
-             break;
            }
          else
            {
-             /* Invalid escape sequence.  Just ignore it.  */
-             break;
-           }
+             if (c >= '(' && c <= '/')
+               {
+                 /* Designation sequence for a charset of dimension 1.  */
+                 ONE_MORE_BYTE (c1);
+                 if (c1 < ' ' || c1 >= 0x80
+                     || (id = iso_charset_table[0][c >= ','][c1]) < 0)
+                   /* Invalid designation sequence.  Just ignore.  */
+                   break;
+               }
+             else if (c == '$')
+               {
+                 /* Designation sequence for a charset of dimension 2.  */
+                 ONE_MORE_BYTE (c);
+                 if (c >= '@' && c <= 'B')
+                   /* Designation for JISX0208.1978, GB2312, or JISX0208.  */
+                   id = iso_charset_table[1][0][c];
+                 else if (c >= '(' && c <= '/')
+                   {
+                     ONE_MORE_BYTE (c1);
+                     if (c1 < ' ' || c1 >= 0x80
+                         || (id = iso_charset_table[1][c >= ','][c1]) < 0)
+                       /* Invalid designation sequence.  Just ignore.  */
+                       break;
+                   }
+                 else
+                   /* Invalid designation sequence.  Just ignore it.  */
+                   break;
+               }
+             else
+               {
+                 /* Invalid escape sequence.  Just ignore it.  */
+                 break;
+               }
 
-         /* We found a valid designation sequence for CHARSET.  */
-         rejected |= CATEGORY_MASK_ISO_8BIT;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
-                             id))
-           found |= CATEGORY_MASK_ISO_7;
-         else
-           rejected |= CATEGORY_MASK_ISO_7;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
-                             id))
-           found |= CATEGORY_MASK_ISO_7_TIGHT;
-         else
-           rejected |= CATEGORY_MASK_ISO_7_TIGHT;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
-                             id))
-           found |= CATEGORY_MASK_ISO_7_ELSE;
-         else
-           rejected |= CATEGORY_MASK_ISO_7_ELSE;
-         if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
-                             id))
-           found |= CATEGORY_MASK_ISO_8_ELSE;
-         else
-           rejected |= CATEGORY_MASK_ISO_8_ELSE;
+             /* We found a valid designation sequence for CHARSET.  */
+             rejected |= CATEGORY_MASK_ISO_8BIT;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7;
+             else
+               rejected |= CATEGORY_MASK_ISO_7;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_tight],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7_TIGHT;
+             else
+               rejected |= CATEGORY_MASK_ISO_7_TIGHT;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_7_else],
+                                 id))
+               found |= CATEGORY_MASK_ISO_7_ELSE;
+             else
+               rejected |= CATEGORY_MASK_ISO_7_ELSE;
+             if (SAFE_CHARSET_P (&coding_categories[coding_category_iso_8_else],
+                                 id))
+               found |= CATEGORY_MASK_ISO_8_ELSE;
+             else
+               rejected |= CATEGORY_MASK_ISO_8_ELSE;
+           }
          break;
 
        case ISO_CODE_SO:
@@ -3105,13 +3097,32 @@ detect_coding_iso_2022 (struct coding_system *coding,
          rejected |= CATEGORY_MASK_ISO_7BIT;
          if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
              & CODING_ISO_FLAG_SINGLE_SHIFT)
-           found |= CATEGORY_MASK_ISO_8_1, single_shifting = 1;
+           {
+             found |= CATEGORY_MASK_ISO_8_1;
+             single_shifting = 1;
+           }
          if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_2])
              & CODING_ISO_FLAG_SINGLE_SHIFT)
-           found |= CATEGORY_MASK_ISO_8_2, single_shifting = 1;
+           {
+             found |= CATEGORY_MASK_ISO_8_2;
+             single_shifting = 1;
+           }
          if (single_shifting)
            break;
-         goto check_extra_latin;
+       check_extra_latin:
+         if (! VECTORP (Vlatin_extra_code_table)
+             || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
+           {
+             rejected = CATEGORY_MASK_ISO;
+             break;
+           }
+         if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
+             & CODING_ISO_FLAG_LATIN_EXTRA)
+           found |= CATEGORY_MASK_ISO_8_1;
+         else
+           rejected |= CATEGORY_MASK_ISO_8_1;
+         rejected |= CATEGORY_MASK_ISO_8_2;
+         break;
 
        default:
          if (c < 0)
@@ -3162,20 +3173,6 @@ detect_coding_iso_2022 (struct coding_system *coding,
                }
              break;
            }
-       check_extra_latin:
-         single_shifting = 0;
-         if (! VECTORP (Vlatin_extra_code_table)
-             || NILP (XVECTOR (Vlatin_extra_code_table)->contents[c]))
-           {
-             rejected = CATEGORY_MASK_ISO;
-             break;
-           }
-         if (CODING_ISO_FLAGS (&coding_categories[coding_category_iso_8_1])
-             & CODING_ISO_FLAG_LATIN_EXTRA)
-           found |= CATEGORY_MASK_ISO_8_1;
-         else
-           rejected |= CATEGORY_MASK_ISO_8_1;
-         rejected |= CATEGORY_MASK_ISO_8_2;
        }
     }
   detect_info->rejected |= CATEGORY_MASK_ISO;
@@ -3265,15 +3262,14 @@ detect_coding_iso_2022 (struct coding_system *coding,
 */
 
 /* Decode a composition rule C1 and maybe one more byte from the
-   source, and set RULE to the encoded composition rule, NBYTES to the
-   length of the composition rule.  If the rule is invalid, set RULE
-   to some negative value.  */
+   source, and set RULE to the encoded composition rule.  If the rule
+   is invalid, goto invalid_code.  */
 
-#define DECODE_COMPOSITION_RULE(rule, nbytes)                          \
+#define DECODE_COMPOSITION_RULE(rule)                                  \
   do {                                                                 \
     rule = c1 - 32;                                                    \
     if (rule < 0)                                                      \
-      break;                                                           \
+      goto invalid_code;                                               \
     if (rule < 81)             /* old format (before ver.21) */        \
       {                                                                        \
        int gref = (rule) / 9;                                          \
@@ -3281,17 +3277,16 @@ detect_coding_iso_2022 (struct coding_system *coding,
        if (gref == 4) gref = 10;                                       \
        if (nref == 4) nref = 10;                                       \
        rule = COMPOSITION_ENCODE_RULE (gref, nref);                    \
-       nbytes = 1;                                                     \
       }                                                                        \
     else                       /* new format (after ver.21) */         \
       {                                                                        \
        int b;                                                          \
                                                                        \
        ONE_MORE_BYTE (b);                                              \
+       if (! COMPOSITION_ENCODE_RULE_VALID (rule - 81, b - 32))        \
+         goto invalid_code;                                            \
        rule = COMPOSITION_ENCODE_RULE (rule - 81, b - 32);             \
-       if (rule >= 0)                                                  \
-         rule += 0x100;   /* to destinguish it from the old format */  \
-       nbytes = 2;                                                     \
+       rule += 0x100;   /* Distinguish it from the old format.  */     \
       }                                                                        \
   } while (0)
 
@@ -3467,7 +3462,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
      loop and one more charset annotation at the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 3);
-  int consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   /* Charsets invoked to graphic plane 0 and 1 respectively.  */
   int charset_id_0 = CODING_ISO_INVOKED_CHARSET (coding, 0);
@@ -3476,23 +3471,22 @@ decode_coding_iso_2022 (struct coding_system *coding)
   struct charset *charset;
   int c;
   struct composition_status *cmp_status = CODING_ISO_CMP_STATUS (coding);
-  Lisp_Object attrs, charset_list;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
   int i;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
   setup_iso_safe_charsets (attrs);
-  /* Charset list may have been changed.  */
-  charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   coding->safe_charsets = SDATA (CODING_ATTR_SAFE_CHARSETS (attrs));
 
   if (cmp_status->state != COMPOSING_NO)
     {
+      if (charbuf_end - charbuf < cmp_status->length)
+       abort ();
       for (i = 0; i < cmp_status->length; i++)
        *charbuf++ = cmp_status->carryover[i];
       coding->annotated = 1;
@@ -3558,11 +3552,9 @@ decode_coding_iso_2022 (struct coding_system *coding)
           || cmp_status->state == COMPOSING_COMPONENT_RULE)
          && c1 != ISO_CODE_ESC)
        {
-         int rule, nbytes;
+         int rule;
 
-         DECODE_COMPOSITION_RULE (rule, nbytes);
-         if (rule < 0)
-           goto invalid_code;
+         DECODE_COMPOSITION_RULE (rule);
          STORE_COMPOSITION_RULE (rule);
          continue;
        }
@@ -4193,7 +4185,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
 
 #define ENCODE_ISO_CHARACTER(charset, c)                                  \
   do {                                                                    \
-    int code = ENCODE_CHAR ((charset), (c));                              \
+    unsigned code = ENCODE_CHAR ((charset), (c));                         \
                                                                           \
     if (CHARSET_DIMENSION (charset) == 1)                                 \
       ENCODE_ISO_CHARACTER_DIMENSION1 ((charset), code);                  \
@@ -4209,10 +4201,10 @@ decode_coding_iso_2022 (struct coding_system *coding)
 static unsigned char *
 encode_invocation_designation (struct charset *charset,
                               struct coding_system *coding,
-                              unsigned char *dst, int *p_nchars)
+                              unsigned char *dst, ptrdiff_t *p_nchars)
 {
   int multibytep = coding->dst_multibyte;
-  int produced_chars = *p_nchars;
+  ptrdiff_t produced_chars = *p_nchars;
   int reg;                     /* graphic register number */
   int id = CHARSET_ID (charset);
 
@@ -4298,13 +4290,13 @@ encode_invocation_designation (struct charset *charset,
 
 static unsigned char *
 encode_designation_at_bol (struct coding_system *coding, int *charbuf,
-                          int *charbuf_end, unsigned char *dst)
+                          unsigned char *dst)
 {
   struct charset *charset;
   /* Table of charsets to be designated to each graphic register.  */
   int r[4];
   int c, found = 0, reg;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int multibytep = coding->dst_multibyte;
   Lisp_Object attrs;
   Lisp_Object charset_list;
@@ -4359,7 +4351,7 @@ encode_coding_iso_2022 (struct coding_system *coding)
   int bol_designation
     = (CODING_ISO_FLAGS (coding) & CODING_ISO_FLAG_DESIGNATE_AT_BOL
        && CODING_ISO_BOL (coding));
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, eol_type, charset_list;
   int ascii_compatible;
   int c;
@@ -4389,7 +4381,7 @@ encode_coding_iso_2022 (struct coding_system *coding)
          unsigned char *dst_prev = dst;
 
          /* We have to produce designation sequences if any now.  */
-         dst = encode_designation_at_bol (coding, charbuf, charbuf_end, dst);
+         dst = encode_designation_at_bol (coding, charbuf, dst);
          bol_designation = 0;
          /* We are sure that designation sequences are all ASCII bytes.  */
          produced_chars += dst - dst_prev;
@@ -4547,7 +4539,7 @@ detect_coding_sjis (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   int c;
   Lisp_Object attrs, charset_list;
@@ -4604,7 +4596,7 @@ detect_coding_big5 (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   int c;
 
@@ -4655,13 +4647,13 @@ decode_coding_sjis (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   struct charset *charset_roman, *charset_kanji, *charset_kana;
   struct charset *charset_kanji2;
   Lisp_Object attrs, charset_list, val;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -4773,12 +4765,12 @@ decode_coding_big5 (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
   struct charset *charset_roman, *charset_big5;
   Lisp_Object attrs, charset_list, val;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
@@ -4875,16 +4867,15 @@ encode_coding_sjis (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 4;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
-  struct charset *charset_roman, *charset_kanji, *charset_kana;
+  struct charset *charset_kanji, *charset_kana;
   struct charset *charset_kanji2;
   int c;
 
   CODING_GET_INFO (coding, attrs, charset_list);
-  val = charset_list;
-  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
+  val = XCDR (charset_list);
   charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji2 = NILP (val) ? NULL : CHARSET_FROM_ID (XINT (XCAR (val)));
@@ -4967,15 +4958,14 @@ encode_coding_big5 (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = 4;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list, val;
   int ascii_compatible;
-  struct charset *charset_roman, *charset_big5;
+  struct charset *charset_big5;
   int c;
 
   CODING_GET_INFO (coding, attrs, charset_list);
-  val = charset_list;
-  charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
+  val = XCDR (charset_list);
   charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
   ascii_compatible = ! NILP (CODING_ATTR_ASCII_COMPAT (attrs));
 
@@ -5043,10 +5033,10 @@ detect_coding_ccl (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int found = 0;
   unsigned char *valids;
-  int head_ascii = coding->head_ascii;
+  ptrdiff_t head_ascii = coding->head_ascii;
   Lisp_Object attrs;
 
   detect_info->checked |= CATEGORY_MASK_CCL;
@@ -5083,7 +5073,7 @@ decode_coding_ccl (struct coding_system *coding)
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int *charbuf = coding->charbuf + coding->charbuf_used;
   int *charbuf_end = coding->charbuf + coding->charbuf_size;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   int multibytep = coding->src_multibyte;
   struct ccl_program *ccl = &coding->spec.ccl->ccl;
   int source_charbuf[1024];
@@ -5155,7 +5145,8 @@ encode_coding_ccl (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int destination_charbuf[1024];
-  int i, produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
+  int i;
   Lisp_Object attrs, charset_list;
 
   CODING_GET_INFO (coding, attrs, charset_list);
@@ -5241,7 +5232,7 @@ encode_coding_raw_text (struct coding_system *coding)
   int *charbuf_end = coding->charbuf + coding->charbuf_used;
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   int c;
 
   if (multibytep)
@@ -5265,11 +5256,12 @@ encode_coding_raw_text (struct coding_system *coding)
                unsigned char str[MAX_MULTIBYTE_LENGTH], *p0 = str, *p1 = str;
 
                CHAR_STRING_ADVANCE (c, p1);
-               while (p0 < p1)
+               do
                  {
                    EMIT_ONE_BYTE (*p0);
                    p0++;
                  }
+               while (p0 < p1);
              }
          }
       else
@@ -5323,10 +5315,10 @@ detect_coding_charset (struct coding_system *coding,
   const unsigned char *src = coding->source, *src_base;
   const unsigned char *src_end = coding->source + coding->src_bytes;
   int multibytep = coding->src_multibyte;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   Lisp_Object attrs, valids, name;
   int found = 0;
-  int head_ascii = coding->head_ascii;
+  ptrdiff_t head_ascii = coding->head_ascii;
   int check_latin_extra = 0;
 
   detect_info->checked |= CATEGORY_MASK_CHARSET;
@@ -5376,8 +5368,8 @@ detect_coding_charset (struct coding_system *coding,
              if (src == src_end)
                goto too_short;
              ONE_MORE_BYTE (c);
-             if (c < charset->code_space[(dim - 1 - idx) * 2]
-                 || c > charset->code_space[(dim - 1 - idx) * 2 + 1])
+             if (c < charset->code_space[(dim - 1 - idx) * 4]
+                 || c > charset->code_space[(dim - 1 - idx) * 4 + 1])
                break;
            }
          if (idx < dim)
@@ -5430,17 +5422,17 @@ decode_coding_charset (struct coding_system *coding)
      the end.  */
   int *charbuf_end
     = coding->charbuf + coding->charbuf_size - (MAX_ANNOTATION_LENGTH * 2);
-  int consumed_chars = 0, consumed_chars_base;
+  ptrdiff_t consumed_chars = 0, consumed_chars_base;
   int multibytep = coding->src_multibyte;
-  Lisp_Object attrs, charset_list, valids;
-  int char_offset = coding->produced_char;
-  int last_offset = char_offset;
+  Lisp_Object attrs = CODING_ID_ATTRS (coding->id);
+  Lisp_Object valids;
+  ptrdiff_t char_offset = coding->produced_char;
+  ptrdiff_t last_offset = char_offset;
   int last_id = charset_ascii;
   int eol_dos =
     !inhibit_eol_conversion && EQ (CODING_ID_EOL_TYPE (coding->id), Qdos);
   int byte_after_cr = -1;
 
-  CODING_GET_INFO (coding, attrs, charset_list);
   valids = AREF (attrs, coding_attr_charset_valids);
 
   while (1)
@@ -5556,7 +5548,7 @@ encode_coding_charset (struct coding_system *coding)
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
   int safe_room = MAX_MULTIBYTE_LENGTH;
-  int produced_chars = 0;
+  ptrdiff_t produced_chars = 0;
   Lisp_Object attrs, charset_list;
   int ascii_compatible;
   int c;
@@ -5846,7 +5838,7 @@ coding_charset_list (struct coding_system *coding)
 Lisp_Object
 coding_system_charset_list (Lisp_Object coding_system)
 {
-  int id;
+  ptrdiff_t id;
   Lisp_Object attrs, charset_list;
 
   CHECK_CODING_SYSTEM_GET_ID (coding_system, id);
@@ -6103,7 +6095,7 @@ complement_process_encoding_system (Lisp_Object coding_system)
 #define MAX_EOL_CHECK_COUNT 3
 
 static int
-detect_eol (const unsigned char *source, EMACS_INT src_bytes,
+detect_eol (const unsigned char *source, ptrdiff_t src_bytes,
            enum coding_category category)
 {
   const unsigned char *src = source, *src_end = src + src_bytes;
@@ -6228,7 +6220,7 @@ adjust_coding_eol_type (struct coding_system *coding, int eol_seen)
    system is detected, update fields of CODING by the detected coding
    system.  */
 
-void
+static void
 detect_coding (struct coding_system *coding)
 {
   const unsigned char *src, *src_end;
@@ -6464,7 +6456,7 @@ decode_eol (struct coding_system *coding)
     }
   else if (EQ (eol_type, Qdos))
     {
-      int n = 0;
+      ptrdiff_t n = 0;
 
       if (NILP (coding->dst_object))
        {
@@ -6479,9 +6471,9 @@ decode_eol (struct coding_system *coding)
        }
       else
        {
-         int pos_byte = coding->dst_pos_byte;
-         int pos = coding->dst_pos;
-         int pos_end = pos + coding->produced_char - 1;
+         ptrdiff_t pos_byte = coding->dst_pos_byte;
+         ptrdiff_t pos = coding->dst_pos;
+         ptrdiff_t pos_end = pos + coding->produced_char - 1;
 
          while (pos < pos_end)
            {
@@ -6621,8 +6613,8 @@ get_translation (Lisp_Object trans, int *buf, int *buf_end)
     {
       Lisp_Object val = XCAR (trans);
       Lisp_Object from = XCAR (val);
-      int len = ASIZE (from);
-      int i;
+      ptrdiff_t len = ASIZE (from);
+      ptrdiff_t i;
 
       for (i = 0; i < len; i++)
        {
@@ -6644,8 +6636,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 {
   unsigned char *dst = coding->destination + coding->produced;
   unsigned char *dst_end = coding->destination + coding->dst_bytes;
-  EMACS_INT produced;
-  EMACS_INT produced_chars = 0;
+  ptrdiff_t produced;
+  ptrdiff_t produced_chars = 0;
   int carryover = 0;
 
   if (! coding->chars_at_source)
@@ -6666,7 +6658,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
 
          if (c >= 0)
            {
-             int from_nchars = 1, to_nchars = 1;
+             ptrdiff_t from_nchars = 1, to_nchars = 1;
              Lisp_Object trans = Qnil;
 
              LOOKUP_TRANSLATION_TABLE (translation_table, c, trans);
@@ -6691,8 +6683,12 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                    break;
                }
 
-             if (dst + MAX_MULTIBYTE_LENGTH * to_nchars > dst_end)
+             if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars)
                {
+                 if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf))
+                      / MAX_MULTIBYTE_LENGTH)
+                     < to_nchars)
+                   memory_full (SIZE_MAX);
                  dst = alloc_destination (coding,
                                           buf_end - buf
                                           + MAX_MULTIBYTE_LENGTH * to_nchars,
@@ -6739,7 +6735,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
          if (coding->src_multibyte)
            {
              int multibytep = 1;
-             EMACS_INT consumed_chars = 0;
+             ptrdiff_t consumed_chars = 0;
 
              while (1)
                {
@@ -6753,7 +6749,7 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                        dst_end = (unsigned char *) src;
                      if (dst == dst_end)
                        {
-                         EMACS_INT offset = src - coding->source;
+                         ptrdiff_t offset = src - coding->source;
 
                          dst = alloc_destination (coding, src_end - src + 1,
                                                   dst);
@@ -6783,8 +6779,8 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
                      dst_end = (unsigned char *) src;
                    if (dst >= dst_end - 1)
                      {
-                       EMACS_INT offset = src - coding->source;
-                       EMACS_INT more_bytes;
+                       ptrdiff_t offset = src - coding->source;
+                       ptrdiff_t more_bytes;
 
                        if (EQ (coding->src_object, coding->dst_object))
                          more_bytes = ((src_end - src) / 2) + 2;
@@ -6806,11 +6802,11 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
        {
          if (!EQ (coding->src_object, coding->dst_object))
            {
-             EMACS_INT require = coding->src_bytes - coding->dst_bytes;
+             ptrdiff_t require = coding->src_bytes - coding->dst_bytes;
 
              if (require > 0)
                {
-                 EMACS_INT offset = src - coding->source;
+                 ptrdiff_t offset = src - coding->source;
 
                  dst = alloc_destination (coding, require, dst);
                  coding_set_source (coding);
@@ -6837,11 +6833,11 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table,
      [ -LENGTH ANNOTATION_MASK NCHARS NBYTES METHOD [ COMPONENTS... ] ]
  */
 
-static INLINE void
-produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
+static inline void
+produce_composition (struct coding_system *coding, int *charbuf, ptrdiff_t pos)
 {
   int len;
-  EMACS_INT to;
+  ptrdiff_t to;
   enum composition_method method;
   Lisp_Object components;
 
@@ -6881,10 +6877,10 @@ produce_composition (struct coding_system *coding, int *charbuf, EMACS_INT pos)
      [ -LENGTH ANNOTATION_MASK NCHARS CHARSET-ID ]
  */
 
-static INLINE void
-produce_charset (struct coding_system *coding, int *charbuf, EMACS_INT pos)
+static inline void
+produce_charset (struct coding_system *coding, int *charbuf, ptrdiff_t pos)
 {
-  EMACS_INT from = pos - charbuf[2];
+  ptrdiff_t from = pos - charbuf[2];
   struct charset *charset = CHARSET_FROM_ID (charbuf[3]);
 
   Fput_text_property (make_number (from), make_number (pos),
@@ -6917,7 +6913,7 @@ produce_charset (struct coding_system *coding, int *charbuf, EMACS_INT pos)
 
 
 static void
-produce_annotation (struct coding_system *coding, EMACS_INT pos)
+produce_annotation (struct coding_system *coding, ptrdiff_t pos)
 {
   int *charbuf = coding->charbuf;
   int *charbuf_end = charbuf + coding->charbuf_used;
@@ -7017,7 +7013,7 @@ decode_coding (struct coding_system *coding)
     }
   do
     {
-      EMACS_INT pos = coding->dst_pos + coding->produced_char;
+      ptrdiff_t pos = coding->dst_pos + coding->produced_char;
 
       coding_set_source (coding);
       coding->annotated = 0;
@@ -7109,12 +7105,12 @@ decode_coding (struct coding_system *coding)
    position of a composition after POS (if any) or to LIMIT, and
    return BUF.  */
 
-static INLINE int *
-handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
+static inline int *
+handle_composition_annotation (ptrdiff_t pos, ptrdiff_t limit,
                               struct coding_system *coding, int *buf,
-                              EMACS_INT *stop)
+                              ptrdiff_t *stop)
 {
-  EMACS_INT start, end;
+  ptrdiff_t start, end;
   Lisp_Object prop;
 
   if (! find_composition (pos, limit, &start, &end, &prop, coding->src_object)
@@ -7136,12 +7132,12 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
          if (method != COMPOSITION_RELATIVE)
            {
              Lisp_Object components;
-             int len, i, i_byte;
+             ptrdiff_t i, len, i_byte;
 
              components = COMPOSITION_COMPONENTS (prop);
              if (VECTORP (components))
                {
-                 len = XVECTOR (components)->size;
+                 len = ASIZE (components);
                  for (i = 0; i < len; i++)
                    *buf++ = XINT (AREF (components, i));
                }
@@ -7192,10 +7188,10 @@ handle_composition_annotation (EMACS_INT pos, EMACS_INT limit,
    If the property value is nil, set *STOP to the position where the
    property value is non-nil (limiting by LIMIT), and return BUF.  */
 
-static INLINE int *
-handle_charset_annotation (EMACS_INT pos, EMACS_INT limit,
+static inline int *
+handle_charset_annotation (ptrdiff_t pos, ptrdiff_t limit,
                           struct coding_system *coding, int *buf,
-                          EMACS_INT *stop)
+                          ptrdiff_t *stop)
 {
   Lisp_Object val, next;
   int id;
@@ -7222,12 +7218,12 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
   int *buf_end = coding->charbuf + coding->charbuf_size;
   const unsigned char *src = coding->source + coding->consumed;
   const unsigned char *src_end = coding->source + coding->src_bytes;
-  EMACS_INT pos = coding->src_pos + coding->consumed_char;
-  EMACS_INT end_pos = coding->src_pos + coding->src_chars;
+  ptrdiff_t pos = coding->src_pos + coding->consumed_char;
+  ptrdiff_t end_pos = coding->src_pos + coding->src_chars;
   int multibytep = coding->src_multibyte;
   Lisp_Object eol_type;
   int c;
-  EMACS_INT stop, stop_composition, stop_charset;
+  ptrdiff_t stop, stop_composition, stop_charset;
   int *lookup_buf = NULL;
 
   if (! NILP (translation_table))
@@ -7276,7 +7272,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
 
       if (! multibytep)
        {
-         EMACS_INT bytes;
+         int bytes;
 
          if (coding->encoder == encode_coding_raw_text
              || coding->encoder == encode_coding_ccl)
@@ -7307,7 +7303,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
        *buf++ = c;
       else
        {
-         int from_nchars = 1, to_nchars = 1;
+         ptrdiff_t from_nchars = 1, to_nchars = 1;
          int *lookup_buf_end;
          const unsigned char *p = src;
          int i;
@@ -7328,7 +7324,7 @@ consume_chars (struct coding_system *coding, Lisp_Object translation_table,
              else
                {
                  to_nchars = ASIZE (trans);
-                 if (buf + to_nchars > buf_end)
+                 if (buf_end - buf < to_nchars)
                    break;
                  c = XINT (AREF (trans, 0));
                }
@@ -7502,9 +7498,9 @@ code_conversion_save (int with_work_buf, int multibyte)
 
 int
 decode_coding_gap (struct coding_system *coding,
-                  EMACS_INT chars, EMACS_INT bytes)
+                  ptrdiff_t chars, ptrdiff_t bytes)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object attrs;
 
   code_conversion_save (0, 0);
@@ -7531,7 +7527,7 @@ decode_coding_gap (struct coding_system *coding,
   attrs = CODING_ID_ATTRS (coding->id);
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
     {
-      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
+      ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
 
       TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
@@ -7546,30 +7542,6 @@ decode_coding_gap (struct coding_system *coding,
   return coding->result;
 }
 
-int
-encode_coding_gap (struct coding_system *coding,
-                  EMACS_INT chars, EMACS_INT bytes)
-{
-  int count = SPECPDL_INDEX ();
-
-  code_conversion_save (0, 0);
-
-  coding->src_object = Fcurrent_buffer ();
-  coding->src_chars = chars;
-  coding->src_bytes = bytes;
-  coding->src_pos = -chars;
-  coding->src_pos_byte = -bytes;
-  coding->src_multibyte = chars < bytes;
-  coding->dst_object = coding->src_object;
-  coding->dst_pos = PT;
-  coding->dst_pos_byte = PT_BYTE;
-
-  encode_coding (coding);
-
-  unbind_to (count, Qnil);
-  return coding->result;
-}
-
 
 /* Decode the text in the range FROM/FROM_BYTE and TO/TO_BYTE in
    SRC_OBJECT into DST_OBJECT by coding context CODING.
@@ -7603,15 +7575,15 @@ encode_coding_gap (struct coding_system *coding,
 void
 decode_coding_object (struct coding_system *coding,
                      Lisp_Object src_object,
-                     EMACS_INT from, EMACS_INT from_byte,
-                     EMACS_INT to, EMACS_INT to_byte,
+                     ptrdiff_t from, ptrdiff_t from_byte,
+                     ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   unsigned char *destination IF_LINT (= NULL);
-  EMACS_INT dst_bytes IF_LINT (= 0);
-  EMACS_INT chars = to - from;
-  EMACS_INT bytes = to_byte - from_byte;
+  ptrdiff_t dst_bytes IF_LINT (= 0);
+  ptrdiff_t chars = to - from;
+  ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
   int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
@@ -7704,7 +7676,7 @@ decode_coding_object (struct coding_system *coding,
   if (! NILP (CODING_ATTR_POST_READ (attrs)))
     {
       struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
-      EMACS_INT prev_Z = Z, prev_Z_BYTE = Z_BYTE;
+      ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE;
       Lisp_Object val;
 
       TEMP_SET_PT_BOTH (coding->dst_pos, coding->dst_pos_byte);
@@ -7793,13 +7765,13 @@ decode_coding_object (struct coding_system *coding,
 void
 encode_coding_object (struct coding_system *coding,
                      Lisp_Object src_object,
-                     EMACS_INT from, EMACS_INT from_byte,
-                     EMACS_INT to, EMACS_INT to_byte,
+                     ptrdiff_t from, ptrdiff_t from_byte,
+                     ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  int count = SPECPDL_INDEX ();
-  EMACS_INT chars = to - from;
-  EMACS_INT bytes = to_byte - from_byte;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  ptrdiff_t chars = to - from;
+  ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
   int saved_pt = -1, saved_pt_byte IF_LINT (= 0);
   int need_marker_adjustment = 0;
@@ -7920,11 +7892,10 @@ encode_coding_object (struct coding_system *coding,
     }
   else if (EQ (dst_object, Qt))
     {
+      ptrdiff_t dst_bytes = max (1, coding->src_chars);
       coding->dst_object = Qnil;
-      coding->dst_bytes = coding->src_chars;
-      if (coding->dst_bytes == 0)
-       coding->dst_bytes = 1;
-      coding->destination = (unsigned char *) xmalloc (coding->dst_bytes);
+      coding->destination = (unsigned char *) xmalloc (dst_bytes);
+      coding->dst_bytes = dst_bytes;
       coding->dst_multibyte = 0;
     }
   else
@@ -8048,7 +8019,7 @@ are lower-case).  */)
   (Lisp_Object prompt, Lisp_Object default_coding_system)
 {
   Lisp_Object val;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   if (SYMBOLP (default_coding_system))
     default_coding_system = SYMBOL_NAME (default_coding_system);
@@ -8100,7 +8071,7 @@ function `define-coding-system'.  */)
 
 Lisp_Object
 detect_coding_system (const unsigned char *src,
-                     EMACS_INT src_chars, EMACS_INT src_bytes,
+                     ptrdiff_t src_chars, ptrdiff_t src_bytes,
                      int highest, int multibytep,
                      Lisp_Object coding_system)
 {
@@ -8108,7 +8079,7 @@ detect_coding_system (const unsigned char *src,
   Lisp_Object attrs, eol_type;
   Lisp_Object val = Qnil;
   struct coding_system coding;
-  int id;
+  ptrdiff_t id;
   struct coding_detection_info detect_info;
   enum coding_category base_category;
   int null_byte_found = 0, eight_bit_found = 0;
@@ -8420,8 +8391,8 @@ If optional argument HIGHEST is non-nil, return the coding system of
 highest priority.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object highest)
 {
-  int from, to;
-  int from_byte, to_byte;
+  ptrdiff_t from, to;
+  ptrdiff_t from_byte, to_byte;
 
   CHECK_NUMBER_COERCE_MARKER (start);
   CHECK_NUMBER_COERCE_MARKER (end);
@@ -8467,7 +8438,7 @@ highest priority.  */)
 }
 
 
-static INLINE int
+static inline int
 char_encodable_p (int c, Lisp_Object attrs)
 {
   Lisp_Object tail;
@@ -8501,7 +8472,7 @@ DEFUN ("find-coding-systems-region-internal",
   (Lisp_Object start, Lisp_Object end, Lisp_Object exclude)
 {
   Lisp_Object coding_attrs_list, safe_codings;
-  EMACS_INT start_byte, end_byte;
+  ptrdiff_t start_byte, end_byte;
   const unsigned char *p, *pbeg, *pend;
   int c;
   Lisp_Object tail, elt, work_table;
@@ -8595,7 +8566,7 @@ DEFUN ("find-coding-systems-region-internal",
            }
          if (charset_map_loaded)
            {
-             EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
+             ptrdiff_t p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
                pbeg = SDATA (start);
@@ -8633,11 +8604,11 @@ for un-encodable characters.  In that case, START and END are indexes
 to the string.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object count, Lisp_Object string)
 {
-  int n;
+  EMACS_INT n;
   struct coding_system coding;
   Lisp_Object attrs, charset_list, translation_table;
   Lisp_Object positions;
-  int from, to;
+  ptrdiff_t from, to;
   const unsigned char *p, *stop, *pend;
   int ascii_compatible;
 
@@ -8670,11 +8641,10 @@ to the string.  */)
       CHECK_STRING (string);
       CHECK_NATNUM (start);
       CHECK_NATNUM (end);
+      if (! (XINT (start) <= XINT (end) && XINT (end) <= SCHARS (string)))
+       args_out_of_range_3 (string, start, end);
       from = XINT (start);
       to = XINT (end);
-      if (from > to
-         || to > SCHARS (string))
-       args_out_of_range_3 (string, start, end);
       if (! STRING_MULTIBYTE (string))
        return Qnil;
       p = SDATA (string) + string_char_to_byte (string, from);
@@ -8749,8 +8719,8 @@ is nil.  */)
   (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system_list)
 {
   Lisp_Object list;
-  EMACS_INT start_byte, end_byte;
-  int pos;
+  ptrdiff_t start_byte, end_byte;
+  ptrdiff_t pos;
   const unsigned char *p, *pbeg, *pend;
   int c;
   Lisp_Object tail, elt, attrs;
@@ -8823,7 +8793,7 @@ is nil.  */)
            }
          if (charset_map_loaded)
            {
-             EMACS_INT p_offset = p - pbeg, pend_offset = pend - pbeg;
+             ptrdiff_t p_offset = p - pbeg, pend_offset = pend - pbeg;
 
              if (STRINGP (start))
                pbeg = SDATA (start);
@@ -8850,13 +8820,13 @@ is nil.  */)
 }
 
 
-Lisp_Object
+static Lisp_Object
 code_convert_region (Lisp_Object start, Lisp_Object end,
                     Lisp_Object coding_system, Lisp_Object dst_object,
                     int encodep, int norecord)
 {
   struct coding_system coding;
-  EMACS_INT from, from_byte, to, to_byte;
+  ptrdiff_t from, from_byte, to, to_byte;
   Lisp_Object src_object;
 
   CHECK_NUMBER_COERCE_MARKER (start);
@@ -8944,7 +8914,7 @@ code_convert_string (Lisp_Object string, Lisp_Object coding_system,
                     Lisp_Object dst_object, int encodep, int nocopy, int norecord)
 {
   struct coding_system coding;
-  EMACS_INT chars, bytes;
+  ptrdiff_t chars, bytes;
 
   CHECK_STRING (string);
   if (NILP (coding_system))
@@ -9032,7 +9002,7 @@ not fully specified.)  */)
   (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer)
 {
   return code_convert_string (string, coding_system, buffer,
-                             1, ! NILP (nocopy), 1);
+                             1, ! NILP (nocopy), 0);
 }
 
 \f
@@ -9043,14 +9013,15 @@ Return the corresponding character.  */)
 {
   Lisp_Object spec, attrs, val;
   struct charset *charset_roman, *charset_kanji, *charset_kana, *charset;
+  EMACS_INT ch;
   int c;
 
   CHECK_NATNUM (code);
-  c = XFASTINT (code);
+  ch = XFASTINT (code);
   CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (c)
+  if (ASCII_BYTE_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -9059,26 +9030,31 @@ Return the corresponding character.  */)
   charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val)));
 
-  if (c <= 0x7F)
-    charset = charset_roman;
-  else if (c >= 0xA0 && c < 0xDF)
+  if (ch <= 0x7F)
+    {
+      c = ch;
+      charset = charset_roman;
+    }
+  else if (ch >= 0xA0 && ch < 0xDF)
     {
+      c = ch - 0x80;
       charset = charset_kana;
-      c -= 0x80;
     }
   else
     {
-      int c1 = c >> 8, c2 = c & 0xFF;
+      EMACS_INT c1 = ch >> 8;
+      int c2 = ch & 0xFF;
 
       if (c1 < 0x81 || (c1 > 0x9F && c1 < 0xE0) || c1 > 0xEF
          || c2 < 0x40 || c2 == 0x7F || c2 > 0xFC)
-       error ("Invalid code: %d", code);
+       error ("Invalid code: %"pI"d", ch);
+      c = ch;
       SJIS_TO_JIS (c);
       charset = charset_kanji;
     }
   c = DECODE_CHAR (charset, c);
   if (c < 0)
-    error ("Invalid code: %d", code);
+    error ("Invalid code: %"pI"d", ch);
   return make_number (c);
 }
 
@@ -9105,7 +9081,7 @@ Return the corresponding code in SJIS.  */)
   charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   charset = char_charset (c, charset_list, &code);
   if (code == CHARSET_INVALID_CODE (charset))
-    error ("Can't encode by shift_jis encoding: %d", c);
+    error ("Can't encode by shift_jis encoding: %c", c);
   JIS_TO_SJIS (code);
 
   return make_number (code);
@@ -9118,14 +9094,15 @@ Return the corresponding character.  */)
 {
   Lisp_Object spec, attrs, val;
   struct charset *charset_roman, *charset_big5, *charset;
+  EMACS_INT ch;
   int c;
 
   CHECK_NATNUM (code);
-  c = XFASTINT (code);
+  ch = XFASTINT (code);
   CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (c)
+  if (ASCII_BYTE_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -9133,19 +9110,24 @@ Return the corresponding character.  */)
   charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);
   charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val)));
 
-  if (c <= 0x7F)
-    charset = charset_roman;
+  if (ch <= 0x7F)
+    {
+      c = ch;
+      charset = charset_roman;
+    }
   else
     {
-      int b1 = c >> 8, b2 = c & 0x7F;
+      EMACS_INT b1 = ch >> 8;
+      int b2 = ch & 0x7F;
       if (b1 < 0xA1 || b1 > 0xFE
          || b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE)
-       error ("Invalid code: %d", code);
+       error ("Invalid code: %"pI"d", ch);
+      c = ch;
       charset = charset_big5;
     }
-  c = DECODE_CHAR (charset, (unsigned )c);
+  c = DECODE_CHAR (charset, c);
   if (c < 0)
-    error ("Invalid code: %d", code);
+    error ("Invalid code: %"pI"d", ch);
   return make_number (c);
 }
 
@@ -9170,7 +9152,7 @@ Return the corresponding character code in Big5.  */)
   charset_list = CODING_ATTR_CHARSET_LIST (attrs);
   charset = char_charset (c, charset_list, &code);
   if (code == CHARSET_INVALID_CODE (charset))
-    error ("Can't encode by Big5 encoding: %d", c);
+    error ("Can't encode by Big5 encoding: %c", c);
 
   return make_number (code);
 }
@@ -9298,7 +9280,7 @@ function to call for FILENAME, that function should examine the
 contents of BUFFER instead of reading the file.
 
 usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object operation, target_idx, target, val;
   register Lisp_Object chain;
@@ -9307,17 +9289,18 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)
     error ("Too few arguments");
   operation = args[0];
   if (!SYMBOLP (operation)
-      || !INTEGERP (target_idx = Fget (operation, Qtarget_idx)))
+      || (target_idx = Fget (operation, Qtarget_idx), !NATNUMP (target_idx)))
     error ("Invalid first argument");
-  if (nargs < 1 + XINT (target_idx))
-    error ("Too few arguments for operation: %s",
+  if (nargs < 1 + XFASTINT (target_idx))
+    error ("Too few arguments for operation `%s'",
           SDATA (SYMBOL_NAME (operation)));
-  target = args[XINT (target_idx) + 1];
+  target = args[XFASTINT (target_idx) + 1];
   if (!(STRINGP (target)
        || (EQ (operation, Qinsert_file_contents) && CONSP (target)
            && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
        || (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
-    error ("Invalid %dth argument", XINT (target_idx) + 1);
+    error ("Invalid argument %"pI"d of operation `%s'",
+          XFASTINT (target_idx) + 1, SDATA (SYMBOL_NAME (operation)));
   if (CONSP (target))
     target = XCAR (target);
 
@@ -9374,9 +9357,9 @@ If multiple coding systems belong to the same category,
 all but the first one are ignored.
 
 usage: (set-coding-system-priority &rest coding-systems)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
-  int i, j;
+  ptrdiff_t i, j;
   int changed[coding_category_max];
   enum coding_category priorities[coding_category_max];
 
@@ -9419,7 +9402,7 @@ usage: (set-coding-system-priority &rest coding-systems)  */)
 
   /* Update `coding-category-list'.  */
   Vcoding_category_list = Qnil;
-  for (i = coding_category_max - 1; i >= 0; i--)
+  for (i = coding_category_max; i-- > 0; )
     Vcoding_category_list
       = Fcons (AREF (Vcoding_category_table, priorities[i]),
               Vcoding_category_list);
@@ -9461,7 +9444,7 @@ static Lisp_Object
 make_subsidiaries (Lisp_Object base)
 {
   Lisp_Object subsidiaries;
-  int base_name_len = SBYTES (SYMBOL_NAME (base));
+  ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base));
   char *buf = (char *) alloca (base_name_len + 6);
   int i;
 
@@ -9469,7 +9452,7 @@ make_subsidiaries (Lisp_Object base)
   subsidiaries = Fmake_vector (make_number (3), Qnil);
   for (i = 0; i < 3; i++)
     {
-      memcpy (buf + base_name_len, suffixes[i], strlen (suffixes[i]) + 1);
+      strcpy (buf + base_name_len, suffixes[i]);
       ASET (subsidiaries, i, intern (buf));
     }
   return subsidiaries;
@@ -9480,7 +9463,7 @@ DEFUN ("define-coding-system-internal", Fdefine_coding_system_internal,
        Sdefine_coding_system_internal, coding_arg_max, MANY, 0,
        doc: /* For internal use only.
 usage: (define-coding-system-internal ...)  */)
-  (int nargs, Lisp_Object *args)
+  (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object name;
   Lisp_Object spec_vec;                /* [ ATTRS ALIASE EOL_TYPE ] */
@@ -9527,8 +9510,12 @@ usage: (define-coding-system-internal ...)  */)
          charset_list = Vemacs_mule_charset_list;
        }
       for (tail = charset_list; CONSP (tail); tail = XCDR (tail))
-       if (max_charset_id < XFASTINT (XCAR (tail)))
-         max_charset_id = XFASTINT (XCAR (tail));
+       {
+         if (! RANGED_INTEGERP (0, XCAR (tail), INT_MAX - 1))
+           error ("Invalid charset-list");
+         if (max_charset_id < XFASTINT (XCAR (tail)))
+           max_charset_id = XFASTINT (XCAR (tail));
+       }
     }
   else
     {
@@ -9688,23 +9675,23 @@ usage: (define-coding-system-internal ...)  */)
          val = Fcar (tail);
          if (INTEGERP (val))
            {
-             from = to = XINT (val);
-             if (from < 0 || from > 255)
+             if (! (0 <= XINT (val) && XINT (val) <= 255))
                args_out_of_range_3 (val, make_number (0), make_number (255));
+             from = to = XINT (val);
            }
          else
            {
              CHECK_CONS (val);
              CHECK_NATNUM_CAR (val);
-             CHECK_NATNUM_CDR (val);
-             from = XINT (XCAR (val));
-             if (from > 255)
+             CHECK_NUMBER_CDR (val);
+             if (XINT (XCAR (val)) > 255)
                args_out_of_range_3 (XCAR (val),
                                     make_number (0), make_number (255));
-             to = XINT (XCDR (val));
-             if (to < from || to > 255)
+             from = XINT (XCAR (val));
+             if (! (from <= XINT (XCDR (val)) && XINT (XCDR (val)) <= 255))
                args_out_of_range_3 (XCDR (val),
                                     XCAR (val), make_number (255));
+             to = XINT (XCDR (val));
            }
          for (i = from; i <= to; i++)
            SSET (valids, i, 1);
@@ -9793,15 +9780,16 @@ usage: (define-coding-system-internal ...)  */)
          CHECK_CHARSET_GET_ID (tmp1, id);
          CHECK_NATNUM_CDR (val);
          if (XINT (XCDR (val)) >= 4)
-           error ("Invalid graphic register number: %d", XINT (XCDR (val)));
+           error ("Invalid graphic register number: %"pI"d", XINT (XCDR (val)));
          XSETCAR (val, make_number (id));
        }
 
       flags = args[coding_arg_iso2022_flags];
       CHECK_NATNUM (flags);
-      i = XINT (flags);
+      i = XINT (flags) & INT_MAX;
       if (EQ (args[coding_arg_charset_list], Qiso_2022))
-       flags = make_number (i | CODING_ISO_FLAG_FULL_SUPPORT);
+       i |= CODING_ISO_FLAG_FULL_SUPPORT;
+      flags = make_number (i);
 
       ASET (attrs, coding_attr_iso_initial, initial);
       ASET (attrs, coding_attr_iso_usage, reg_usage);