Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
0f6990a7
Commit
0f6990a7
authored
May 27, 2011
by
Paul Eggert
Browse files
Merge: Integer overflow fixes.
parents
fb1ac845
b57f7e0a
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
855 additions
and
569 deletions
+855
-569
src/ChangeLog
src/ChangeLog
+82
-0
src/alloc.c
src/alloc.c
+1
-1
src/ccl.c
src/ccl.c
+134
-103
src/character.c
src/character.c
+7
-2
src/character.h
src/character.h
+1
-1
src/data.c
src/data.c
+37
-4
src/dbusbind.c
src/dbusbind.c
+59
-35
src/editfns.c
src/editfns.c
+528
-383
src/fns.c
src/fns.c
+1
-1
src/insdel.c
src/insdel.c
+0
-31
src/lisp.h
src/lisp.h
+2
-4
src/mem-limits.h
src/mem-limits.h
+2
-3
src/print.c
src/print.c
+1
-1
No files found.
src/ChangeLog
View file @
0f6990a7
2011-05-27 Paul Eggert <eggert@cs.ucla.edu>
Integer overflow fixes.
* dbusbind.c: Serial number integer overflow fixes.
(CHECK_DBUS_SERIAL_GET_SERIAL): New macro.
(Fdbus_call_method_asynchronously, xd_read_message_1): Use a float
to hold a serial number that is too large for a fixnum.
(Fdbus_method_return_internal, Fdbus_method_error_internal):
Check for serial numbers out of range. Decode any serial number
that was so large that it became a float. (Bug#8722)
* dbusbind.c: Use XFASTINT rather than XUINT, and check for nonneg.
(Fdbus_call_method, Fdbus_call_method_asynchronously):
Use XFASTINT rather than XUINT when numbers are nonnegative.
(xd_append_arg, Fdbus_method_return_internal):
(Fdbus_method_error_internal): Likewise. Also, for unsigned
arguments, check that Lisp number is nonnegative, rather than
silently wrapping negative numbers around. (Bug#8722)
(xd_read_message_1): Don't assume dbus_uint32_t can fit in int.
(Bug#8722)
* data.c (arith_driver, Flsh): Avoid unnecessary casts to EMACS_UINT.
* ccl.c (ccl_driver): Redo slightly to avoid the need for 'unsigned'.
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. (Bug#8719)
* alloc.c (make_event_array): Use XINT, not XUINT.
There's no need for unsigned here.
* mem-limits.h (EXCEEDS_LISP_PTR) [!USE_LSB_TAG]: EMACS_UINT -> uintptr_t
This follows up to the 2011-05-06 change that substituted uintptr_t
for EMACS_INT. This case wasn't caught back then.
Rework Fformat to avoid integer overflow issues.
* editfns.c: Include <float.h> unconditionally, as it's everywhere
now (part of C89). Include <verify.h>.
(MAX_10_EXP, CONVERTED_BYTE_SIZE): Remove; no longer needed.
(pWIDE, pWIDElen, signed_wide, unsigned_wide): New defns.
(Fformat): Avoid the prepass trying to compute sizes; it was only
approximate and thus did not catch overflow reliably. Instead, walk
through the format just once, formatting and computing sizes as we go,
checking for integer overflow at every step, and allocating a larger
buffer as needed. Keep track separately whether the format is
multibyte. Keep only the most-recently calculated precision, rather
than them all. Record whether each argument has been converted to
string. Use EMACS_INT, not int, for byte and char and arg counts.
Support field widths and precisions larger than INT_MAX. Avoid
sprintf's undefined behavior with conversion specifications such as %#d
and %.0c. Fix bug with strchr succeeding on '\0' when looking for
flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when
formatting out-of-range floating point numbers with int
formats. (Bug#8668)
* lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN.
* data.c: Avoid integer truncation in expressions involving floats.
* data.c: Include <intprops.h>.
(arith_driver): When there's an integer overflow in an expression
involving floating point, convert the integers to floating point
so that the resulting value does not suffer from catastrophic
integer truncation. For example, on a 64-bit host (* 4
most-negative-fixnum 0.5) should yield about -4.6e+18, not zero.
Do not rely on undefined behavior after integer overflow.
merge count_size_as_multibyte, parse_str_to_multibyte
* character.c, character.h (count_size_as_multibyte):
Renamed from parse_str_to_multibyte; all uses changed.
Check for integer overflow.
* insdel.c, lisp.h (count_size_as_multibyte): Remove,
since it's now a duplicate of the other. This is more of
a character than a buffer op, so better that it's in character.c.
* fns.c, print.c: Adjust to above changes.
2011-05-27 Paul Eggert <eggert@cs.ucla.edu>
* xselect.c: Fix minor problems prompted by GCC 4.6.0 warnings.
...
...
src/alloc.c
View file @
0f6990a7
...
...
@@ -3244,7 +3244,7 @@ make_event_array (register int nargs, Lisp_Object *args)
are characters that are in 0...127,
after discarding the meta bit and all the bits above it. */
if (!INTEGERP (args[i])
|| (X
U
INT (args[i]) & ~(-CHAR_META)) >= 0200)
|| (XINT (args[i]) & ~(-CHAR_META)) >= 0200)
return Fvector (nargs, args);
/* Since the loop exited, we know that all the things in it are
...
...
src/ccl.c
View file @
0f6990a7
...
...
@@ -98,6 +98,8 @@ static Lisp_Object Vccl_program_table;
and `rrr' are CCL register number, `XXXXX' is one of the following
CCL commands. */
#define CCL_CODE_MAX ((1 << (28 - 1)) - 1)
/* CCL commands
Each comment fields shows one or more lines for command syntax and
...
...
@@ -742,6 +744,24 @@ while(0)
#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
output buffer. If CH is less than 256, CH is written as is. */
#define CCL_WRITE_CHAR(ch) \
...
...
@@ -899,7 +919,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
}
this_ic
=
ic
;
code
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_CODE
(
code
,
ccl_prog
,
ic
++
)
;
field1
=
code
>>
8
;
field2
=
(
code
&
0xFF
)
>>
5
;
...
...
@@ -920,15 +940,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
case
CCL_SetConst
:
/* 00000000000000000000rrrXXXXX */
reg
[
rrr
]
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_INT
(
reg
[
rrr
],
ccl_prog
,
ic
++
);
break
;
case
CCL_SetArray
:
/* CCCCCCCCCCCCCCCCCCCCRRRrrrXXXXX */
i
=
reg
[
RRR
];
j
=
field1
>>
3
;
if
(
(
unsigned
int
)
i
<
j
)
reg
[
rrr
]
=
XINT
(
ccl_prog
[
ic
+
i
]
);
if
(
0
<=
i
&&
i
<
j
)
GET_CCL_INT
(
reg
[
rrr
],
ccl_prog
,
ic
+
i
);
ic
+=
j
;
break
;
...
...
@@ -956,13 +975,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
case
CCL_WriteConstJump
:
/* A--D--D--R--E--S--S-000XXXXX */
i
=
X
INT
(
ccl_prog
[
ic
]
);
GET_CCL_
INT
(
i
,
ccl_prog
,
ic
);
CCL_WRITE_CHAR
(
i
);
ic
+=
ADDR
;
break
;
case
CCL_WriteConstReadJump
:
/* A--D--D--R--E--S--S-rrrXXXXX */
i
=
X
INT
(
ccl_prog
[
ic
]
);
GET_CCL_
INT
(
i
,
ccl_prog
,
ic
);
CCL_WRITE_CHAR
(
i
);
ic
++
;
CCL_READ_CHAR
(
reg
[
rrr
]);
...
...
@@ -970,18 +989,17 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
case
CCL_WriteStringJump
:
/* A--D--D--R--E--S--S-000XXXXX */
j
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_INT
(
j
,
ccl_prog
,
ic
++
);
CCL_WRITE_STRING
(
j
);
ic
+=
ADDR
-
1
;
break
;
case
CCL_WriteArrayReadJump
:
/* A--D--D--R--E--S--S-rrrXXXXX */
i
=
reg
[
rrr
];
j
=
X
INT
(
ccl_prog
[
ic
]
);
if
(
(
unsigned
int
)
i
<
j
)
GET_CCL_
INT
(
j
,
ccl_prog
,
ic
);
if
(
0
<=
i
&&
i
<
j
)
{
i
=
X
INT
(
ccl_prog
[
ic
+
1
+
i
]
);
GET_CCL_
INT
(
i
,
ccl_prog
,
ic
+
1
+
i
);
CCL_WRITE_CHAR
(
i
);
}
ic
+=
j
+
2
;
...
...
@@ -998,10 +1016,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR
(
reg
[
rrr
]);
/* fall through ... */
case
CCL_Branch
:
/* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
if
((
unsigned
int
)
reg
[
rrr
]
<
field1
)
ic
+=
XINT
(
ccl_prog
[
ic
+
reg
[
rrr
]]);
else
ic
+=
XINT
(
ccl_prog
[
ic
+
field1
]);
{
int
incr
;
GET_CCL_INT
(
incr
,
ccl_prog
,
ic
+
(
0
<=
reg
[
rrr
]
&&
reg
[
rrr
]
<
field1
?
reg
[
rrr
]
:
field1
));
ic
+=
incr
;
}
break
;
case
CCL_ReadRegister
:
/* CCCCCCCCCCCCCCCCCCCCrrXXXXX */
...
...
@@ -1009,7 +1031,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{
CCL_READ_CHAR
(
reg
[
rrr
]);
if
(
!
field1
)
break
;
code
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_CODE
(
code
,
ccl_prog
,
ic
++
)
;
field1
=
code
>>
8
;
field2
=
(
code
&
0xFF
)
>>
5
;
}
...
...
@@ -1018,7 +1040,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case
CCL_WriteExprConst
:
/* 1:00000OPERATION000RRR000XXXXX */
rrr
=
7
;
i
=
reg
[
RRR
];
j
=
X
INT
(
ccl_prog
[
ic
]
);
GET_CCL_
INT
(
j
,
ccl_prog
,
ic
);
op
=
field1
>>
6
;
jump_address
=
ic
+
1
;
goto
ccl_set_expr
;
...
...
@@ -1029,7 +1051,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
i
=
reg
[
rrr
];
CCL_WRITE_CHAR
(
i
);
if
(
!
field1
)
break
;
code
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_CODE
(
code
,
ccl_prog
,
ic
++
)
;
field1
=
code
>>
8
;
field2
=
(
code
&
0xFF
)
>>
5
;
}
...
...
@@ -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
following code. */
if
(
rrr
)
{
prog_id
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
}
GET_CCL_INT
(
prog_id
,
ccl_prog
,
ic
++
);
else
prog_id
=
field1
;
...
...
@@ -1095,9 +1114,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case
CCL_WriteArray
:
/* CCCCCCCCCCCCCCCCCCCCrrrXXXXX */
i
=
reg
[
rrr
];
if
(
(
unsigned
int
)
i
<
field1
)
if
(
0
<=
i
&&
i
<
field1
)
{
j
=
X
INT
(
ccl_prog
[
ic
+
i
]
);
GET_CCL_
INT
(
j
,
ccl_prog
,
ic
+
i
);
CCL_WRITE_CHAR
(
j
);
}
ic
+=
field1
;
...
...
@@ -1122,8 +1141,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_SUCCESS
;
case
CCL_ExprSelfConst
:
/* 00000OPERATION000000rrrXXXXX */
i
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
GET_CCL_INT
(
i
,
ccl_prog
,
ic
++
);
op
=
field1
>>
6
;
goto
ccl_expr_self
;
...
...
@@ -1159,9 +1177,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case
CCL_SetExprConst
:
/* 00000OPERATION000RRRrrrXXXXX */
i
=
reg
[
RRR
];
j
=
X
INT
(
ccl_prog
[
ic
]
);
GET_CCL_
INT
(
j
,
ccl_prog
,
ic
++
);
op
=
field1
>>
6
;
jump_address
=
++
ic
;
jump_address
=
ic
;
goto
ccl_set_expr
;
case
CCL_SetExprReg
:
/* 00000OPERATIONRrrRRRrrrXXXXX */
...
...
@@ -1175,10 +1193,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR
(
reg
[
rrr
]);
case
CCL_JumpCondExprConst
:
/* A--D--D--R--E--S--S-rrrXXXXX */
i
=
reg
[
rrr
];
op
=
XINT
(
ccl_prog
[
ic
]);
jump_address
=
ic
++
+
ADDR
;
j
=
XINT
(
ccl_prog
[
ic
]);
ic
++
;
jump_address
=
ic
+
ADDR
;
GET_CCL_INT
(
op
,
ccl_prog
,
ic
++
);
GET_CCL_INT
(
j
,
ccl_prog
,
ic
++
);
rrr
=
7
;
goto
ccl_set_expr
;
...
...
@@ -1186,10 +1203,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
CCL_READ_CHAR
(
reg
[
rrr
]);
case
CCL_JumpCondExprReg
:
i
=
reg
[
rrr
];
op
=
XINT
(
ccl_prog
[
ic
])
;
jump_address
=
ic
++
+
ADDR
;
j
=
reg
[
XINT
(
ccl_prog
[
ic
])]
;
ic
++
;
jump_address
=
ic
+
ADDR
;
GET_CCL_INT
(
op
,
ccl_prog
,
ic
++
)
;
GET_CCL_RANGE
(
j
,
ccl_prog
,
ic
++
,
0
,
7
)
;
j
=
reg
[
j
]
;
rrr
=
7
;
ccl_set_expr:
...
...
@@ -1267,18 +1284,27 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
case
CCL_TranslateCharacterConstTbl
:
op
=
XINT
(
ccl_prog
[
ic
]);
/* table */
ic
++
;
i
=
CCL_DECODE_CHAR
(
reg
[
RRR
],
reg
[
rrr
]);
op
=
translate_char
(
GET_TRANSLATION_TABLE
(
op
),
i
);
CCL_ENCODE_CHAR
(
op
,
charset_list
,
reg
[
RRR
],
reg
[
rrr
]);
{
EMACS_INT
eop
;
GET_CCL_RANGE
(
eop
,
ccl_prog
,
ic
++
,
0
,
(
VECTORP
(
Vtranslation_table_vector
)
?
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
;
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
);
if
(
op
>=
0
)
...
...
@@ -1297,18 +1323,22 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
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
);
if
(
op
>=
0
)
{
Lisp_Object
opl
;
opl
=
HASH_VALUE
(
h
,
op
);
if
(
!
INTEGERP
(
opl
))
if
(
!
(
INTEGERP
(
opl
)
&&
IN_INT_RANGE
(
XINT
(
opl
)))
)
CCL_INVALID_CMD
;
reg
[
RRR
]
=
XINT
(
opl
);
reg
[
7
]
=
1
;
/* r7 true for success */
...
...
@@ -1321,9 +1351,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
case
CCL_IterateMultipleMap
:
{
Lisp_Object
map
,
content
,
attrib
,
value
;
int
point
,
size
,
fin_ic
;
EMACS_INT
point
,
size
;
int
fin_ic
;
j
=
X
INT
(
ccl_prog
[
ic
++
]
);
/* number of maps. */
GET_CCL_
INT
(
j
,
ccl_prog
,
ic
++
);
/* number of maps. */
fin_ic
=
ic
+
j
;
op
=
reg
[
rrr
];
if
((
j
>
reg
[
RRR
])
&&
(
j
>=
0
))
...
...
@@ -1343,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
size
=
ASIZE
(
Vcode_conversion_map_vector
);
point
=
XINT
(
ccl_prog
[
ic
++
]);
if
(
point
>=
size
)
continue
;
if
(
!
(
0
<=
point
&&
point
<
size
)
)
continue
;
map
=
AREF
(
Vcode_conversion_map_vector
,
point
);
/* Check map validity. */
...
...
@@ -1358,18 +1389,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
/* check map type,
[STARTPOINT VAL1 VAL2 ...] or
[t ELEMENT STARTPOINT ENDPOINT] */
if
(
NUMB
ERP
(
content
))
if
(
INTEG
ERP
(
content
))
{
point
=
XUINT
(
content
);
point
=
op
-
point
+
1
;
if
(
!
((
point
>=
1
)
&&
(
point
<
size
)))
continue
;
content
=
AREF
(
map
,
point
);
point
=
XINT
(
content
);
if
(
!
(
point
<=
op
&&
op
-
point
+
1
<
size
))
continue
;
content
=
AREF
(
map
,
op
-
point
+
1
);
}
else
if
(
EQ
(
content
,
Qt
))
{
if
(
size
!=
4
)
continue
;
if
((
op
>=
XUINT
(
AREF
(
map
,
2
)))
&&
(
op
<
XUINT
(
AREF
(
map
,
3
))))
if
(
INTEGERP
(
AREF
(
map
,
2
))
&&
XINT
(
AREF
(
map
,
2
))
<=
op
&&
INTEGERP
(
AREF
(
map
,
3
))
&&
op
<
XINT
(
AREF
(
map
,
3
)))
content
=
AREF
(
map
,
1
);
else
continue
;
...
...
@@ -1379,7 +1411,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
if
(
NILP
(
content
))
continue
;
else
if
(
NUMB
ERP
(
content
))
else
if
(
INTEG
ERP
(
content
)
&&
IN_INT_RANGE
(
XINT
(
content
))
)
{
reg
[
RRR
]
=
i
;
reg
[
rrr
]
=
XINT
(
content
);
...
...
@@ -1394,10 +1426,11 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{
attrib
=
XCAR
(
content
);
value
=
XCDR
(
content
);
if
(
!
NUMBERP
(
attrib
)
||
!
NUMBERP
(
value
))
if
(
!
(
INTEGERP
(
attrib
)
&&
INTEGERP
(
value
)
&&
IN_INT_RANGE
(
XINT
(
value
))))
continue
;
reg
[
RRR
]
=
i
;
reg
[
rrr
]
=
X
U
INT
(
value
);
reg
[
rrr
]
=
XINT
(
value
);
break
;
}
else
if
(
SYMBOLP
(
content
))
...
...
@@ -1432,8 +1465,9 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
mapping_stack_pointer
=
mapping_stack
;
stack_idx_of_map_multiple
=
0
;
map_set_rest_length
=
XINT
(
ccl_prog
[
ic
++
]);
/* number of maps and separators. */
/* Get number of maps and separators. */
GET_CCL_INT
(
map_set_rest_length
,
ccl_prog
,
ic
++
);
fin_ic
=
ic
+
map_set_rest_length
;
op
=
reg
[
rrr
];
...
...
@@ -1501,7 +1535,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
do
{
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
)
{
/* +1 is for including separator. */
...
...
@@ -1531,18 +1565,19 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
/* check map type,
[STARTPOINT VAL1 VAL2 ...] or
[t ELEMENT STARTPOINT ENDPOINT] */
if
(
NUMB
ERP
(
content
))
if
(
INTEG
ERP
(
content
))
{
point
=
XUINT
(
content
);
point
=
op
-
point
+
1
;
if
(
!
((
point
>=
1
)
&&
(
point
<
size
)))
continue
;
content
=
AREF
(
map
,
point
);
point
=
XINT
(
content
);
if
(
!
(
point
<=
op
&&
op
-
point
+
1
<
size
))
continue
;
content
=
AREF
(
map
,
op
-
point
+
1
);
}
else
if
(
EQ
(
content
,
Qt
))
{
if
(
size
!=
4
)
continue
;
if
((
op
>=
XUINT
(
AREF
(
map
,
2
)))
&&
(
op
<
XUINT
(
AREF
(
map
,
3
))))
if
(
INTEGERP
(
AREF
(
map
,
2
))
&&
XINT
(
AREF
(
map
,
2
))
<=
op
&&
INTEGERP
(
AREF
(
map
,
3
))
&&
op
<
XINT
(
AREF
(
map
,
3
)))
content
=
AREF
(
map
,
1
);
else
continue
;
...
...
@@ -1554,7 +1589,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
continue
;
reg
[
RRR
]
=
i
;
if
(
NUMB
ERP
(
content
))
if
(
INTEG
ERP
(
content
)
&&
IN_INT_RANGE
(
XINT
(
content
))
)
{
op
=
XINT
(
content
);
i
+=
map_set_rest_length
-
1
;
...
...
@@ -1566,9 +1601,10 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
{
attrib
=
XCAR
(
content
);
value
=
XCDR
(
content
);
if
(
!
NUMBERP
(
attrib
)
||
!
NUMBERP
(
value
))
if
(
!
(
INTEGERP
(
attrib
)
&&
INTEGERP
(
value
)
&&
IN_INT_RANGE
(
XINT
(
value
))))
continue
;
op
=
X
U
INT
(
value
);
op
=
XINT
(
value
);
i
+=
map_set_rest_length
-
1
;
ic
+=
map_set_rest_length
-
1
;
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
case
CCL_MapSingle
:
{
Lisp_Object
map
,
attrib
,
value
,
content
;
int
size
,
point
;
int
point
;
j
=
XINT
(
ccl_prog
[
ic
++
]);
/* map_id */
op
=
reg
[
rrr
];
if
(
j
>=
ASIZE
(
Vcode_conversion_map_vector
))
...
...
@@ -1628,41 +1664,36 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size
break
;
}
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
;
break
;
}
size
=
ASIZE
(
map
);
point
=
XUINT
(
AREF
(
map
,
0
));
point
=
XINT
(
AREF
(
map
,
0
));
point
=
op
-
point
+
1
;
reg
[
RRR
]
=
0
;
if
((
size
<=
1
)
||
(
!
((
point
>=
1
)
&&
(
point
<
size
))
))
content
=
AREF
(
map
,
point
);
if
(
NILP
(
content
))
reg
[
RRR
]
=
-
1
;
else
else
if
(
INTEGERP
(
content
))
reg
[
rrr
]
=
XINT
(
content
);
else
if
(
EQ
(
content
,
Qt
));
else
if
(
CONSP
(
content
))
{
reg
[
RRR
]
=
0
;
content
=
AREF
(
map
,
point
);
if
(
NILP
(
content
))
reg
[
RRR
]
=
-
1
;
else
if
(
NUMBERP
(
content
))
reg
[
rrr
]
=
XINT
(
content
);
else
if
(
EQ
(
content
,
Qt
));
else
if
(
CONSP
(
content
))
{
attrib
=
XCAR
(
content
);
value
=
XCDR
(
content
);
if
(
!
NUMBERP
(
attrib
)
||
!
NUMBERP
(
value
))
continue
;
reg
[
rrr
]
=
XUINT
(
value
);
break
;
}
else
if
(
SYMBOLP
(
content
))
CCL_CALL_FOR_MAP_INSTRUCTION
(
content
,
ic
);
else
reg
[
RRR
]
=
-
1
;
attrib
=
XCAR
(
content
);
value
=
XCDR
(
content
);
if
(
!
INTEGERP
(
attrib
)
||
!
INTEGERP
(
value
))
continue
;
reg
[
rrr
]
=
XINT
(
value
);
break
;
}
else
if
(
SYMBOLP
(
content
))
CCL_CALL_FOR_MAP_INSTRUCTION
(
content
,
ic
);
else
reg
[
RRR
]
=
-
1
;
}
break
;
...
...
src/character.c
View file @
0f6990a7
...
...
@@ -672,13 +672,18 @@ str_as_multibyte (unsigned char *str, EMACS_INT len, EMACS_INT nbytes,
`str_to_multibyte'. */
EMACS_INT
parse_str_to
_multibyte
(
const
unsigned
char
*
str
,
EMACS_INT
len
)
count_size_as
_multibyte
(
const
unsigned
char
*
str
,
EMACS_INT
len
)
{
const
unsigned
char
*
endp
=
str
+
len
;
EMACS_INT
bytes
;
for
(
bytes
=
0
;
str
<
endp
;
str
++
)
bytes
+=
(
*
str
<
0x80
)
?
1
:
2
;
{
int
n
=
*
str
<
0x80
?
1
:
2
;
if
(
INT_ADD_OVERFLOW
(
bytes
,
n
))
string_overflow
();
bytes
+=
n
;
}
return
bytes
;
}
...
...
src/character.h
View file @
0f6990a7
...
...
@@ -602,7 +602,7 @@ extern int translate_char (Lisp_Object, int c);
extern
int
char_printable_p
(
int
c
);
extern
void
parse_str_as_multibyte
(
const
unsigned
char
*
,
EMACS_INT
,
EMACS_INT
*
,
EMACS_INT
*
);
extern
EMACS_INT
parse_str_to
_multibyte
(
const
unsigned
char
*
,
EMACS_INT
);
extern
EMACS_INT
count_size_as
_multibyte
(
const
unsigned
char
*
,
EMACS_INT
);
extern
EMACS_INT
str_as_multibyte
(
unsigned
char
*
,
EMACS_INT
,
EMACS_INT
,
EMACS_INT
*
);
extern
EMACS_INT
str_to_multibyte
(
unsigned
char
*
,
EMACS_INT
,
EMACS_INT
);
...
...
src/data.c
View file @
0f6990a7
...
...
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include <intprops.h>
#include "lisp.h"
#include "puresize.h"
#include "character.h"
...
...
@@ -2431,6 +2434,10 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)