diff options
| author | Paul Eggert | 2011-06-06 01:29:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-06 01:29:01 -0700 |
| commit | be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434 (patch) | |
| tree | 34110ed6783c1314604f3382e8cd6d0812b939e3 | |
| parent | d1f3d2afe1057a99b9dec6d1bd5b57bfee81fdff (diff) | |
| download | emacs-be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434.tar.gz emacs-be44ca6cd47bff4cb0dfcfd71aa14f10fdab5434.zip | |
Check for overflow when converting integer to cons and back.
* charset.c (Fdefine_charset_internal, Fdecode_char):
Use cons_to_unsigned to catch overflow.
(Fencode_char): Use INTEGER_TO_CONS.
* composite.h (LGLYPH_CODE): Use cons_to_unsigned.
(LGLYPH_SET_CODE): Use INTEGER_TO_CONS.
* data.c (long_to_cons, cons_to_long): Remove.
(cons_to_unsigned, cons_to_signed): New functions.
These signal an error for invalid or out-of-range values.
* dired.c (Ffile_attributes): Use INTEGER_TO_CONS.
* fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER.
* font.c (Ffont_variation_glyphs):
* fontset.c (Finternal_char_font): Use INTEGER_TO_CONS.
* lisp.h: Include <intprops.h>.
(INTEGER_TO_CONS, CONS_TO_INTEGER): New macros.
(cons_to_signed, cons_to_unsigned): New decls.
(long_to_cons, cons_to_long): Remove decls.
* undo.c (record_first_change): Use INTEGER_TO_CONS.
(Fprimitive_undo): Use CONS_TO_INTEGER.
* xfns.c (Fx_window_property): Likewise.
* xselect.c: Include <limits.h>.
(x_own_selection, selection_data_to_lisp_data):
Use INTEGER_TO_CONS.
(x_handle_selection_request, x_handle_selection_clear)
(x_get_foreign_selection, Fx_disown_selection_internal)
(Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER.
(lisp_data_to_selection_data): Use cons_to_unsigned.
(x_fill_property_data): Use cons_to_signed.
Report values out of range.
| -rw-r--r-- | src/ChangeLog | 30 | ||||
| -rw-r--r-- | src/charset.c | 38 | ||||
| -rw-r--r-- | src/composite.h | 16 | ||||
| -rw-r--r-- | src/data.c | 121 | ||||
| -rw-r--r-- | src/dired.c | 39 | ||||
| -rw-r--r-- | src/fileio.c | 2 | ||||
| -rw-r--r-- | src/font.c | 10 | ||||
| -rw-r--r-- | src/fontset.c | 8 | ||||
| -rw-r--r-- | src/lisp.h | 32 | ||||
| -rw-r--r-- | src/undo.c | 15 | ||||
| -rw-r--r-- | src/xfns.c | 15 | ||||
| -rw-r--r-- | src/xselect.c | 88 |
12 files changed, 219 insertions, 195 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index bf81533460a..c9c739dde9a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,35 @@ | |||
| 1 | 2011-06-06 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-06-06 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Check for overflow when converting integer to cons and back. | ||
| 4 | * charset.c (Fdefine_charset_internal, Fdecode_char): | ||
| 5 | Use cons_to_unsigned to catch overflow. | ||
| 6 | (Fencode_char): Use INTEGER_TO_CONS. | ||
| 7 | * composite.h (LGLYPH_CODE): Use cons_to_unsigned. | ||
| 8 | (LGLYPH_SET_CODE): Use INTEGER_TO_CONS. | ||
| 9 | * data.c (long_to_cons, cons_to_long): Remove. | ||
| 10 | (cons_to_unsigned, cons_to_signed): New functions. | ||
| 11 | These signal an error for invalid or out-of-range values. | ||
| 12 | * dired.c (Ffile_attributes): Use INTEGER_TO_CONS. | ||
| 13 | * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER. | ||
| 14 | * font.c (Ffont_variation_glyphs): | ||
| 15 | * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS. | ||
| 16 | * lisp.h: Include <intprops.h>. | ||
| 17 | (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros. | ||
| 18 | (cons_to_signed, cons_to_unsigned): New decls. | ||
| 19 | (long_to_cons, cons_to_long): Remove decls. | ||
| 20 | * undo.c (record_first_change): Use INTEGER_TO_CONS. | ||
| 21 | (Fprimitive_undo): Use CONS_TO_INTEGER. | ||
| 22 | * xfns.c (Fx_window_property): Likewise. | ||
| 23 | * xselect.c: Include <limits.h>. | ||
| 24 | (x_own_selection, selection_data_to_lisp_data): | ||
| 25 | Use INTEGER_TO_CONS. | ||
| 26 | (x_handle_selection_request, x_handle_selection_clear) | ||
| 27 | (x_get_foreign_selection, Fx_disown_selection_internal) | ||
| 28 | (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER. | ||
| 29 | (lisp_data_to_selection_data): Use cons_to_unsigned. | ||
| 30 | (x_fill_property_data): Use cons_to_signed. | ||
| 31 | Report values out of range. | ||
| 32 | |||
| 3 | Check for buffer and string overflow more precisely. | 33 | Check for buffer and string overflow more precisely. |
| 4 | * buffer.h (BUF_BYTES_MAX): New macro. | 34 | * buffer.h (BUF_BYTES_MAX): New macro. |
| 5 | * lisp.h (STRING_BYTES_MAX): New macro. | 35 | * lisp.h (STRING_BYTES_MAX): New macro. |
diff --git a/src/charset.c b/src/charset.c index bfebe02f52e..770e98c99e1 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -932,17 +932,8 @@ usage: (define-charset-internal ...) */) | |||
| 932 | val = args[charset_arg_min_code]; | 932 | val = args[charset_arg_min_code]; |
| 933 | if (! NILP (val)) | 933 | if (! NILP (val)) |
| 934 | { | 934 | { |
| 935 | unsigned code; | 935 | unsigned code = cons_to_unsigned (val, UINT_MAX); |
| 936 | 936 | ||
| 937 | if (INTEGERP (val)) | ||
| 938 | code = XINT (val); | ||
| 939 | else | ||
| 940 | { | ||
| 941 | CHECK_CONS (val); | ||
| 942 | CHECK_NUMBER_CAR (val); | ||
| 943 | CHECK_NUMBER_CDR (val); | ||
| 944 | code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); | ||
| 945 | } | ||
| 946 | if (code < charset.min_code | 937 | if (code < charset.min_code |
| 947 | || code > charset.max_code) | 938 | || code > charset.max_code) |
| 948 | args_out_of_range_3 (make_number (charset.min_code), | 939 | args_out_of_range_3 (make_number (charset.min_code), |
| @@ -954,17 +945,8 @@ usage: (define-charset-internal ...) */) | |||
| 954 | val = args[charset_arg_max_code]; | 945 | val = args[charset_arg_max_code]; |
| 955 | if (! NILP (val)) | 946 | if (! NILP (val)) |
| 956 | { | 947 | { |
| 957 | unsigned code; | 948 | unsigned code = cons_to_unsigned (val, UINT_MAX); |
| 958 | 949 | ||
| 959 | if (INTEGERP (val)) | ||
| 960 | code = XINT (val); | ||
| 961 | else | ||
| 962 | { | ||
| 963 | CHECK_CONS (val); | ||
| 964 | CHECK_NUMBER_CAR (val); | ||
| 965 | CHECK_NUMBER_CDR (val); | ||
| 966 | code = (XINT (XCAR (val)) << 16) | (XINT (XCDR (val))); | ||
| 967 | } | ||
| 968 | if (code < charset.min_code | 950 | if (code < charset.min_code |
| 969 | || code > charset.max_code) | 951 | || code > charset.max_code) |
| 970 | args_out_of_range_3 (make_number (charset.min_code), | 952 | args_out_of_range_3 (make_number (charset.min_code), |
| @@ -1865,17 +1847,7 @@ and CODE-POINT to a character. Currently not supported and just ignored. */) | |||
| 1865 | struct charset *charsetp; | 1847 | struct charset *charsetp; |
| 1866 | 1848 | ||
| 1867 | CHECK_CHARSET_GET_ID (charset, id); | 1849 | CHECK_CHARSET_GET_ID (charset, id); |
| 1868 | if (CONSP (code_point)) | 1850 | code = cons_to_unsigned (code_point, UINT_MAX); |
| 1869 | { | ||
| 1870 | CHECK_NATNUM_CAR (code_point); | ||
| 1871 | CHECK_NATNUM_CDR (code_point); | ||
| 1872 | code = (XINT (XCAR (code_point)) << 16) | (XINT (XCDR (code_point))); | ||
| 1873 | } | ||
| 1874 | else | ||
| 1875 | { | ||
| 1876 | CHECK_NATNUM (code_point); | ||
| 1877 | code = XINT (code_point); | ||
| 1878 | } | ||
| 1879 | charsetp = CHARSET_FROM_ID (id); | 1851 | charsetp = CHARSET_FROM_ID (id); |
| 1880 | c = DECODE_CHAR (charsetp, code); | 1852 | c = DECODE_CHAR (charsetp, code); |
| 1881 | return (c >= 0 ? make_number (c) : Qnil); | 1853 | return (c >= 0 ? make_number (c) : Qnil); |
| @@ -1900,9 +1872,7 @@ code-point in CCS. Currently not supported and just ignored. */) | |||
| 1900 | code = ENCODE_CHAR (charsetp, XINT (ch)); | 1872 | code = ENCODE_CHAR (charsetp, XINT (ch)); |
| 1901 | if (code == CHARSET_INVALID_CODE (charsetp)) | 1873 | if (code == CHARSET_INVALID_CODE (charsetp)) |
| 1902 | return Qnil; | 1874 | return Qnil; |
| 1903 | if (code > 0x7FFFFFF) | 1875 | return INTEGER_TO_CONS (code); |
| 1904 | return Fcons (make_number (code >> 16), make_number (code & 0xFFFF)); | ||
| 1905 | return make_number (code); | ||
| 1906 | } | 1876 | } |
| 1907 | 1877 | ||
| 1908 | 1878 | ||
diff --git a/src/composite.h b/src/composite.h index cc8ca10a139..0f81911f0b0 100644 --- a/src/composite.h +++ b/src/composite.h | |||
| @@ -265,10 +265,7 @@ enum lglyph_indices | |||
| 265 | #define LGLYPH_CODE(g) \ | 265 | #define LGLYPH_CODE(g) \ |
| 266 | (NILP (AREF ((g), LGLYPH_IX_CODE)) \ | 266 | (NILP (AREF ((g), LGLYPH_IX_CODE)) \ |
| 267 | ? FONT_INVALID_CODE \ | 267 | ? FONT_INVALID_CODE \ |
| 268 | : CONSP (AREF ((g), LGLYPH_IX_CODE)) \ | 268 | : cons_to_unsigned (AREF (g, LGLYPH_IX_CODE), TYPE_MAXIMUM (unsigned))) |
| 269 | ? ((XFASTINT (XCAR (AREF ((g), LGLYPH_IX_CODE))) << 16) \ | ||
| 270 | | (XFASTINT (XCDR (AREF ((g), LGLYPH_IX_CODE))))) \ | ||
| 271 | : XFASTINT (AREF ((g), LGLYPH_IX_CODE))) | ||
| 272 | #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) | 269 | #define LGLYPH_WIDTH(g) XINT (AREF ((g), LGLYPH_IX_WIDTH)) |
| 273 | #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) | 270 | #define LGLYPH_LBEARING(g) XINT (AREF ((g), LGLYPH_IX_LBEARING)) |
| 274 | #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) | 271 | #define LGLYPH_RBEARING(g) XINT (AREF ((g), LGLYPH_IX_RBEARING)) |
| @@ -280,15 +277,8 @@ enum lglyph_indices | |||
| 280 | #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) | 277 | #define LGLYPH_SET_CHAR(g, val) ASET ((g), LGLYPH_IX_CHAR, make_number (val)) |
| 281 | /* Callers must assure that VAL is not negative! */ | 278 | /* Callers must assure that VAL is not negative! */ |
| 282 | #define LGLYPH_SET_CODE(g, val) \ | 279 | #define LGLYPH_SET_CODE(g, val) \ |
| 283 | do { \ | 280 | ASET (g, LGLYPH_IX_CODE, \ |
| 284 | if (val == FONT_INVALID_CODE) \ | 281 | val == FONT_INVALID_CODE ? Qnil : INTEGER_TO_CONS (val)) |
| 285 | ASET ((g), LGLYPH_IX_CODE, Qnil); \ | ||
| 286 | else if ((EMACS_INT)val > MOST_POSITIVE_FIXNUM) \ | ||
| 287 | ASET ((g), LGLYPH_IX_CODE, Fcons (make_number ((val) >> 16), \ | ||
| 288 | make_number ((val) & 0xFFFF))); \ | ||
| 289 | else \ | ||
| 290 | ASET ((g), LGLYPH_IX_CODE, make_number (val)); \ | ||
| 291 | } while (0) | ||
| 292 | 282 | ||
| 293 | #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) | 283 | #define LGLYPH_SET_WIDTH(g, val) ASET ((g), LGLYPH_IX_WIDTH, make_number (val)) |
| 294 | #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) | 284 | #define LGLYPH_SET_LBEARING(g, val) ASET ((g), LGLYPH_IX_LBEARING, make_number (val)) |
diff --git a/src/data.c b/src/data.c index 78bd454056d..a41ffe7a1f6 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2326,33 +2326,110 @@ DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, | |||
| 2326 | return Qnil; | 2326 | return Qnil; |
| 2327 | } | 2327 | } |
| 2328 | 2328 | ||
| 2329 | /* Convert between long values and pairs of Lisp integers. | 2329 | /* Convert the cons-of-integers, integer, or float value C to an |
| 2330 | Note that long_to_cons returns a single Lisp integer | 2330 | unsigned value with maximum value MAX. Signal an error if C does not |
| 2331 | when the value fits in one. */ | 2331 | have a valid format or is out of range. */ |
| 2332 | uintmax_t | ||
| 2333 | cons_to_unsigned (Lisp_Object c, uintmax_t max) | ||
| 2334 | { | ||
| 2335 | int valid = 0; | ||
| 2336 | uintmax_t val IF_LINT (= 0); | ||
| 2337 | if (INTEGERP (c)) | ||
| 2338 | { | ||
| 2339 | valid = 0 <= XINT (c); | ||
| 2340 | val = XINT (c); | ||
| 2341 | } | ||
| 2342 | else if (FLOATP (c)) | ||
| 2343 | { | ||
| 2344 | double d = XFLOAT_DATA (c); | ||
| 2345 | if (0 <= d | ||
| 2346 | && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1)) | ||
| 2347 | { | ||
| 2348 | val = d; | ||
| 2349 | valid = 1; | ||
| 2350 | } | ||
| 2351 | } | ||
| 2352 | else if (CONSP (c) && NATNUMP (XCAR (c))) | ||
| 2353 | { | ||
| 2354 | uintmax_t top = XFASTINT (XCAR (c)); | ||
| 2355 | Lisp_Object rest = XCDR (c); | ||
| 2356 | if (top <= UINTMAX_MAX >> 24 >> 16 | ||
| 2357 | && CONSP (rest) | ||
| 2358 | && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 | ||
| 2359 | && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) | ||
| 2360 | { | ||
| 2361 | uintmax_t mid = XFASTINT (XCAR (rest)); | ||
| 2362 | val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); | ||
| 2363 | valid = 1; | ||
| 2364 | } | ||
| 2365 | else if (top <= UINTMAX_MAX >> 16) | ||
| 2366 | { | ||
| 2367 | if (CONSP (rest)) | ||
| 2368 | rest = XCAR (rest); | ||
| 2369 | if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) | ||
| 2370 | { | ||
| 2371 | val = top << 16 | XFASTINT (rest); | ||
| 2372 | valid = 1; | ||
| 2373 | } | ||
| 2374 | } | ||
| 2375 | } | ||
| 2332 | 2376 | ||
| 2333 | Lisp_Object | 2377 | if (! (valid && val <= max)) |
| 2334 | long_to_cons (long unsigned int i) | 2378 | error ("Not an in-range integer, float, or cons of integers"); |
| 2335 | { | 2379 | return val; |
| 2336 | unsigned long top = i >> 16; | ||
| 2337 | unsigned int bot = i & 0xFFFF; | ||
| 2338 | if (top == 0) | ||
| 2339 | return make_number (bot); | ||
| 2340 | if (top == (unsigned long)-1 >> 16) | ||
| 2341 | return Fcons (make_number (-1), make_number (bot)); | ||
| 2342 | return Fcons (make_number (top), make_number (bot)); | ||
| 2343 | } | 2380 | } |
| 2344 | 2381 | ||
| 2345 | unsigned long | 2382 | /* Convert the cons-of-integers, integer, or float value C to a signed |
| 2346 | cons_to_long (Lisp_Object c) | 2383 | value with extrema MIN and MAX. Signal an error if C does not have |
| 2384 | a valid format or is out of range. */ | ||
| 2385 | intmax_t | ||
| 2386 | cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | ||
| 2347 | { | 2387 | { |
| 2348 | Lisp_Object top, bot; | 2388 | int valid = 0; |
| 2389 | intmax_t val IF_LINT (= 0); | ||
| 2349 | if (INTEGERP (c)) | 2390 | if (INTEGERP (c)) |
| 2350 | return XINT (c); | 2391 | { |
| 2351 | top = XCAR (c); | 2392 | val = XINT (c); |
| 2352 | bot = XCDR (c); | 2393 | valid = 1; |
| 2353 | if (CONSP (bot)) | 2394 | } |
| 2354 | bot = XCAR (bot); | 2395 | else if (FLOATP (c)) |
| 2355 | return ((XINT (top) << 16) | XINT (bot)); | 2396 | { |
| 2397 | double d = XFLOAT_DATA (c); | ||
| 2398 | if (min <= d | ||
| 2399 | && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1)) | ||
| 2400 | { | ||
| 2401 | val = d; | ||
| 2402 | valid = 1; | ||
| 2403 | } | ||
| 2404 | } | ||
| 2405 | else if (CONSP (c) && INTEGERP (XCAR (c))) | ||
| 2406 | { | ||
| 2407 | intmax_t top = XINT (XCAR (c)); | ||
| 2408 | Lisp_Object rest = XCDR (c); | ||
| 2409 | if (INTMAX_MIN >> 24 >> 16 <= top && top <= INTMAX_MAX >> 24 >> 16 | ||
| 2410 | && CONSP (rest) | ||
| 2411 | && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24 | ||
| 2412 | && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16) | ||
| 2413 | { | ||
| 2414 | intmax_t mid = XFASTINT (XCAR (rest)); | ||
| 2415 | val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest)); | ||
| 2416 | valid = 1; | ||
| 2417 | } | ||
| 2418 | else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16) | ||
| 2419 | { | ||
| 2420 | if (CONSP (rest)) | ||
| 2421 | rest = XCAR (rest); | ||
| 2422 | if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16) | ||
| 2423 | { | ||
| 2424 | val = top << 16 | XFASTINT (rest); | ||
| 2425 | valid = 1; | ||
| 2426 | } | ||
| 2427 | } | ||
| 2428 | } | ||
| 2429 | |||
| 2430 | if (! (valid && min <= val && val <= max)) | ||
| 2431 | error ("Not an in-range integer, float, or cons of integers"); | ||
| 2432 | return val; | ||
| 2356 | } | 2433 | } |
| 2357 | 2434 | ||
| 2358 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, | 2435 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, |
diff --git a/src/dired.c b/src/dired.c index 1e587353f6d..a95882060fb 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -900,11 +900,10 @@ Elements of the attribute list are: | |||
| 900 | This is a floating point number if the size is too large for an integer. | 900 | This is a floating point number if the size is too large for an integer. |
| 901 | 8. File modes, as a string of ten letters or dashes as in ls -l. | 901 | 8. File modes, as a string of ten letters or dashes as in ls -l. |
| 902 | 9. t if file's gid would change if file were deleted and recreated. | 902 | 9. t if file's gid would change if file were deleted and recreated. |
| 903 | 10. inode number. If inode number is larger than what Emacs integer | 903 | 10. inode number. If it is larger than what an Emacs integer can hold, |
| 904 | can hold, but still fits into a 32-bit number, this is a cons cell | 904 | this is of the form (HIGH . LOW): first the high bits, then the low 16 bits. |
| 905 | containing two integers: first the high part, then the low 16 bits. | 905 | If even HIGH is too large for an Emacs integer, this is instead of the form |
| 906 | If the inode number is wider than 32 bits, this is of the form | 906 | (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits, |
| 907 | (HIGH MIDDLE . LOW): first the high 24 bits, then middle 24 bits, | ||
| 908 | and finally the low 16 bits. | 907 | and finally the low 16 bits. |
| 909 | 11. Filesystem device number. If it is larger than what the Emacs | 908 | 11. Filesystem device number. If it is larger than what the Emacs |
| 910 | integer can hold, this is a cons cell, similar to the inode number. | 909 | integer can hold, this is a cons cell, similar to the inode number. |
| @@ -998,34 +997,8 @@ so last access time will always be midnight of that day. */) | |||
| 998 | #else /* file gid will be egid */ | 997 | #else /* file gid will be egid */ |
| 999 | values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; | 998 | values[9] = (s.st_gid != getegid ()) ? Qt : Qnil; |
| 1000 | #endif /* not BSD4_2 */ | 999 | #endif /* not BSD4_2 */ |
| 1001 | if (!FIXNUM_OVERFLOW_P (s.st_ino)) | 1000 | values[10] = INTEGER_TO_CONS (s.st_ino); |
| 1002 | /* Keep the most common cases as integers. */ | 1001 | values[11] = INTEGER_TO_CONS (s.st_dev); |
| 1003 | values[10] = make_number (s.st_ino); | ||
| 1004 | else if (!FIXNUM_OVERFLOW_P (s.st_ino >> 16)) | ||
| 1005 | /* To allow inode numbers larger than VALBITS, separate the bottom | ||
| 1006 | 16 bits. */ | ||
| 1007 | values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)), | ||
| 1008 | make_number ((EMACS_INT)(s.st_ino & 0xffff))); | ||
| 1009 | else | ||
| 1010 | { | ||
| 1011 | /* To allow inode numbers beyond 32 bits, separate into 2 24-bit | ||
| 1012 | high parts and a 16-bit bottom part. | ||
| 1013 | The code on the next line avoids a compiler warning on | ||
| 1014 | systems where st_ino is 32 bit wide. (bug#766). */ | ||
| 1015 | EMACS_INT high_ino = s.st_ino >> 31 >> 1; | ||
| 1016 | |||
| 1017 | values[10] = Fcons (make_number (high_ino >> 8), | ||
| 1018 | Fcons (make_number (((high_ino & 0xff) << 16) | ||
| 1019 | + (s.st_ino >> 16 & 0xffff)), | ||
| 1020 | make_number (s.st_ino & 0xffff))); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /* Likewise for device. */ | ||
| 1024 | if (FIXNUM_OVERFLOW_P (s.st_dev)) | ||
| 1025 | values[11] = Fcons (make_number (s.st_dev >> 16), | ||
| 1026 | make_number (s.st_dev & 0xffff)); | ||
| 1027 | else | ||
| 1028 | values[11] = make_number (s.st_dev); | ||
| 1029 | 1002 | ||
| 1030 | return Flist (sizeof(values) / sizeof(values[0]), values); | 1003 | return Flist (sizeof(values) / sizeof(values[0]), values); |
| 1031 | } | 1004 | } |
diff --git a/src/fileio.c b/src/fileio.c index 82b31036fb9..d9bc28d8c37 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -5005,7 +5005,7 @@ An argument specifies the modification time value to use | |||
| 5005 | { | 5005 | { |
| 5006 | if (!NILP (time_list)) | 5006 | if (!NILP (time_list)) |
| 5007 | { | 5007 | { |
| 5008 | current_buffer->modtime = cons_to_long (time_list); | 5008 | CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime); |
| 5009 | current_buffer->modtime_size = -1; | 5009 | current_buffer->modtime_size = -1; |
| 5010 | } | 5010 | } |
| 5011 | else | 5011 | else |
diff --git a/src/font.c b/src/font.c index 398198324a4..326c9d80e44 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -4388,16 +4388,8 @@ where | |||
| 4388 | for (i = 0; i < 255; i++) | 4388 | for (i = 0; i < 255; i++) |
| 4389 | if (variations[i]) | 4389 | if (variations[i]) |
| 4390 | { | 4390 | { |
| 4391 | Lisp_Object code; | ||
| 4392 | int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); | 4391 | int vs = (i < 16 ? 0xFE00 + i : 0xE0100 + (i - 16)); |
| 4393 | /* Stops GCC whining about limited range of data type. */ | 4392 | Lisp_Object code = INTEGER_TO_CONS (variations[i]); |
| 4394 | EMACS_INT var = variations[i]; | ||
| 4395 | |||
| 4396 | if (var > MOST_POSITIVE_FIXNUM) | ||
| 4397 | code = Fcons (make_number ((variations[i]) >> 16), | ||
| 4398 | make_number ((variations[i]) & 0xFFFF)); | ||
| 4399 | else | ||
| 4400 | code = make_number (variations[i]); | ||
| 4401 | val = Fcons (Fcons (make_number (vs), code), val); | 4393 | val = Fcons (Fcons (make_number (vs), code), val); |
| 4402 | } | 4394 | } |
| 4403 | return val; | 4395 | return val; |
diff --git a/src/fontset.c b/src/fontset.c index 46637b53b3e..fec3c56b036 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1859,17 +1859,11 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, | |||
| 1859 | { | 1859 | { |
| 1860 | unsigned code = face->font->driver->encode_char (face->font, c); | 1860 | unsigned code = face->font->driver->encode_char (face->font, c); |
| 1861 | Lisp_Object font_object; | 1861 | Lisp_Object font_object; |
| 1862 | /* Assignment to EMACS_INT stops GCC whining about limited range | ||
| 1863 | of data type. */ | ||
| 1864 | EMACS_INT cod = code; | ||
| 1865 | 1862 | ||
| 1866 | if (code == FONT_INVALID_CODE) | 1863 | if (code == FONT_INVALID_CODE) |
| 1867 | return Qnil; | 1864 | return Qnil; |
| 1868 | XSETFONT (font_object, face->font); | 1865 | XSETFONT (font_object, face->font); |
| 1869 | if (cod <= MOST_POSITIVE_FIXNUM) | 1866 | return Fcons (font_object, INTEGER_TO_CONS (code)); |
| 1870 | return Fcons (font_object, make_number (code)); | ||
| 1871 | return Fcons (font_object, Fcons (make_number (code >> 16), | ||
| 1872 | make_number (code & 0xFFFF))); | ||
| 1873 | } | 1867 | } |
| 1874 | return Qnil; | 1868 | return Qnil; |
| 1875 | } | 1869 | } |
diff --git a/src/lisp.h b/src/lisp.h index a46436e718b..1c1e3ec3708 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | #include <stddef.h> | 24 | #include <stddef.h> |
| 25 | #include <inttypes.h> | 25 | #include <inttypes.h> |
| 26 | 26 | ||
| 27 | #include <intprops.h> | ||
| 28 | |||
| 27 | /* Use the configure flag --enable-checking[=LIST] to enable various | 29 | /* Use the configure flag --enable-checking[=LIST] to enable various |
| 28 | types of run time checks for Lisp objects. */ | 30 | types of run time checks for Lisp objects. */ |
| 29 | 31 | ||
| @@ -2408,9 +2410,35 @@ EXFUN (Fadd1, 1); | |||
| 2408 | EXFUN (Fsub1, 1); | 2410 | EXFUN (Fsub1, 1); |
| 2409 | EXFUN (Fmake_variable_buffer_local, 1); | 2411 | EXFUN (Fmake_variable_buffer_local, 1); |
| 2410 | 2412 | ||
| 2413 | /* Convert the integer I to an Emacs representation, either the integer | ||
| 2414 | itself, or a cons of two or three integers, or if all else fails a float. | ||
| 2415 | I should not have side effects. */ | ||
| 2416 | #define INTEGER_TO_CONS(i) \ | ||
| 2417 | (! FIXNUM_OVERFLOW_P (i) \ | ||
| 2418 | ? make_number (i) \ | ||
| 2419 | : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16) \ | ||
| 2420 | || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16)) \ | ||
| 2421 | && FIXNUM_OVERFLOW_P ((i) >> 16)) \ | ||
| 2422 | ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff)) \ | ||
| 2423 | : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16 >> 24) \ | ||
| 2424 | || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16 >> 24)) \ | ||
| 2425 | && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24)) \ | ||
| 2426 | ? Fcons (make_number ((i) >> 16 >> 24), \ | ||
| 2427 | Fcons (make_number ((i) >> 16 & 0xffffff), \ | ||
| 2428 | make_number ((i) & 0xffff))) \ | ||
| 2429 | : make_float (i)) | ||
| 2430 | |||
| 2431 | /* Convert the Emacs representation CONS back to an integer of type | ||
| 2432 | TYPE, storing the result the variable VAR. Signal an error if CONS | ||
| 2433 | is not a valid representation or is out of range for TYPE. */ | ||
| 2434 | #define CONS_TO_INTEGER(cons, type, var) \ | ||
| 2435 | (TYPE_SIGNED (type) \ | ||
| 2436 | ? ((var) = cons_to_signed (cons, TYPE_MINIMUM (type), TYPE_MAXIMUM (type))) \ | ||
| 2437 | : ((var) = cons_to_unsigned (cons, TYPE_MAXIMUM (type)))) | ||
| 2438 | extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); | ||
| 2439 | extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); | ||
| 2440 | |||
| 2411 | extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); | 2441 | extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); |
| 2412 | extern Lisp_Object long_to_cons (unsigned long); | ||
| 2413 | extern unsigned long cons_to_long (Lisp_Object); | ||
| 2414 | extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; | 2442 | extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; |
| 2415 | extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, | 2443 | extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, |
| 2416 | Lisp_Object) NO_RETURN; | 2444 | Lisp_Object) NO_RETURN; |
diff --git a/src/undo.c b/src/undo.c index 142960545a7..e7e9ae5632e 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length) | |||
| 212 | void | 212 | void |
| 213 | record_first_change (void) | 213 | record_first_change (void) |
| 214 | { | 214 | { |
| 215 | Lisp_Object high, low; | ||
| 216 | struct buffer *base_buffer = current_buffer; | 215 | struct buffer *base_buffer = current_buffer; |
| 217 | 216 | ||
| 218 | if (EQ (BVAR (current_buffer, undo_list), Qt)) | 217 | if (EQ (BVAR (current_buffer, undo_list), Qt)) |
| @@ -225,9 +224,9 @@ record_first_change (void) | |||
| 225 | if (base_buffer->base_buffer) | 224 | if (base_buffer->base_buffer) |
| 226 | base_buffer = base_buffer->base_buffer; | 225 | base_buffer = base_buffer->base_buffer; |
| 227 | 226 | ||
| 228 | XSETFASTINT (high, (base_buffer->modtime >> 16) & 0xffff); | 227 | BVAR (current_buffer, undo_list) = |
| 229 | XSETFASTINT (low, base_buffer->modtime & 0xffff); | 228 | Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)), |
| 230 | BVAR (current_buffer, undo_list) = Fcons (Fcons (Qt, Fcons (high, low)), BVAR (current_buffer, undo_list)); | 229 | BVAR (current_buffer, undo_list)); |
| 231 | } | 230 | } |
| 232 | 231 | ||
| 233 | /* Record a change in property PROP (whose old value was VAL) | 232 | /* Record a change in property PROP (whose old value was VAL) |
| @@ -499,13 +498,9 @@ Return what remains of the list. */) | |||
| 499 | if (EQ (car, Qt)) | 498 | if (EQ (car, Qt)) |
| 500 | { | 499 | { |
| 501 | /* Element (t high . low) records previous modtime. */ | 500 | /* Element (t high . low) records previous modtime. */ |
| 502 | Lisp_Object high, low; | ||
| 503 | time_t mod_time; | ||
| 504 | struct buffer *base_buffer = current_buffer; | 501 | struct buffer *base_buffer = current_buffer; |
| 505 | 502 | time_t mod_time; | |
| 506 | high = Fcar (cdr); | 503 | CONS_TO_INTEGER (cdr, time_t, mod_time); |
| 507 | low = Fcdr (cdr); | ||
| 508 | mod_time = (XFASTINT (high) << 16) + XFASTINT (low); | ||
| 509 | 504 | ||
| 510 | if (current_buffer->base_buffer) | 505 | if (current_buffer->base_buffer) |
| 511 | base_buffer = current_buffer->base_buffer; | 506 | base_buffer = current_buffer->base_buffer; |
diff --git a/src/xfns.c b/src/xfns.c index 34ffdbffbfe..c307cc345e3 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -4299,18 +4299,9 @@ no value of TYPE (always string in the MS Windows case). */) | |||
| 4299 | 4299 | ||
| 4300 | if (! NILP (source)) | 4300 | if (! NILP (source)) |
| 4301 | { | 4301 | { |
| 4302 | if (NUMBERP (source)) | 4302 | CONS_TO_INTEGER (source, Window, target_window); |
| 4303 | { | 4303 | if (! target_window) |
| 4304 | if (FLOATP (source)) | 4304 | target_window = FRAME_X_DISPLAY_INFO (f)->root_window; |
| 4305 | target_window = (Window) XFLOAT (source); | ||
| 4306 | else | ||
| 4307 | target_window = XFASTINT (source); | ||
| 4308 | |||
| 4309 | if (target_window == 0) | ||
| 4310 | target_window = FRAME_X_DISPLAY_INFO (f)->root_window; | ||
| 4311 | } | ||
| 4312 | else if (CONSP (source)) | ||
| 4313 | target_window = cons_to_long (source); | ||
| 4314 | } | 4305 | } |
| 4315 | 4306 | ||
| 4316 | BLOCK_INPUT; | 4307 | BLOCK_INPUT; |
diff --git a/src/xselect.c b/src/xselect.c index 00d70eee477..5b01fc22a42 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | /* Rewritten by jwz */ | 20 | /* Rewritten by jwz */ |
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include <limits.h> | ||
| 23 | #include <stdio.h> /* termhooks.h needs this */ | 24 | #include <stdio.h> /* termhooks.h needs this */ |
| 24 | #include <setjmp.h> | 25 | #include <setjmp.h> |
| 25 | 26 | ||
| @@ -335,7 +336,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, | |||
| 335 | Lisp_Object prev_value; | 336 | Lisp_Object prev_value; |
| 336 | 337 | ||
| 337 | selection_data = list4 (selection_name, selection_value, | 338 | selection_data = list4 (selection_name, selection_value, |
| 338 | long_to_cons (timestamp), frame); | 339 | INTEGER_TO_CONS (timestamp), frame); |
| 339 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); | 340 | prev_value = LOCAL_SELECTION (selection_name, dpyinfo); |
| 340 | 341 | ||
| 341 | dpyinfo->terminal->Vselection_alist | 342 | dpyinfo->terminal->Vselection_alist |
| @@ -419,7 +420,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 419 | || INTEGERP (check) | 420 | || INTEGERP (check) |
| 420 | || NILP (value)) | 421 | || NILP (value)) |
| 421 | return value; | 422 | return value; |
| 422 | /* Check for a value that cons_to_long could handle. */ | 423 | /* Check for a value that CONS_TO_INTEGER could handle. */ |
| 423 | else if (CONSP (check) | 424 | else if (CONSP (check) |
| 424 | && INTEGERP (XCAR (check)) | 425 | && INTEGERP (XCAR (check)) |
| 425 | && (INTEGERP (XCDR (check)) | 426 | && (INTEGERP (XCDR (check)) |
| @@ -782,8 +783,8 @@ x_handle_selection_request (struct input_event *event) | |||
| 782 | if (NILP (local_selection_data)) goto DONE; | 783 | if (NILP (local_selection_data)) goto DONE; |
| 783 | 784 | ||
| 784 | /* Decline requests issued prior to our acquiring the selection. */ | 785 | /* Decline requests issued prior to our acquiring the selection. */ |
| 785 | local_selection_time | 786 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 786 | = (Time) cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 787 | Time, local_selection_time); |
| 787 | if (SELECTION_EVENT_TIME (event) != CurrentTime | 788 | if (SELECTION_EVENT_TIME (event) != CurrentTime |
| 788 | && local_selection_time > SELECTION_EVENT_TIME (event)) | 789 | && local_selection_time > SELECTION_EVENT_TIME (event)) |
| 789 | goto DONE; | 790 | goto DONE; |
| @@ -950,8 +951,8 @@ x_handle_selection_clear (struct input_event *event) | |||
| 950 | /* Well, we already believe that we don't own it, so that's just fine. */ | 951 | /* Well, we already believe that we don't own it, so that's just fine. */ |
| 951 | if (NILP (local_selection_data)) return; | 952 | if (NILP (local_selection_data)) return; |
| 952 | 953 | ||
| 953 | local_selection_time = (Time) | 954 | CONS_TO_INTEGER (XCAR (XCDR (XCDR (local_selection_data))), |
| 954 | cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))); | 955 | Time, local_selection_time); |
| 955 | 956 | ||
| 956 | /* We have reasserted the selection since this SelectionClear was | 957 | /* We have reasserted the selection since this SelectionClear was |
| 957 | generated, so we can disregard it. */ | 958 | generated, so we can disregard it. */ |
| @@ -1212,16 +1213,7 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, | |||
| 1212 | return Qnil; | 1213 | return Qnil; |
| 1213 | 1214 | ||
| 1214 | if (! NILP (time_stamp)) | 1215 | if (! NILP (time_stamp)) |
| 1215 | { | 1216 | CONS_TO_INTEGER (time_stamp, Time, requestor_time); |
| 1216 | if (CONSP (time_stamp)) | ||
| 1217 | requestor_time = (Time) cons_to_long (time_stamp); | ||
| 1218 | else if (INTEGERP (time_stamp)) | ||
| 1219 | requestor_time = (Time) XUINT (time_stamp); | ||
| 1220 | else if (FLOATP (time_stamp)) | ||
| 1221 | requestor_time = (Time) XFLOAT_DATA (time_stamp); | ||
| 1222 | else | ||
| 1223 | error ("TIME_STAMP must be cons or number"); | ||
| 1224 | } | ||
| 1225 | 1217 | ||
| 1226 | BLOCK_INPUT; | 1218 | BLOCK_INPUT; |
| 1227 | TRACE2 ("Get selection %s, type %s", | 1219 | TRACE2 ("Get selection %s, type %s", |
| @@ -1639,7 +1631,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1639 | convert it to a cons of integers, 16 bits in each half. | 1631 | convert it to a cons of integers, 16 bits in each half. |
| 1640 | */ | 1632 | */ |
| 1641 | else if (format == 32 && size == sizeof (int)) | 1633 | else if (format == 32 && size == sizeof (int)) |
| 1642 | return long_to_cons (((unsigned int *) data) [0]); | 1634 | return INTEGER_TO_CONS (((unsigned int *) data) [0]); |
| 1643 | else if (format == 16 && size == sizeof (short)) | 1635 | else if (format == 16 && size == sizeof (short)) |
| 1644 | return make_number ((int) (((unsigned short *) data) [0])); | 1636 | return make_number ((int) (((unsigned short *) data) [0])); |
| 1645 | 1637 | ||
| @@ -1665,7 +1657,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, | |||
| 1665 | for (i = 0; i < size / 4; i++) | 1657 | for (i = 0; i < size / 4; i++) |
| 1666 | { | 1658 | { |
| 1667 | unsigned int j = ((unsigned int *) data) [i]; | 1659 | unsigned int j = ((unsigned int *) data) [i]; |
| 1668 | Faset (v, make_number (i), long_to_cons (j)); | 1660 | Faset (v, make_number (i), INTEGER_TO_CONS (j)); |
| 1669 | } | 1661 | } |
| 1670 | return v; | 1662 | return v; |
| 1671 | } | 1663 | } |
| @@ -1742,7 +1734,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1742 | *size_ret = 1; | 1734 | *size_ret = 1; |
| 1743 | *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); | 1735 | *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1); |
| 1744 | (*data_ret) [sizeof (long)] = 0; | 1736 | (*data_ret) [sizeof (long)] = 0; |
| 1745 | (*(unsigned long **) data_ret) [0] = cons_to_long (obj); | 1737 | (*(unsigned long **) data_ret) [0] = cons_to_unsigned (obj, ULONG_MAX); |
| 1746 | if (NILP (type)) type = QINTEGER; | 1738 | if (NILP (type)) type = QINTEGER; |
| 1747 | } | 1739 | } |
| 1748 | else if (VECTORP (obj)) | 1740 | else if (VECTORP (obj)) |
| @@ -1790,11 +1782,11 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, | |||
| 1790 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); | 1782 | *data_ret = (unsigned char *) xmalloc (*size_ret * data_size); |
| 1791 | for (i = 0; i < *size_ret; i++) | 1783 | for (i = 0; i < *size_ret; i++) |
| 1792 | if (*format_ret == 32) | 1784 | if (*format_ret == 32) |
| 1793 | (*((unsigned long **) data_ret)) [i] | 1785 | (*((unsigned long **) data_ret)) [i] = |
| 1794 | = cons_to_long (XVECTOR (obj)->contents [i]); | 1786 | cons_to_unsigned (XVECTOR (obj)->contents [i], ULONG_MAX); |
| 1795 | else | 1787 | else |
| 1796 | (*((unsigned short **) data_ret)) [i] | 1788 | (*((unsigned short **) data_ret)) [i] = |
| 1797 | = (unsigned short) cons_to_long (XVECTOR (obj)->contents [i]); | 1789 | cons_to_unsigned (XVECTOR (obj)->contents [i], USHRT_MAX); |
| 1798 | } | 1790 | } |
| 1799 | } | 1791 | } |
| 1800 | else | 1792 | else |
| @@ -2012,8 +2004,10 @@ frame's display, or the first available X display. */) | |||
| 2012 | selection_atom = symbol_to_x_atom (dpyinfo, selection); | 2004 | selection_atom = symbol_to_x_atom (dpyinfo, selection); |
| 2013 | 2005 | ||
| 2014 | BLOCK_INPUT; | 2006 | BLOCK_INPUT; |
| 2015 | timestamp = (NILP (time_object) ? last_event_timestamp | 2007 | if (NILP (time_object)) |
| 2016 | : cons_to_long (time_object)); | 2008 | timestamp = last_event_timestamp; |
| 2009 | else | ||
| 2010 | CONS_TO_INTEGER (time_object, Time, timestamp); | ||
| 2017 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); | 2011 | XSetSelectionOwner (dpyinfo->display, selection_atom, None, timestamp); |
| 2018 | UNBLOCK_INPUT; | 2012 | UNBLOCK_INPUT; |
| 2019 | 2013 | ||
| @@ -2250,12 +2244,8 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2250 | { | 2244 | { |
| 2251 | Lisp_Object o = XCAR (iter); | 2245 | Lisp_Object o = XCAR (iter); |
| 2252 | 2246 | ||
| 2253 | if (INTEGERP (o)) | 2247 | if (INTEGERP (o) || FLOATP (o) || CONSP (o)) |
| 2254 | val = (long) XFASTINT (o); | 2248 | val = cons_to_signed (o, LONG_MIN, LONG_MAX); |
| 2255 | else if (FLOATP (o)) | ||
| 2256 | val = (long) XFLOAT_DATA (o); | ||
| 2257 | else if (CONSP (o)) | ||
| 2258 | val = (long) cons_to_long (o); | ||
| 2259 | else if (STRINGP (o)) | 2249 | else if (STRINGP (o)) |
| 2260 | { | 2250 | { |
| 2261 | BLOCK_INPUT; | 2251 | BLOCK_INPUT; |
| @@ -2266,9 +2256,19 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format) | |||
| 2266 | error ("Wrong type, must be string, number or cons"); | 2256 | error ("Wrong type, must be string, number or cons"); |
| 2267 | 2257 | ||
| 2268 | if (format == 8) | 2258 | if (format == 8) |
| 2269 | *d08++ = (char) val; | 2259 | { |
| 2260 | if (CHAR_MIN <= val && val <= CHAR_MAX) | ||
| 2261 | *d08++ = val; | ||
| 2262 | else | ||
| 2263 | error ("Out of 'char' range"); | ||
| 2264 | } | ||
| 2270 | else if (format == 16) | 2265 | else if (format == 16) |
| 2271 | *d16++ = (short) val; | 2266 | { |
| 2267 | if (SHRT_MIN <= val && val <= SHRT_MAX) | ||
| 2268 | *d16++ = val; | ||
| 2269 | else | ||
| 2270 | error ("Out of 'short' range"); | ||
| 2271 | } | ||
| 2272 | else | 2272 | else |
| 2273 | *d32++ = val; | 2273 | *d32++ = val; |
| 2274 | } | 2274 | } |
| @@ -2352,14 +2352,7 @@ If the value is 0 or the atom is not known, return the empty string. */) | |||
| 2352 | Atom atom; | 2352 | Atom atom; |
| 2353 | int had_errors; | 2353 | int had_errors; |
| 2354 | 2354 | ||
| 2355 | if (INTEGERP (value)) | 2355 | CONS_TO_INTEGER (value, Atom, atom); |
| 2356 | atom = (Atom) XUINT (value); | ||
| 2357 | else if (FLOATP (value)) | ||
| 2358 | atom = (Atom) XFLOAT_DATA (value); | ||
| 2359 | else if (CONSP (value)) | ||
| 2360 | atom = (Atom) cons_to_long (value); | ||
| 2361 | else | ||
| 2362 | error ("Wrong type, value must be number or cons"); | ||
| 2363 | 2356 | ||
| 2364 | BLOCK_INPUT; | 2357 | BLOCK_INPUT; |
| 2365 | x_catch_errors (dpy); | 2358 | x_catch_errors (dpy); |
| @@ -2549,17 +2542,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, At | |||
| 2549 | else | 2542 | else |
| 2550 | error ("DEST as a string must be one of PointerWindow or InputFocus"); | 2543 | error ("DEST as a string must be one of PointerWindow or InputFocus"); |
| 2551 | } | 2544 | } |
| 2552 | else if (INTEGERP (dest)) | 2545 | else if (INTEGERP (dest) || FLOATP (dest) || CONSP (dest)) |
| 2553 | wdest = (Window) XFASTINT (dest); | 2546 | CONS_TO_INTEGER (dest, Window, wdest); |
| 2554 | else if (FLOATP (dest)) | ||
| 2555 | wdest = (Window) XFLOAT_DATA (dest); | ||
| 2556 | else if (CONSP (dest)) | ||
| 2557 | { | ||
| 2558 | if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest))) | ||
| 2559 | error ("Both car and cdr for DEST must be numbers"); | ||
| 2560 | else | ||
| 2561 | wdest = (Window) cons_to_long (dest); | ||
| 2562 | } | ||
| 2563 | else | 2547 | else |
| 2564 | error ("DEST must be a frame, nil, string, number or cons"); | 2548 | error ("DEST must be a frame, nil, string, number or cons"); |
| 2565 | 2549 | ||