Commit 30569699 authored by Paul Eggert's avatar Paul Eggert
Browse files

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.
parent c11285dc
2011-05-23 Paul Eggert <eggert@cs.ucla.edu> 2011-05-23 Paul Eggert <eggert@cs.ucla.edu>
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.
* alloc.c (make_event_array): Use XINT, not XUINT. * alloc.c (make_event_array): Use XINT, not XUINT.
There's no need for unsigned here. There's no need for unsigned here.
......
...@@ -98,6 +98,8 @@ static Lisp_Object Vccl_program_table; ...@@ -98,6 +98,8 @@ static Lisp_Object Vccl_program_table;
and `rrr' are CCL register number, `XXXXX' is one of the following and `rrr' are CCL register number, `XXXXX' is one of the following
CCL commands. */ CCL commands. */
#define CCL_CODE_MAX ((1 << (28 - 1)) - 1)
/* CCL commands /* CCL commands
Each comment fields shows one or more lines for command syntax and Each comment fields shows one or more lines for command syntax and
...@@ -742,6 +744,24 @@ while(0) ...@@ -742,6 +744,24 @@ while(0)
#endif #endif
#define GET_CCL_RANGE(var, ccl_prog, ic, lo, hi) \
do \
{ \
EMACS_INT prog_word = XINT ((ccl_prog)[ic]); \
if (! ((lo) <= prog_word && prog_word <= (hi))) \
CCL_INVALID_CMD; \
(var) = prog_word; \
} \
while (0)
#define GET_CCL_CODE(code, ccl_prog, ic) \
GET_CCL_RANGE (code, ccl_prog, ic, 0, CCL_CODE_MAX)
#define GET_CCL_INT(var, ccl_prog, ic) \
GET_CCL_RANGE (var, ccl_prog, ic, INT_MIN, INT_MAX)
#define IN_INT_RANGE(val) (INT_MIN <= (val) && (val) <= INT_MAX)
/* Encode one character CH to multibyte form and write to the current /* Encode one character CH to multibyte form and write to the current
output buffer. If CH is less than 256, CH is written as is. */ output buffer. If CH is less than 256, CH is written as is. */
#define CCL_WRITE_CHAR(ch) \ #define CCL_WRITE_CHAR(ch) \
...@@ -899,7 +919,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -899,7 +919,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
} }
this_ic = ic; this_ic = ic;
code = XINT (ccl_prog[ic]); ic++; GET_CCL_CODE (code, ccl_prog, ic++);
field1 = code >> 8; field1 = code >> 8;
field2 = (code & 0xFF) >> 5; field2 = (code & 0xFF) >> 5;
...@@ -920,15 +940,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -920,15 +940,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
case CCL_SetConst: /* 00000000000000000000rrrXXXXX */ case CCL_SetConst: /* 00000000000000000000rrrXXXXX */
reg[rrr] = XINT (ccl_prog[ic]); GET_CCL_INT (reg[rrr], ccl_prog, ic++);
ic++;
break; break;
case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */ case CCL_SetArray: /* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */
i = reg[RRR]; i = reg[RRR];
j = field1 >> 3; j = field1 >> 3;
if ((unsigned int) i < j) if ((unsigned int) i < j)
reg[rrr] = XINT (ccl_prog[ic + i]); GET_CCL_INT (reg[rrr], ccl_prog, ic + i);
ic += j; ic += j;
break; break;
...@@ -956,13 +975,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -956,13 +975,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */ case CCL_WriteConstJump: /* A--D--D--R--E--S--S-000XXXXX */
i = XINT (ccl_prog[ic]); GET_CCL_INT (i, ccl_prog, ic);
CCL_WRITE_CHAR (i); CCL_WRITE_CHAR (i);
ic += ADDR; ic += ADDR;
break; break;
case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ case CCL_WriteConstReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
i = XINT (ccl_prog[ic]); GET_CCL_INT (i, ccl_prog, ic);
CCL_WRITE_CHAR (i); CCL_WRITE_CHAR (i);
ic++; ic++;
CCL_READ_CHAR (reg[rrr]); CCL_READ_CHAR (reg[rrr]);
...@@ -970,18 +989,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -970,18 +989,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */ case CCL_WriteStringJump: /* A--D--D--R--E--S--S-000XXXXX */
j = XINT (ccl_prog[ic]); GET_CCL_INT (j, ccl_prog, ic++);
ic++;
CCL_WRITE_STRING (j); CCL_WRITE_STRING (j);
ic += ADDR - 1; ic += ADDR - 1;
break; break;
case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */ case CCL_WriteArrayReadJump: /* A--D--D--R--E--S--S-rrrXXXXX */
i = reg[rrr]; i = reg[rrr];
j = XINT (ccl_prog[ic]); GET_CCL_INT (j, ccl_prog, ic);
if ((unsigned int) i < j) if ((unsigned int) i < j)
{ {
i = XINT (ccl_prog[ic + 1 + i]); GET_CCL_INT (i, ccl_prog, ic + 1 + i);
CCL_WRITE_CHAR (i); CCL_WRITE_CHAR (i);
} }
ic += j + 2; ic += j + 2;
...@@ -998,10 +1016,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -998,10 +1016,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR (reg[rrr]); CCL_READ_CHAR (reg[rrr]);
/* fall through ... */ /* fall through ... */
case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */ case CCL_Branch: /* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
if ((unsigned int) reg[rrr] < field1) {
ic += XINT (ccl_prog[ic + reg[rrr]]); int incr;
else GET_CCL_INT (incr, ccl_prog,
ic += XINT (ccl_prog[ic + field1]); ic + ((unsigned int) reg[rrr] < field1
? reg[rrr]
: field1));
ic += incr;
}
break; break;
case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */ case CCL_ReadRegister: /* CCCCCCCCCCCCCCCCCCCCrrXXXXX */
...@@ -1009,7 +1031,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1009,7 +1031,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{ {
CCL_READ_CHAR (reg[rrr]); CCL_READ_CHAR (reg[rrr]);
if (!field1) break; if (!field1) break;
code = XINT (ccl_prog[ic]); ic++; GET_CCL_CODE (code, ccl_prog, ic++);
field1 = code >> 8; field1 = code >> 8;
field2 = (code & 0xFF) >> 5; field2 = (code & 0xFF) >> 5;
} }
...@@ -1018,7 +1040,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1018,7 +1040,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */ case CCL_WriteExprConst: /* 1:00000OPERATION000RRR000XXXXX */
rrr = 7; rrr = 7;
i = reg[RRR]; i = reg[RRR];
j = XINT (ccl_prog[ic]); GET_CCL_INT (j, ccl_prog, ic);
op = field1 >> 6; op = field1 >> 6;
jump_address = ic + 1; jump_address = ic + 1;
goto ccl_set_expr; goto ccl_set_expr;
...@@ -1029,7 +1051,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1029,7 +1051,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
i = reg[rrr]; i = reg[rrr];
CCL_WRITE_CHAR (i); CCL_WRITE_CHAR (i);
if (!field1) break; if (!field1) break;
code = XINT (ccl_prog[ic]); ic++; GET_CCL_CODE (code, ccl_prog, ic++);
field1 = code >> 8; field1 = code >> 8;
field2 = (code & 0xFF) >> 5; field2 = (code & 0xFF) >> 5;
} }
...@@ -1051,10 +1073,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1051,10 +1073,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
/* If FFF is nonzero, the CCL program ID is in the /* If FFF is nonzero, the CCL program ID is in the
following code. */ following code. */
if (rrr) if (rrr)
{ GET_CCL_INT (prog_id, ccl_prog, ic++);
prog_id = XINT (ccl_prog[ic]);
ic++;
}
else else
prog_id = field1; prog_id = field1;
...@@ -1097,7 +1116,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1097,7 +1116,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
i = reg[rrr]; i = reg[rrr];
if ((unsigned int) i < field1) if ((unsigned int) i < field1)
{ {
j = XINT (ccl_prog[ic + i]); GET_CCL_INT (j, ccl_prog, ic + i);
CCL_WRITE_CHAR (j); CCL_WRITE_CHAR (j);
} }
ic += field1; ic += field1;
...@@ -1122,8 +1141,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1122,8 +1141,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_SUCCESS; CCL_SUCCESS;
case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */ case CCL_ExprSelfConst: /* 00000OPERATION000000rrrXXXXX */
i = XINT (ccl_prog[ic]); GET_CCL_INT (i, ccl_prog, ic++);
ic++;
op = field1 >> 6; op = field1 >> 6;
goto ccl_expr_self; goto ccl_expr_self;
...@@ -1159,9 +1177,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1159,9 +1177,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */ case CCL_SetExprConst: /* 00000OPERATION000RRRrrrXXXXX */
i = reg[RRR]; i = reg[RRR];
j = XINT (ccl_prog[ic]); GET_CCL_INT (j, ccl_prog, ic++);
op = field1 >> 6; op = field1 >> 6;
jump_address = ++ic; jump_address = ic;
goto ccl_set_expr; goto ccl_set_expr;
case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */ case CCL_SetExprReg: /* 00000OPERATIONRrrRRRrrrXXXXX */
...@@ -1175,10 +1193,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1175,10 +1193,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR (reg[rrr]); CCL_READ_CHAR (reg[rrr]);
case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */ case CCL_JumpCondExprConst: /* A--D--D--R--E--S--S-rrrXXXXX */
i = reg[rrr]; i = reg[rrr];
op = XINT (ccl_prog[ic]); jump_address = ic + ADDR;
jump_address = ic++ + ADDR; GET_CCL_INT (op, ccl_prog, ic++);
j = XINT (ccl_prog[ic]); GET_CCL_INT (j, ccl_prog, ic++);
ic++;
rrr = 7; rrr = 7;
goto ccl_set_expr; goto ccl_set_expr;
...@@ -1186,10 +1203,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1186,10 +1203,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR (reg[rrr]); CCL_READ_CHAR (reg[rrr]);
case CCL_JumpCondExprReg: case CCL_JumpCondExprReg:
i = reg[rrr]; i = reg[rrr];
op = XINT (ccl_prog[ic]); jump_address = ic + ADDR;
jump_address = ic++ + ADDR; GET_CCL_INT (op, ccl_prog, ic++);
j = reg[XINT (ccl_prog[ic])]; GET_CCL_RANGE (j, ccl_prog, ic++, 0, 7);
ic++; j = reg[j];
rrr = 7; rrr = 7;
ccl_set_expr: ccl_set_expr:
...@@ -1267,18 +1284,27 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1267,18 +1284,27 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
case CCL_TranslateCharacterConstTbl: case CCL_TranslateCharacterConstTbl:
op = XINT (ccl_prog[ic]); /* table */ {
ic++; EMACS_INT eop;
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]); GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
op = translate_char (GET_TRANSLATION_TABLE (op), i); (VECTORP (Vtranslation_table_vector)
CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]); ? ASIZE (Vtranslation_table_vector)
: -1));
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
op = translate_char (GET_TRANSLATION_TABLE (eop), i);
CCL_ENCODE_CHAR (op, charset_list, reg[RRR], reg[rrr]);
}
break; break;
case CCL_LookupIntConstTbl: case CCL_LookupIntConstTbl:
op = XINT (ccl_prog[ic]); /* table */
ic++;
{ {
struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); EMACS_INT eop;
struct Lisp_Hash_Table *h;
GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
(VECTORP (Vtranslation_hash_table_vector)
? ASIZE (Vtranslation_hash_table_vector)
: -1));
h = GET_HASH_TABLE (eop);
op = hash_lookup (h, make_number (reg[RRR]), NULL); op = hash_lookup (h, make_number (reg[RRR]), NULL);
if (op >= 0) if (op >= 0)
...@@ -1297,18 +1323,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1297,18 +1323,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
case CCL_LookupCharConstTbl: case CCL_LookupCharConstTbl:
op = XINT (ccl_prog[ic]); /* table */
ic++;
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
{ {
struct Lisp_Hash_Table *h = GET_HASH_TABLE (op); EMACS_INT eop;
struct Lisp_Hash_Table *h;
GET_CCL_RANGE (eop, ccl_prog, ic++, 0,
(VECTORP (Vtranslation_hash_table_vector)
? ASIZE (Vtranslation_hash_table_vector)
: -1));
i = CCL_DECODE_CHAR (reg[RRR], reg[rrr]);
h = GET_HASH_TABLE (eop);
op = hash_lookup (h, make_number (i), NULL); op = hash_lookup (h, make_number (i), NULL);
if (op >= 0) if (op >= 0)
{ {
Lisp_Object opl; Lisp_Object opl;
opl = HASH_VALUE (h, op); opl = HASH_VALUE (h, op);
if (!INTEGERP (opl)) if (! (INTEGERP (opl) && IN_INT_RANGE (XINT (opl))))
CCL_INVALID_CMD; CCL_INVALID_CMD;
reg[RRR] = XINT (opl); reg[RRR] = XINT (opl);
reg[7] = 1; /* r7 true for success */ 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,9 +1351,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_IterateMultipleMap: case CCL_IterateMultipleMap:
{ {
Lisp_Object map, content, attrib, value; Lisp_Object map, content, attrib, value;
int point, size, fin_ic; EMACS_INT point, size;
int fin_ic;
j = XINT (ccl_prog[ic++]); /* number of maps. */ GET_CCL_INT (j, ccl_prog, ic++); /* number of maps. */
fin_ic = ic + j; fin_ic = ic + j;
op = reg[rrr]; op = reg[rrr];
if ((j > reg[RRR]) && (j >= 0)) if ((j > reg[RRR]) && (j >= 0))
...@@ -1343,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1343,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
size = ASIZE (Vcode_conversion_map_vector); size = ASIZE (Vcode_conversion_map_vector);
point = XINT (ccl_prog[ic++]); point = XINT (ccl_prog[ic++]);
if (point >= size) continue; if (! (0 <= point && point < size)) continue;
map = AREF (Vcode_conversion_map_vector, point); map = AREF (Vcode_conversion_map_vector, point);
/* Check map validity. */ /* Check map validity. */
...@@ -1358,18 +1389,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1358,18 +1389,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
/* check map type, /* check map type,
[STARTPOINT VAL1 VAL2 ...] or [STARTPOINT VAL1 VAL2 ...] or
[t ELEMENT STARTPOINT ENDPOINT] */ [t ELEMENT STARTPOINT ENDPOINT] */
if (NUMBERP (content)) if (INTEGERP (content))
{ {
point = XUINT (content); point = XINT (content);
point = op - point + 1; if (!(point <= op && op - point + 1 < size)) continue;
if (!((point >= 1) && (point < size))) continue; content = AREF (map, op - point + 1);
content = AREF (map, point);
} }
else if (EQ (content, Qt)) else if (EQ (content, Qt))
{ {
if (size != 4) continue; if (size != 4) continue;
if ((op >= XUINT (AREF (map, 2))) if (INTEGERP (AREF (map, 2))
&& (op < XUINT (AREF (map, 3)))) && XINT (AREF (map, 2)) <= op
&& INTEGERP (AREF (map, 3))
&& op < XINT (AREF (map, 3)))
content = AREF (map, 1); content = AREF (map, 1);
else else
continue; continue;
...@@ -1379,7 +1411,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1379,7 +1411,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
if (NILP (content)) if (NILP (content))
continue; continue;
else if (NUMBERP (content)) else if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
{ {
reg[RRR] = i; reg[RRR] = i;
reg[rrr] = XINT(content); reg[rrr] = XINT(content);
...@@ -1394,10 +1426,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1394,10 +1426,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{ {
attrib = XCAR (content); attrib = XCAR (content);
value = XCDR (content); value = XCDR (content);
if (!NUMBERP (attrib) || !NUMBERP (value)) if (! (INTEGERP (attrib) && INTEGERP (value)
&& IN_INT_RANGE (XINT (value))))
continue; continue;
reg[RRR] = i; reg[RRR] = i;
reg[rrr] = XUINT (value); reg[rrr] = XINT (value);
break; break;
} }
else if (SYMBOLP (content)) else if (SYMBOLP (content))
...@@ -1432,8 +1465,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1432,8 +1465,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
mapping_stack_pointer = mapping_stack; mapping_stack_pointer = mapping_stack;
stack_idx_of_map_multiple = 0; stack_idx_of_map_multiple = 0;
map_set_rest_length = /* Get number of maps and separators. */
XINT (ccl_prog[ic++]); /* number of maps and separators. */ GET_CCL_INT (map_set_rest_length, ccl_prog, ic++);
fin_ic = ic + map_set_rest_length; fin_ic = ic + map_set_rest_length;
op = reg[rrr]; op = reg[rrr];
...@@ -1501,7 +1535,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1501,7 +1535,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
do { do {
for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--) for (;map_set_rest_length > 0;i++, ic++, map_set_rest_length--)
{ {
point = XINT(ccl_prog[ic]); GET_CCL_INT (point, ccl_prog, ic);
if (point < 0) if (point < 0)
{ {
/* +1 is for including separator. */ /* +1 is for including separator. */
...@@ -1531,18 +1565,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1531,18 +1565,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
/* check map type, /* check map type,
[STARTPOINT VAL1 VAL2 ...] or [STARTPOINT VAL1 VAL2 ...] or
[t ELEMENT STARTPOINT ENDPOINT] */ [t ELEMENT STARTPOINT ENDPOINT] */
if (NUMBERP (content)) if (INTEGERP (content))
{ {
point = XUINT (content); point = XINT (content);
point = op - point + 1; if (!(point <= op && op - point + 1 < size)) continue;
if (!((point >= 1) && (point < size))) continue; content = AREF (map, op - point + 1);
content = AREF (map, point);
} }
else if (EQ (content, Qt)) else if (EQ (content, Qt))
{ {
if (size != 4) continue; if (size != 4) continue;
if ((op >= XUINT (AREF (map, 2))) && if (INTEGERP (AREF (map, 2))
(op < XUINT (AREF (map, 3)))) && XINT (AREF (map, 2)) <= op
&& INTEGERP (AREF (map, 3))
&& op < XINT (AREF (map, 3)))
content = AREF (map, 1); content = AREF (map, 1);
else else
continue; continue;
...@@ -1554,7 +1589,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1554,7 +1589,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
continue; continue;
reg[RRR] = i; reg[RRR] = i;
if (NUMBERP (content)) if (INTEGERP (content) && IN_INT_RANGE (XINT (content)))
{ {
op = XINT (content); op = XINT (content);
i += map_set_rest_length - 1; i += map_set_rest_length - 1;
...@@ -1566,9 +1601,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size ...@@ -1566,9 +1601,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{ {
attrib = XCAR (content); attrib = XCAR (content);
value = XCDR (content); value = XCDR (content);
if (!NUMBERP (attrib) || !NUMBERP (value)) if (! (INTEGERP (attrib) && INTEGERP (value)
&& IN_INT_RANGE (XINT (value))))
continue; continue;
op = XUINT (value); op = XINT (value);
i += map_set_rest_length - 1; i += map_set_rest_length - 1;
ic += map_set_rest_length - 1; ic += map_set_rest_length - 1;
POP_MAPPING_STACK (map_set_rest_length, reg[rrr]); 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,7 +1649,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case CCL_MapSingle: case CCL_MapSingle:
{ {
Lisp_Object map, attrib, value, content; Lisp_Object map, attrib, value, content;
int size, point; int point;
j = XINT (ccl_prog[ic++]); /* map_id */ j = XINT (ccl_prog[ic++]); /* map_id */
op = reg[rrr]; op = reg[rrr];
if (j >= ASIZE (Vcode_conversion_map_vector)) 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,41 +1664,36 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break; break;
} }
map = XCDR (map); map = XCDR (map);
if (!VECTORP (map)) if (! (VECTORP (map)
&& INTEGERP (AREF (map, 0))
&& XINT (AREF (map, 0)) <= op
&& op - XINT (AREF (map, 0)) + 1 < ASIZE (map)))
{ {
reg[RRR] = -1; reg[RRR] = -1;
break; break;
} }
size = ASIZE (map); point = XINT (AREF (map, 0));
point = XUINT (AREF (map, 0));
point = op - point + 1; point = op - point + 1;
reg[RRR] = 0; reg[RRR] = 0;