aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-22 23:50:03 -0700
committerPaul Eggert2011-05-22 23:50:03 -0700
commit305696990bd24e602e83444651fbb1ed8819fe14 (patch)
tree47ae4fc861057181e147caea99fa47df80eafe03 /src
parentc11285dca1ee2896b487fe03408a4c7c356b6d5b (diff)
downloademacs-305696990bd24e602e83444651fbb1ed8819fe14.tar.gz
emacs-305696990bd24e602e83444651fbb1ed8819fe14.zip
ccl: add integer overflow checks
* ccl.c (CCL_CODE_MAX, GET_CCL_RANGE, GET_CCL_CODE, GET_CCL_INT): (IN_INT_RANGE): New macros. (ccl_driver): Use them to check for integer overflow when decoding a CCL program. Many of the new checks are whether XINT (x) fits in int; it doesn't always, on 64-bit hosts. The new version doesn't catch all possible integer overflows, but it's an improvement.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/ccl.c231
2 files changed, 140 insertions, 100 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index f6a6c21c25c..29595113f1b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
12011-05-23 Paul Eggert <eggert@cs.ucla.edu> 12011-05-23 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 ccl: add integer overflow checks
4 * ccl.c (CCL_CODE_MAX, GET_CCL_RANGE, GET_CCL_CODE, GET_CCL_INT):
5 (IN_INT_RANGE): New macros.
6 (ccl_driver): Use them to check for integer overflow when
7 decoding a CCL program. Many of the new checks are whether XINT (x)
8 fits in int; it doesn't always, on 64-bit hosts. The new version
9 doesn't catch all possible integer overflows, but it's an
10 improvement.
11
3 * alloc.c (make_event_array): Use XINT, not XUINT. 12 * alloc.c (make_event_array): Use XINT, not XUINT.
4 There's no need for unsigned here. 13 There's no need for unsigned here.
5 14
diff --git a/src/ccl.c b/src/ccl.c
index 83afd7bc800..d66a61b713d 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -98,6 +98,8 @@ static Lisp_Object Vccl_program_table;
98 and `rrr' are CCL register number, `XXXXX' is one of the following 98 and `rrr' are CCL register number, `XXXXX' is one of the following
99 CCL commands. */ 99 CCL commands. */
100 100
101#define CCL_CODE_MAX ((1 << (28 - 1)) - 1)
102
101/* CCL commands 103/* CCL commands
102 104
103 Each comment fields shows one or more lines for command syntax and 105 Each comment fields shows one or more lines for command syntax and
@@ -742,6 +744,24 @@ while(0)
742 744
743#endif 745#endif
744 746
747#define GET_CCL_RANGE(var, ccl_prog, ic, lo, hi) \
748 do \
749 { \
750 EMACS_INT prog_word = XINT ((ccl_prog)[ic]); \
751 if (! ((lo) <= prog_word && prog_word <= (hi))) \
752 CCL_INVALID_CMD; \
753 (var) = prog_word; \
754 } \
755 while (0)
756
757#define GET_CCL_CODE(code, ccl_prog, ic) \
758 GET_CCL_RANGE (code, ccl_prog, ic, 0, CCL_CODE_MAX)
759
760#define GET_CCL_INT(var, ccl_prog, ic) \
761 GET_CCL_RANGE (var, ccl_prog, ic, INT_MIN, INT_MAX)
762
763#define IN_INT_RANGE(val) (INT_MIN <= (val) && (val) <= INT_MAX)
764
745/* Encode one character CH to multibyte form and write to the current 765/* Encode one character CH to multibyte form and write to the current
746 output buffer. If CH is less than 256, CH is written as is. */ 766 output buffer. If CH is less than 256, CH is written as is. */
747#define CCL_WRITE_CHAR(ch) \ 767#define CCL_WRITE_CHAR(ch) \
@@ -899,7 +919,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
899 } 919 }
900 920
901 this_ic = ic; 921 this_ic = ic;
902 code = XINT (ccl_prog[ic]); ic++; 922 GET_CCL_CODE (code, ccl_prog, ic++);
903 field1 = code >> 8; 923 field1 = code >> 8;
904 field2 = (code & 0xFF) >> 5; 924 field2 = (code & 0xFF) >> 5;
905 925
@@ -920,15 +940,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
920 break; 940 break;
921 941
922 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ 942 case CCL_SetConst: /* 00000000000000000000rrrXXXXX */
923 reg[rrr] = XINT (ccl_prog[ic]); 943 GET_CCL_INT (reg[rrr], ccl_prog, ic++);
924 ic++;
925 break; 944 break;
926 945
927 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ 946 case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */
928 i = reg[RRR]; 947 i = reg[RRR];
929 j = field1 >> 3; 948 j = field1 >> 3;
930 if ((unsigned int) i < j) 949 if ((unsigned int) i < j)
931 reg[rrr] = XINT (ccl_prog[ic + i]); 950 GET_CCL_INT (reg[rrr], ccl_prog, ic + i);
932 ic += j; 951 ic += j;
933 break; 952 break;
934 953
@@ -956,13 +975,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
956 break; 975 break;
957 976
958 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ 977 case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */
959 i = XINT (ccl_prog[ic]); 978 GET_CCL_INT (i, ccl_prog, ic);
960 CCL_WRITE_CHAR (i); 979 CCL_WRITE_CHAR (i);
961 ic += ADDR; 980 ic += ADDR;
962 break; 981 break;
963 982
964 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 983 case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
965 i = XINT (ccl_prog[ic]); 984 GET_CCL_INT (i, ccl_prog, ic);
966 CCL_WRITE_CHAR (i); 985 CCL_WRITE_CHAR (i);
967 ic++; 986 ic++;
968 CCL_READ_CHAR (reg[rrr]); 987 CCL_READ_CHAR (reg[rrr]);
@@ -970,18 +989,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
970 break; 989 break;
971 990
972 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ 991 case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */
973 j = XINT (ccl_prog[ic]); 992 GET_CCL_INT (j, ccl_prog, ic++);
974 ic++;
975 CCL_WRITE_STRING (j); 993 CCL_WRITE_STRING (j);
976 ic += ADDR - 1; 994 ic += ADDR - 1;
977 break; 995 break;
978 996
979 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ 997 case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
980 i = reg[rrr]; 998 i = reg[rrr];
981 j = XINT (ccl_prog[ic]); 999 GET_CCL_INT (j, ccl_prog, ic);
982 if ((unsigned int) i < j) 1000 if ((unsigned int) i < j)
983 { 1001 {
984 i = XINT (ccl_prog[ic + 1 + i]); 1002 GET_CCL_INT (i, ccl_prog, ic + 1 + i);
985 CCL_WRITE_CHAR (i); 1003 CCL_WRITE_CHAR (i);
986 } 1004 }
987 ic += j + 2; 1005 ic += j + 2;
@@ -998,10 +1016,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
998 CCL_READ_CHAR (reg[rrr]); 1016 CCL_READ_CHAR (reg[rrr]);
999 /* fall through ... */ 1017 /* fall through ... */
1000 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ 1018 case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
1001 if ((unsigned int) reg[rrr] < field1) 1019 {
1002 ic += XINT (ccl_prog[ic + reg[rrr]]); 1020 int incr;
1003 else 1021 GET_CCL_INT (incr, ccl_prog,
1004 ic += XINT (ccl_prog[ic + field1]); 1022 ic + ((unsigned int) reg[rrr] < field1
1023 ? reg[rrr]
1024 : field1));
1025 ic += incr;
1026 }
1005 break; 1027 break;
1006 1028
1007 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ 1029 case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */
@@ -1009,7 +1031,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1009 { 1031 {
1010 CCL_READ_CHAR (reg[rrr]); 1032 CCL_READ_CHAR (reg[rrr]);
1011 if (!field1) break; 1033 if (!field1) break;
1012 code = XINT (ccl_prog[ic]); ic++; 1034 GET_CCL_CODE (code, ccl_prog, ic++);
1013 field1 = code >> 8; 1035 field1 = code >> 8;
1014 field2 = (code & 0xFF) >> 5; 1036 field2 = (code & 0xFF) >> 5;
1015 } 1037 }
@@ -1018,7 +1040,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1018 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ 1040 case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */
1019 rrr = 7; 1041 rrr = 7;
1020 i = reg[RRR]; 1042 i = reg[RRR];
1021 j = XINT (ccl_prog[ic]); 1043 GET_CCL_INT (j, ccl_prog, ic);
1022 op = field1 >> 6; 1044 op = field1 >> 6;
1023 jump_address = ic + 1; 1045 jump_address = ic + 1;
1024 goto ccl_set_expr; 1046 goto ccl_set_expr;
@@ -1029,7 +1051,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1029 i = reg[rrr]; 1051 i = reg[rrr];
1030 CCL_WRITE_CHAR (i); 1052 CCL_WRITE_CHAR (i);
1031 if (!field1) break; 1053 if (!field1) break;
1032 code = XINT (ccl_prog[ic]); ic++; 1054 GET_CCL_CODE (code, ccl_prog, ic++);
1033 field1 = code >> 8; 1055 field1 = code >> 8;
1034 field2 = (code & 0xFF) >> 5; 1056 field2 = (code & 0xFF) >> 5;
1035 } 1057 }
@@ -1051,10 +1073,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1051 /* If FFF is nonzero, the CCL program ID is in the 1073 /* If FFF is nonzero, the CCL program ID is in the
1052 following code. */ 1074 following code. */
1053 if (rrr) 1075 if (rrr)
1054 { 1076 GET_CCL_INT (prog_id, ccl_prog, ic++);
1055 prog_id = XINT (ccl_prog[ic]);
1056 ic++;
1057 }
1058 else 1077 else
1059 prog_id = field1; 1078 prog_id = field1;
1060 1079
@@ -1097,7 +1116,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1097 i = reg[rrr]; 1116 i = reg[rrr];
1098 if ((unsigned int) i < field1) 1117 if ((unsigned int) i < field1)
1099 { 1118 {
1100 j = XINT (ccl_prog[ic + i]); 1119 GET_CCL_INT (j, ccl_prog, ic + i);
1101 CCL_WRITE_CHAR (j); 1120 CCL_WRITE_CHAR (j);
1102 } 1121 }
1103 ic += field1; 1122 ic += field1;
@@ -1122,8 +1141,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1122 CCL_SUCCESS; 1141 CCL_SUCCESS;
1123 1142
1124 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ 1143 case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */
1125 i = XINT (ccl_prog[ic]); 1144 GET_CCL_INT (i, ccl_prog, ic++);
1126 ic++;
1127 op = field1 >> 6; 1145 op = field1 >> 6;
1128 goto ccl_expr_self; 1146 goto ccl_expr_self;
1129 1147
@@ -1159,9 +1177,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1159 1177
1160 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ 1178 case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */
1161 i = reg[RRR]; 1179 i = reg[RRR];
1162 j = XINT (ccl_prog[ic]); 1180 GET_CCL_INT (j, ccl_prog, ic++);
1163 op = field1 >> 6; 1181 op = field1 >> 6;
1164 jump_address = ++ic; 1182 jump_address = ic;
1165 goto ccl_set_expr; 1183 goto ccl_set_expr;
1166 1184
1167 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ 1185 case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */
@@ -1175,10 +1193,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1175 CCL_READ_CHAR (reg[rrr]); 1193 CCL_READ_CHAR (reg[rrr]);
1176 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ 1194 case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */
1177 i = reg[rrr]; 1195 i = reg[rrr];
1178 op = XINT (ccl_prog[ic]); 1196 jump_address = ic + ADDR;
1179 jump_address = ic++ + ADDR; 1197 GET_CCL_INT (op, ccl_prog, ic++);
1180 j = XINT (ccl_prog[ic]); 1198 GET_CCL_INT (j, ccl_prog, ic++);
1181 ic++;
1182 rrr = 7; 1199 rrr = 7;
1183 goto ccl_set_expr; 1200 goto ccl_set_expr;
1184 1201
@@ -1186,10 +1203,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1186 CCL_READ_CHAR (reg[rrr]); 1203 CCL_READ_CHAR (reg[rrr]);
1187 case CCL_JumpCondExprReg: 1204 case CCL_JumpCondExprReg:
1188 i = reg[rrr]; 1205 i = reg[rrr];
1189 op = XINT (ccl_prog[ic]); 1206 jump_address = ic + ADDR;
1190 jump_address = ic++ + ADDR; 1207 GET_CCL_INT (op, ccl_prog, ic++);
1191 j = reg[XINT (ccl_prog[ic])]; 1208 GET_CCL_RANGE (j, ccl_prog, ic++, 0, 7);
1192 ic++; 1209 j = reg[j];
1193 rrr = 7; 1210 rrr = 7;
1194 1211
1195 ccl_set_expr: 1212 ccl_set_expr:
@@ -1267,18 +1284,27 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1267 break; 1284 break;
1268 1285
1269 case CCL_TranslateCharacterConstTbl: 1286 case CCL_TranslateCharacterConstTbl:
1270 op = XINT (ccl_prog[ic]); /* table */ 1287 {
1271 ic++; 1288 EMACS_INT eop;
1272 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); 1289 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1273 op = translate_char (GET_TRANSLATION_TABLE (op), i); 1290 (VECTORP (Vtranslation_table_vector)
1274 CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); 1291 ? ASIZE (Vtranslation_table_vector)
1292 : -1));
1293 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1294 op = translate_char (GET_TRANSLATION_TABLE (eop), i);
1295 CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
1296 }
1275 break; 1297 break;
1276 1298
1277 case CCL_LookupIntConstTbl: 1299 case CCL_LookupIntConstTbl:
1278 op = XINT (ccl_prog[ic]); /* table */
1279 ic++;
1280 { 1300 {
1281 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); 1301 EMACS_INT eop;
1302 struct Lisp_Hash_Table *h;
1303 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1304 (VECTORP (Vtranslation_hash_table_vector)
1305 ? ASIZE (Vtranslation_hash_table_vector)
1306 : -1));
1307 h = GET_HASH_TABLE (eop);
1282 1308
1283 op = hash_lookup (h, make_number (reg[RRR]), NULL); 1309 op = hash_lookup (h, make_number (reg[RRR]), NULL);
1284 if (op >= 0) 1310 if (op >= 0)
@@ -1297,18 +1323,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1297 break; 1323 break;
1298 1324
1299 case CCL_LookupCharConstTbl: 1325 case CCL_LookupCharConstTbl:
1300 op = XINT (ccl_prog[ic]); /* table */
1301 ic++;
1302 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1303 { 1326 {
1304 struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); 1327 EMACS_INT eop;
1328 struct Lisp_Hash_Table *h;
1329 GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
1330 (VECTORP (Vtranslation_hash_table_vector)
1331 ? ASIZE (Vtranslation_hash_table_vector)
1332 : -1));
1333 i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
1334 h = GET_HASH_TABLE (eop);
1305 1335
1306 op = hash_lookup (h, make_number (i), NULL); 1336 op = hash_lookup (h, make_number (i), NULL);
1307 if (op >= 0) 1337 if (op >= 0)
1308 { 1338 {
1309 Lisp_Object opl; 1339 Lisp_Object opl;
1310 opl = HASH_VALUE (h, op); 1340 opl = HASH_VALUE (h, op);
1311 if (!INTEGERP (opl)) 1341 if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl))))
1312 CCL_INVALID_CMD; 1342 CCL_INVALID_CMD;
1313 reg[RRR] = XINT (opl); 1343 reg[RRR] = XINT (opl);
1314 reg[7] = 1; /* r7 true for success */ 1344 reg[7] = 1; /* r7 true for success */
@@ -1321,9 +1351,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1321 case CCL_IterateMultipleMap: 1351 case CCL_IterateMultipleMap:
1322 { 1352 {
1323 Lisp_Object map, content, attrib, value; 1353 Lisp_Object map, content, attrib, value;
1324 int point, size, fin_ic; 1354 EMACS_INT point, size;
1355 int fin_ic;
1325 1356
1326 j = XINT (ccl_prog[ic++]); /* number of maps. */ 1357 GET_CCL_INT (j, ccl_prog, ic++); /* number of maps. */
1327 fin_ic = ic + j; 1358 fin_ic = ic + j;
1328 op = reg[rrr]; 1359 op = reg[rrr];
1329 if ((j > reg[RRR]) && (j >= 0)) 1360 if ((j > reg[RRR]) && (j >= 0))
@@ -1343,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1343 1374
1344 size = ASIZE (Vcode_conversion_map_vector); 1375 size = ASIZE (Vcode_conversion_map_vector);
1345 point = XINT (ccl_prog[ic++]); 1376 point = XINT (ccl_prog[ic++]);
1346 if (point >= size) continue; 1377 if (! (0 <= point && point < size)) continue;
1347 map = AREF (Vcode_conversion_map_vector, point); 1378 map = AREF (Vcode_conversion_map_vector, point);
1348 1379
1349 /* Check map validity. */ 1380 /* Check map validity. */
@@ -1358,18 +1389,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1358 /* check map type, 1389 /* check map type,
1359 [STARTPOINT VAL1 VAL2 ...] or 1390 [STARTPOINT VAL1 VAL2 ...] or
1360 [t ELEMENT STARTPOINT ENDPOINT] */ 1391 [t ELEMENT STARTPOINT ENDPOINT] */
1361 if (NUMBERP (content)) 1392 if (INTEGERP (content))
1362 { 1393 {
1363 point = XUINT (content); 1394 point = XINT (content);
1364 point = op - point + 1; 1395 if (!(point <= op && op - point + 1 < size)) continue;
1365 if (!((point >= 1) && (point < size))) continue; 1396 content = AREF (map, op - point + 1);
1366 content = AREF (map, point);
1367 } 1397 }
1368 else if (EQ (content, Qt)) 1398 else if (EQ (content, Qt))
1369 { 1399 {
1370 if (size != 4) continue; 1400 if (size != 4) continue;
1371 if ((op >= XUINT (AREF (map, 2))) 1401 if (INTEGERP (AREF (map, 2))
1372 && (op < XUINT (AREF (map, 3)))) 1402 && XINT (AREF (map, 2)) <= op
1403 && INTEGERP (AREF (map, 3))
1404 && op < XINT (AREF (map, 3)))
1373 content = AREF (map, 1); 1405 content = AREF (map, 1);
1374 else 1406 else
1375 continue; 1407 continue;
@@ -1379,7 +1411,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1379 1411
1380 if (NILP (content)) 1412 if (NILP (content))
1381 continue; 1413 continue;
1382 else if (NUMBERP (content)) 1414 else if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
1383 { 1415 {
1384 reg[RRR] = i; 1416 reg[RRR] = i;
1385 reg[rrr] = XINT(content); 1417 reg[rrr] = XINT(content);
@@ -1394,10 +1426,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1394 { 1426 {
1395 attrib = XCAR (content); 1427 attrib = XCAR (content);
1396 value = XCDR (content); 1428 value = XCDR (content);
1397 if (!NUMBERP (attrib) || !NUMBERP (value)) 1429 if (! (INTEGERP (attrib) && INTEGERP (value)
1430 && IN_INT_RANGE (XINT (value))))
1398 continue; 1431 continue;
1399 reg[RRR] = i; 1432 reg[RRR] = i;
1400 reg[rrr] = XUINT (value); 1433 reg[rrr] = XINT (value);
1401 break; 1434 break;
1402 } 1435 }
1403 else if (SYMBOLP (content)) 1436 else if (SYMBOLP (content))
@@ -1432,8 +1465,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1432 mapping_stack_pointer = mapping_stack; 1465 mapping_stack_pointer = mapping_stack;
1433 stack_idx_of_map_multiple = 0; 1466 stack_idx_of_map_multiple = 0;
1434 1467
1435 map_set_rest_length = 1468 /* Get number of maps and separators. */
1436 XINT (ccl_prog[ic++]); /* number of maps and separators. */ 1469 GET_CCL_INT (map_set_rest_length, ccl_prog, ic++);
1470
1437 fin_ic = ic + map_set_rest_length; 1471 fin_ic = ic + map_set_rest_length;
1438 op = reg[rrr]; 1472 op = reg[rrr];
1439 1473
@@ -1501,7 +1535,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1501 do { 1535 do {
1502 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) 1536 for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--)
1503 { 1537 {
1504 point = XINT(ccl_prog[ic]); 1538 GET_CCL_INT (point, ccl_prog, ic);
1505 if (point < 0) 1539 if (point < 0)
1506 { 1540 {
1507 /* +1 is for including separator. */ 1541 /* +1 is for including separator. */
@@ -1531,18 +1565,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1531 /* check map type, 1565 /* check map type,
1532 [STARTPOINT VAL1 VAL2 ...] or 1566 [STARTPOINT VAL1 VAL2 ...] or
1533 [t ELEMENT STARTPOINT ENDPOINT] */ 1567 [t ELEMENT STARTPOINT ENDPOINT] */
1534 if (NUMBERP (content)) 1568 if (INTEGERP (content))
1535 { 1569 {
1536 point = XUINT (content); 1570 point = XINT (content);
1537 point = op - point + 1; 1571 if (!(point <= op && op - point + 1 < size)) continue;
1538 if (!((point >= 1) && (point < size))) continue; 1572 content = AREF (map, op - point + 1);
1539 content = AREF (map, point);
1540 } 1573 }
1541 else if (EQ (content, Qt)) 1574 else if (EQ (content, Qt))
1542 { 1575 {
1543 if (size != 4) continue; 1576 if (size != 4) continue;
1544 if ((op >= XUINT (AREF (map, 2))) && 1577 if (INTEGERP (AREF (map, 2))
1545 (op < XUINT (AREF (map, 3)))) 1578 && XINT (AREF (map, 2)) <= op
1579 && INTEGERP (AREF (map, 3))
1580 && op < XINT (AREF (map, 3)))
1546 content = AREF (map, 1); 1581 content = AREF (map, 1);
1547 else 1582 else
1548 continue; 1583 continue;
@@ -1554,7 +1589,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1554 continue; 1589 continue;
1555 1590
1556 reg[RRR] = i; 1591 reg[RRR] = i;
1557 if (NUMBERP (content)) 1592 if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
1558 { 1593 {
1559 op = XINT (content); 1594 op = XINT (content);
1560 i += map_set_rest_length - 1; 1595 i += map_set_rest_length - 1;
@@ -1566,9 +1601,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1566 { 1601 {
1567 attrib = XCAR (content); 1602 attrib = XCAR (content);
1568 value = XCDR (content); 1603 value = XCDR (content);
1569 if (!NUMBERP (attrib) || !NUMBERP (value)) 1604 if (! (INTEGERP (attrib) && INTEGERP (value)
1605 && IN_INT_RANGE (XINT (value))))
1570 continue; 1606 continue;
1571 op = XUINT (value); 1607 op = XINT (value);
1572 i += map_set_rest_length - 1; 1608 i += map_set_rest_length - 1;
1573 ic += map_set_rest_length - 1; 1609 ic += map_set_rest_length - 1;
1574 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); 1610 POP_MAPPING_STACK (map_set_rest_length, reg[rrr]);
@@ -1613,7 +1649,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1613 case CCL_MapSingle: 1649 case CCL_MapSingle:
1614 { 1650 {
1615 Lisp_Object map, attrib, value, content; 1651 Lisp_Object map, attrib, value, content;
1616 int size, point; 1652 int point;
1617 j = XINT (ccl_prog[ic++]); /* map_id */ 1653 j = XINT (ccl_prog[ic++]); /* map_id */
1618 op = reg[rrr]; 1654 op = reg[rrr];
1619 if (j >= ASIZE (Vcode_conversion_map_vector)) 1655 if (j >= ASIZE (Vcode_conversion_map_vector))
@@ -1628,41 +1664,36 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
1628 break; 1664 break;
1629 } 1665 }
1630 map = XCDR (map); 1666 map = XCDR (map);
1631 if (!VECTORP (map)) 1667 if (! (VECTORP (map)
1668 && INTEGERP (AREF (map, 0))
1669 && XINT (AREF (map, 0)) <= op
1670 && op - XINT (AREF (map, 0)) + 1 < ASIZE (map)))
1632 { 1671 {
1633 reg[RRR] = -1; 1672 reg[RRR] = -1;
1634 break; 1673 break;
1635 } 1674 }
1636 size = ASIZE (map); 1675 point = XINT (AREF (map, 0));
1637 point = XUINT (AREF (map, 0));
1638 point = op - point + 1; 1676 point = op - point + 1;
1639 reg[RRR] = 0; 1677 reg[RRR] = 0;
1640 if ((size <= 1) || 1678 content = AREF (map, point);
1641 (!((point >= 1) && (point < size)))) 1679 if (NILP (content))
1642 reg[RRR] = -1; 1680 reg[RRR] = -1;
1643 else 1681 else if (INTEGERP (content))
1682 reg[rrr] = XINT (content);
1683 else if (EQ (content, Qt));
1684 else if (CONSP (content))
1644 { 1685 {
1645 reg[RRR] = 0; 1686 attrib = XCAR (content);
1646 content = AREF (map, point); 1687 value = XCDR (content);
1647 if (NILP (content)) 1688 if (!INTEGERP (attrib) || !INTEGERP (value))
1648 reg[RRR] = -1; 1689 continue;
1649 else if (NUMBERP (content)) 1690 reg[rrr] = XINT(value);
1650 reg[rrr] = XINT (content); 1691 break;
1651 else if (EQ (content, Qt));
1652 else if (CONSP (content))
1653 {
1654 attrib = XCAR (content);
1655 value = XCDR (content);
1656 if (!NUMBERP (attrib) || !NUMBERP (value))
1657 continue;
1658 reg[rrr] = XUINT(value);
1659 break;
1660 }
1661 else if (SYMBOLP (content))
1662 CCL_CALL_FOR_MAP_INSTRUCTION (content, ic);
1663 else
1664 reg[RRR] = -1;
1665 } 1692 }
1693 else if (SYMBOLP (content))
1694 CCL_CALL_FOR_MAP_INSTRUCTION (content, ic);
1695 else
1696 reg[RRR] = -1;
1666 } 1697 }
1667 break; 1698 break;
1668 1699