changeset 2829:714b354cef67

[xemacs-hg @ 2005-06-26 18:42:21 by aidan] Prevent Mule-CCL crashing XEmacs on an invalid charset id.
author aidan
date Sun, 26 Jun 2005 18:42:23 +0000
parents a25c824ed558
children d7505a1267a4
files src/ChangeLog src/mule-ccl.c
diffstat 2 files changed, 41 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun Jun 26 18:05:05 2005 +0000
+++ b/src/ChangeLog	Sun Jun 26 18:42:23 2005 +0000
@@ -1,3 +1,9 @@
+2005-06-26  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* mule-ccl.c (POSSIBLE_LEADING_BYTE_P): Add.
+	* mule-ccl.c: Check that a character set exists before using it
+	to create a character. 
+	
 2005-06-26  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* cmds.c (Fself_insert_command):
--- a/src/mule-ccl.c	Sun Jun 26 18:05:05 2005 +0000
+++ b/src/mule-ccl.c	Sun Jun 26 18:42:23 2005 +0000
@@ -826,6 +826,9 @@
       }							\
   } while (0)
 
+#define POSSIBLE_LEADING_BYTE_P(lb) \
+  ((leading_byte > MIN_LEADING_BYTE) && \
+   (leading_byte - MIN_LEADING_BYTE) < NUM_LEADING_BYTES)
 
 /* Set C to the character code made from CHARSET and CODE.  This is
    like make_ichar but check the validity of CHARSET and CODE.  If they
@@ -1295,6 +1298,16 @@
 		    reg[rrr] = i;
 		    reg[RRR] = LEADING_BYTE_ASCII;
 		  }
+		/* Previously, these next two elses were reversed in order,
+		   which should have worked fine, but is more fragile than
+		   this order. */
+		else if (LEADING_BYTE_CONTROL_1 == i)
+		  {
+		    if (src >= src_end)
+		      goto ccl_read_multibyte_character_suspend;
+		    reg[RRR] = i;
+		    reg[rrr] = (*src++ - 0xA0);
+		  }
 		else if (i <= MAX_LEADING_BYTE_OFFICIAL_1)
 		  {
 		    if (src >= src_end)
@@ -1302,13 +1315,6 @@
 		    reg[RRR] = i;
 		    reg[rrr] = (*src++ & 0x7F);
 		  }
-		else if (LEADING_BYTE_CONTROL_1 == i)
-		  {
-		    if (src >= src_end)
-		      goto ccl_read_multibyte_character_suspend;
-		    reg[RRR] = i;
-		    reg[rrr] = (*src++ - 0xA0);
-		  }
 		else if (i <= MAX_LEADING_BYTE_OFFICIAL_2)
 		  {
 		    if ((src + 1) >= src_end)
@@ -1356,15 +1362,29 @@
 
 	    case CCL_WriteMultibyteChar2:
 	      i = reg[RRR]; /* charset */
-	      if (i == LEADING_BYTE_ASCII || i == LEADING_BYTE_CONTROL_1)
+	      if (i == LEADING_BYTE_ASCII) 
 		i = reg[rrr] & 0xFF;
-	      else if (XCHARSET_DIMENSION (charset_by_leading_byte (i)) == 1)
-		i = (((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7)
-		     | (reg[rrr] & 0x7F));
-	      else if (i < MAX_LEADING_BYTE_OFFICIAL_2)
-		i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) | reg[rrr];
-	      else
-		i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr];
+	      else if (LEADING_BYTE_CONTROL_1 == i)
+		i = ((reg[rrr] & 0xFF) - 0xA0);
+	      else if (POSSIBLE_LEADING_BYTE_P(i) &&
+		       !NILP(charset_by_leading_byte(i))
+		{
+		  if (XCHARSET_DIMENSION (charset_by_leading_byte (i)) == 1)
+		    i = (((i - FIELD2_TO_OFFICIAL_LEADING_BYTE) << 7)
+			 | (reg[rrr] & 0x7F));
+		  else if (i < MAX_LEADING_BYTE_OFFICIAL_2)
+		    i = ((i - FIELD1_TO_OFFICIAL_LEADING_BYTE) << 14) 
+		      | reg[rrr];
+		  else
+		    i = ((i - FIELD1_TO_PRIVATE_LEADING_BYTE) << 14) | reg[rrr];
+		}
+	      else 
+		{
+		  /* No charset we know about; use U+3012 GETA MARK */
+		  i = make_ichar
+		    (charset_by_leading_byte(LEADING_BYTE_JAPANESE_JISX0208),
+		     34, 46);
+		}
 
 	      CCL_WRITE_CHAR (i);
 
@@ -1423,7 +1443,6 @@
 
 		for (;i < j;i++)
 		  {
-
 		    size = XVECTOR (Vcode_conversion_map_vector)->size;
 		    point = XINT (ccl_prog[ic++]);
 		    if (point >= size) continue;