diff options
| author | Paul Eggert | 2011-05-22 23:50:03 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-05-22 23:50:03 -0700 |
| commit | 305696990bd24e602e83444651fbb1ed8819fe14 (patch) | |
| tree | 47ae4fc861057181e147caea99fa47df80eafe03 /src | |
| parent | c11285dca1ee2896b487fe03408a4c7c356b6d5b (diff) | |
| download | emacs-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/ChangeLog | 9 | ||||
| -rw-r--r-- | src/ccl.c | 231 |
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 @@ | |||
| 1 | 2011-05-23 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-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 | ||
| @@ -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 | ||