aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-06-06 11:36:36 -0700
committerPaul Eggert2011-06-06 11:36:36 -0700
commit0c1477cd00313d6aa13c40550a0b413a01d188c6 (patch)
treefecfa94a4e32d8bbe5d7c62f38ccbbc030bbe4ac /src
parentd6d100dd7c48e124ca9ce4bbb761f24b8e052493 (diff)
parent695e5b41ac15af4bcd635606db86995900617057 (diff)
downloademacs-0c1477cd00313d6aa13c40550a0b413a01d188c6.tar.gz
emacs-0c1477cd00313d6aa13c40550a0b413a01d188c6.zip
Merge: Cons<->int and similar integer overflow fixes.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog79
-rw-r--r--src/alloc.c2
-rw-r--r--src/buffer.h7
-rw-r--r--src/character.c4
-rw-r--r--src/character.h2
-rw-r--r--src/charset.c42
-rw-r--r--src/coding.c4
-rw-r--r--src/composite.h16
-rw-r--r--src/data.c121
-rw-r--r--src/dired.c40
-rw-r--r--src/doprnt.c4
-rw-r--r--src/editfns.c4
-rw-r--r--src/eval.c2
-rw-r--r--src/fileio.c8
-rw-r--r--src/font.c10
-rw-r--r--src/fontset.c8
-rw-r--r--src/ftfont.c2
-rw-r--r--src/image.c19
-rw-r--r--src/keyboard.c8
-rw-r--r--src/keymap.c14
-rw-r--r--src/lisp.h38
-rw-r--r--src/undo.c15
-rw-r--r--src/xfns.c15
-rw-r--r--src/xselect.c88
24 files changed, 317 insertions, 235 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 44dc1939db9..08a008d0c98 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,82 @@
12011-06-06 Paul Eggert <eggert@cs.ucla.edu>
2
3 Cons<->int and similar integer overflow fixes.
4
5 Check for overflow when converting integer to cons and back.
6 * charset.c (Fdefine_charset_internal, Fdecode_char):
7 Use cons_to_unsigned to catch overflow.
8 (Fencode_char): Use INTEGER_TO_CONS.
9 * composite.h (LGLYPH_CODE): Use cons_to_unsigned.
10 (LGLYPH_SET_CODE): Use INTEGER_TO_CONS.
11 * data.c (long_to_cons, cons_to_long): Remove.
12 (cons_to_unsigned, cons_to_signed): New functions.
13 These signal an error for invalid or out-of-range values.
14 * dired.c (Ffile_attributes): Use INTEGER_TO_CONS.
15 * fileio.c (Fset_visited_file_modtime): Use CONS_TO_INTEGER.
16 * font.c (Ffont_variation_glyphs):
17 * fontset.c (Finternal_char_font): Use INTEGER_TO_CONS.
18 * lisp.h: Include <intprops.h>.
19 (INTEGER_TO_CONS, CONS_TO_INTEGER): New macros.
20 (cons_to_signed, cons_to_unsigned): New decls.
21 (long_to_cons, cons_to_long): Remove decls.
22 * undo.c (record_first_change): Use INTEGER_TO_CONS.
23 (Fprimitive_undo): Use CONS_TO_INTEGER.
24 * xfns.c (Fx_window_property): Likewise.
25 * xselect.c: Include <limits.h>.
26 (x_own_selection, selection_data_to_lisp_data):
27 Use INTEGER_TO_CONS.
28 (x_handle_selection_request, x_handle_selection_clear)
29 (x_get_foreign_selection, Fx_disown_selection_internal)
30 (Fx_get_atom_name, x_send_client_event): Use CONS_TO_INTEGER.
31 (lisp_data_to_selection_data): Use cons_to_unsigned.
32 (x_fill_property_data): Use cons_to_signed.
33 Report values out of range.
34
35 Check for buffer and string overflow more precisely.
36 * buffer.h (BUF_BYTES_MAX): New macro.
37 * lisp.h (STRING_BYTES_MAX): New macro.
38 * alloc.c (Fmake_string):
39 * character.c (string_escape_byte8):
40 * coding.c (coding_alloc_by_realloc):
41 * doprnt.c (doprnt):
42 * editfns.c (Fformat):
43 * eval.c (verror):
44 Use STRING_BYTES_MAX, not MOST_POSITIVE_FIXNUM,
45 since they may not be the same number.
46 * editfns.c (Finsert_char):
47 * fileio.c (Finsert_file_contents):
48 Likewise for BUF_BYTES_MAX.
49
50 * image.c: Use ptrdiff_t, not int, for sizes.
51 (slurp_file): Switch from int to ptrdiff_t.
52 All uses changed.
53 (slurp_file): Check that file size fits in both size_t (for
54 malloc) and ptrdiff_t (for sanity and safety).
55
56 * fileio.c (Fverify_visited_file_modtime): Avoid time overflow
57 if b->modtime has its maximal value.
58
59 * dired.c (Ffile_attributes): Don't assume EMACS_INT has >32 bits.
60
61 Don't assume time_t can fit into int.
62 * buffer.h (struct buffer.modtime): Now time_t, not int.
63 * fileio.c (Fvisited_file_modtime): No need for time_t cast now.
64 * undo.c (Fprimitive_undo): Use time_t, not int, for time_t value.
65
66 Minor fixes for signed vs unsigned integers.
67 * character.h (MAYBE_UNIFY_CHAR):
68 * charset.c (maybe_unify_char):
69 * keyboard.c (read_char, reorder_modifiers):
70 XINT -> XFASTINT, since the integer must be nonnegative.
71 * ftfont.c (ftfont_spec_pattern):
72 * keymap.c (access_keymap, silly_event_symbol_error):
73 XUINT -> XFASTINT, since the integer must be nonnegative.
74 (Fsingle_key_description, preferred_sequence_p): XUINT -> XINT,
75 since it makes no difference and we prefer signed.
76 * keyboard.c (record_char): Use XUINT when all the neighbors do.
77 (access_keymap): NATNUMP -> INTEGERP, since the integer must be
78 nonnegative.
79
12011-06-06 Stefan Monnier <monnier@iro.umontreal.ca> 802011-06-06 Stefan Monnier <monnier@iro.umontreal.ca>
2 81
3 * window.h (Fwindow_frame): Declare. 82 * window.h (Fwindow_frame): Declare.
diff --git a/src/alloc.c b/src/alloc.c
index 453286836fd..cfbb79b2e61 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2204,7 +2204,7 @@ INIT must be an integer that represents a character. */)
2204 int len = CHAR_STRING (c, str); 2204 int len = CHAR_STRING (c, str);
2205 EMACS_INT string_len = XINT (length); 2205 EMACS_INT string_len = XINT (length);
2206 2206
2207 if (string_len > MOST_POSITIVE_FIXNUM / len) 2207 if (string_len > STRING_BYTES_MAX / len)
2208 string_overflow (); 2208 string_overflow ();
2209 nbytes = len * string_len; 2209 nbytes = len * string_len;
2210 val = make_uninit_multibyte_string (string_len, nbytes); 2210 val = make_uninit_multibyte_string (string_len, nbytes);
diff --git a/src/buffer.h b/src/buffer.h
index 2f33065cd1a..3c91bdfe570 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -306,6 +306,11 @@ do \
306 } \ 306 } \
307while (0) 307while (0)
308 308
309/* Maximum number of bytes in a buffer.
310 A buffer cannot contain more bytes than a 1-origin fixnum can represent,
311 nor can it be so large that C pointer arithmetic stops working. */
312#define BUF_BYTES_MAX min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX))
313
309/* Return the address of byte position N in current buffer. */ 314/* Return the address of byte position N in current buffer. */
310 315
311#define BYTE_POS_ADDR(n) \ 316#define BYTE_POS_ADDR(n) \
@@ -545,7 +550,7 @@ struct buffer
545 -1 means visited file was nonexistent. 550 -1 means visited file was nonexistent.
546 0 means visited file modtime unknown; in no case complain 551 0 means visited file modtime unknown; in no case complain
547 about any mismatch on next save attempt. */ 552 about any mismatch on next save attempt. */
548 int modtime; 553 time_t modtime;
549 /* Size of the file when modtime was set. This is used to detect the 554 /* Size of the file when modtime was set. This is used to detect the
550 case where the file grew while we were reading it, so the modtime 555 case where the file grew while we were reading it, so the modtime
551 is still the same (since it's rounded up to seconds) but we're actually 556 is still the same (since it's rounded up to seconds) but we're actually
diff --git a/src/character.c b/src/character.c
index 34e69da9cc5..170952619e7 100644
--- a/src/character.c
+++ b/src/character.c
@@ -838,7 +838,7 @@ string_escape_byte8 (Lisp_Object string)
838 if (multibyte) 838 if (multibyte)
839 { 839 {
840 if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count 840 if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count
841 || (MOST_POSITIVE_FIXNUM - nbytes) / 2 < byte8_count) 841 || (STRING_BYTES_MAX - nbytes) / 2 < byte8_count)
842 string_overflow (); 842 string_overflow ();
843 843
844 /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ 844 /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */
@@ -847,7 +847,7 @@ string_escape_byte8 (Lisp_Object string)
847 } 847 }
848 else 848 else
849 { 849 {
850 if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count) 850 if ((STRING_BYTES_MAX - nchars) / 3 < byte8_count)
851 string_overflow (); 851 string_overflow ();
852 852
853 /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ 853 /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */
diff --git a/src/character.h b/src/character.h
index 31e3b0a9416..884833775de 100644
--- a/src/character.h
+++ b/src/character.h
@@ -544,7 +544,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
544 Lisp_Object val; \ 544 Lisp_Object val; \
545 val = CHAR_TABLE_REF (Vchar_unify_table, c); \ 545 val = CHAR_TABLE_REF (Vchar_unify_table, c); \
546 if (INTEGERP (val)) \ 546 if (INTEGERP (val)) \
547 c = XINT (val); \ 547 c = XFASTINT (val); \
548 else if (! NILP (val)) \ 548 else if (! NILP (val)) \
549 c = maybe_unify_char (c, val); \ 549 c = maybe_unify_char (c, val); \
550 } \ 550 } \
diff --git a/src/charset.c b/src/charset.c
index 0af21b48ad2..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),
@@ -1637,7 +1619,7 @@ maybe_unify_char (int c, Lisp_Object val)
1637 struct charset *charset; 1619 struct charset *charset;
1638 1620
1639 if (INTEGERP (val)) 1621 if (INTEGERP (val))
1640 return XINT (val); 1622 return XFASTINT (val);
1641 if (NILP (val)) 1623 if (NILP (val))
1642 return c; 1624 return c;
1643 1625
@@ -1647,7 +1629,7 @@ maybe_unify_char (int c, Lisp_Object val)
1647 { 1629 {
1648 val = CHAR_TABLE_REF (Vchar_unify_table, c); 1630 val = CHAR_TABLE_REF (Vchar_unify_table, c);
1649 if (! NILP (val)) 1631 if (! NILP (val))
1650 c = XINT (val); 1632 c = XFASTINT (val);
1651 } 1633 }
1652 else 1634 else
1653 { 1635 {
@@ -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/coding.c b/src/coding.c
index 6ccaf354c74..64e8e41a5a1 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -1071,8 +1071,8 @@ coding_set_destination (struct coding_system *coding)
1071static void 1071static void
1072coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes) 1072coding_alloc_by_realloc (struct coding_system *coding, EMACS_INT bytes)
1073{ 1073{
1074 if (coding->dst_bytes >= MOST_POSITIVE_FIXNUM - bytes) 1074 if (STRING_BYTES_MAX - coding->dst_bytes < bytes)
1075 error ("Maximum size of buffer or string exceeded"); 1075 string_overflow ();
1076 coding->destination = (unsigned char *) xrealloc (coding->destination, 1076 coding->destination = (unsigned char *) xrealloc (coding->destination,
1077 coding->dst_bytes + bytes); 1077 coding->dst_bytes + bytes);
1078 coding->dst_bytes += bytes; 1078 coding->dst_bytes += bytes;
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. */
2332uintmax_t
2333cons_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
2333Lisp_Object 2377 if (! (valid && val <= max))
2334long_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
2345unsigned long 2382/* Convert the cons-of-integers, integer, or float value C to a signed
2346cons_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. */
2385intmax_t
2386cons_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
2358DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, 2435DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
diff --git a/src/dired.c b/src/dired.c
index 60d7bc64974..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.
90310. inode number. If inode number is larger than what Emacs integer 90310. 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.
90911. Filesystem device number. If it is larger than what the Emacs 90811. 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,35 +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 EMACS_INT low_ino = s.st_ino & 0xffffffff;
1017
1018 values[10] = Fcons (make_number (high_ino >> 8),
1019 Fcons (make_number (((high_ino & 0xff) << 16)
1020 + (low_ino >> 16)),
1021 make_number (low_ino & 0xffff)));
1022 }
1023
1024 /* Likewise for device. */
1025 if (FIXNUM_OVERFLOW_P (s.st_dev))
1026 values[11] = Fcons (make_number (s.st_dev >> 16),
1027 make_number (s.st_dev & 0xffff));
1028 else
1029 values[11] = make_number (s.st_dev);
1030 1002
1031 return Flist (sizeof(values) / sizeof(values[0]), values); 1003 return Flist (sizeof(values) / sizeof(values[0]), values);
1032} 1004}
diff --git a/src/doprnt.c b/src/doprnt.c
index d2abc119912..5ca3ea89be6 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -329,7 +329,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
329 minlen = atoi (&fmtcpy[1]); 329 minlen = atoi (&fmtcpy[1]);
330 string = va_arg (ap, char *); 330 string = va_arg (ap, char *);
331 tem = strlen (string); 331 tem = strlen (string);
332 if (tem > MOST_POSITIVE_FIXNUM) 332 if (tem > STRING_BYTES_MAX)
333 error ("String for %%s or %%S format is too long"); 333 error ("String for %%s or %%S format is too long");
334 width = strwidth (string, tem); 334 width = strwidth (string, tem);
335 goto doit1; 335 goto doit1;
@@ -338,7 +338,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
338 doit: 338 doit:
339 /* Coming here means STRING contains ASCII only. */ 339 /* Coming here means STRING contains ASCII only. */
340 tem = strlen (string); 340 tem = strlen (string);
341 if (tem > MOST_POSITIVE_FIXNUM) 341 if (tem > STRING_BYTES_MAX)
342 error ("Format width or precision too large"); 342 error ("Format width or precision too large");
343 width = tem; 343 width = tem;
344 doit1: 344 doit1:
diff --git a/src/editfns.c b/src/editfns.c
index b961e602e4c..b4ce9a1c571 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2342,7 +2342,7 @@ from adjoining text, if those properties are sticky. */)
2342 len = CHAR_STRING (XFASTINT (character), str); 2342 len = CHAR_STRING (XFASTINT (character), str);
2343 else 2343 else
2344 str[0] = XFASTINT (character), len = 1; 2344 str[0] = XFASTINT (character), len = 1;
2345 if (MOST_POSITIVE_FIXNUM / len < XINT (count)) 2345 if (BUF_BYTES_MAX / len < XINT (count))
2346 error ("Maximum buffer size would be exceeded"); 2346 error ("Maximum buffer size would be exceeded");
2347 n = XINT (count) * len; 2347 n = XINT (count) * len;
2348 if (n <= 0) 2348 if (n <= 0)
@@ -3589,7 +3589,7 @@ usage: (format STRING &rest OBJECTS) */)
3589 char initial_buffer[4000]; 3589 char initial_buffer[4000];
3590 char *buf = initial_buffer; 3590 char *buf = initial_buffer;
3591 EMACS_INT bufsize = sizeof initial_buffer; 3591 EMACS_INT bufsize = sizeof initial_buffer;
3592 EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); 3592 EMACS_INT max_bufsize = STRING_BYTES_MAX + 1;
3593 char *p; 3593 char *p;
3594 Lisp_Object buf_save_value IF_LINT (= {0}); 3594 Lisp_Object buf_save_value IF_LINT (= {0});
3595 register char *format, *end, *format_start; 3595 register char *format, *end, *format_start;
diff --git a/src/eval.c b/src/eval.c
index f8bc0a9f6aa..ef5abac17ae 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1994,7 +1994,7 @@ verror (const char *m, va_list ap)
1994{ 1994{
1995 char buf[4000]; 1995 char buf[4000];
1996 size_t size = sizeof buf; 1996 size_t size = sizeof buf;
1997 size_t size_max = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX); 1997 size_t size_max = STRING_BYTES_MAX + 1;
1998 size_t mlen = strlen (m); 1998 size_t mlen = strlen (m);
1999 char *buffer = buf; 1999 char *buffer = buf;
2000 size_t used; 2000 size_t used;
diff --git a/src/fileio.c b/src/fileio.c
index 7e6fd8c82a8..d9bc28d8c37 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3248,7 +3248,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3248 /* Check whether the size is too large or negative, which can happen on a 3248 /* Check whether the size is too large or negative, which can happen on a
3249 platform that allows file sizes greater than the maximum off_t value. */ 3249 platform that allows file sizes greater than the maximum off_t value. */
3250 if (! not_regular 3250 if (! not_regular
3251 && ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM)) 3251 && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX))
3252 error ("Maximum buffer size exceeded"); 3252 error ("Maximum buffer size exceeded");
3253 3253
3254 /* Prevent redisplay optimizations. */ 3254 /* Prevent redisplay optimizations. */
@@ -4960,7 +4960,7 @@ See Info node `(elisp)Modification Time' for more details. */)
4960 if ((st.st_mtime == b->modtime 4960 if ((st.st_mtime == b->modtime
4961 /* If both are positive, accept them if they are off by one second. */ 4961 /* If both are positive, accept them if they are off by one second. */
4962 || (st.st_mtime > 0 && b->modtime > 0 4962 || (st.st_mtime > 0 && b->modtime > 0
4963 && (st.st_mtime == b->modtime + 1 4963 && (st.st_mtime - 1 == b->modtime
4964 || st.st_mtime == b->modtime - 1))) 4964 || st.st_mtime == b->modtime - 1)))
4965 && (st.st_size == b->modtime_size 4965 && (st.st_size == b->modtime_size
4966 || b->modtime_size < 0)) 4966 || b->modtime_size < 0))
@@ -4990,7 +4990,7 @@ See Info node `(elisp)Modification Time' for more details. */)
4990{ 4990{
4991 if (! current_buffer->modtime) 4991 if (! current_buffer->modtime)
4992 return make_number (0); 4992 return make_number (0);
4993 return make_time ((time_t) current_buffer->modtime); 4993 return make_time (current_buffer->modtime);
4994} 4994}
4995 4995
4996DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, 4996DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
@@ -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/ftfont.c b/src/ftfont.c
index 47425e853da..cd8829a3e51 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -815,7 +815,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots
815 goto err; 815 goto err;
816 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) 816 for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
817 if (CHARACTERP (XCAR (chars)) 817 if (CHARACTERP (XCAR (chars))
818 && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) 818 && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars))))
819 goto err; 819 goto err;
820 } 820 }
821 } 821 }
diff --git a/src/image.c b/src/image.c
index 26542bf27e7..a179568cb85 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2112,9 +2112,6 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he
2112 File Handling 2112 File Handling
2113 ***********************************************************************/ 2113 ***********************************************************************/
2114 2114
2115static unsigned char *slurp_file (char *, int *);
2116
2117
2118/* Find image file FILE. Look in data-directory/images, then 2115/* Find image file FILE. Look in data-directory/images, then
2119 x-bitmap-file-path. Value is the encoded full name of the file 2116 x-bitmap-file-path. Value is the encoded full name of the file
2120 found, or nil if not found. */ 2117 found, or nil if not found. */
@@ -2151,7 +2148,7 @@ x_find_image_file (Lisp_Object file)
2151 occurred. *SIZE is set to the size of the file. */ 2148 occurred. *SIZE is set to the size of the file. */
2152 2149
2153static unsigned char * 2150static unsigned char *
2154slurp_file (char *file, int *size) 2151slurp_file (char *file, ptrdiff_t *size)
2155{ 2152{
2156 FILE *fp = NULL; 2153 FILE *fp = NULL;
2157 unsigned char *buf = NULL; 2154 unsigned char *buf = NULL;
@@ -2159,6 +2156,7 @@ slurp_file (char *file, int *size)
2159 2156
2160 if (stat (file, &st) == 0 2157 if (stat (file, &st) == 0
2161 && (fp = fopen (file, "rb")) != NULL 2158 && (fp = fopen (file, "rb")) != NULL
2159 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
2162 && (buf = (unsigned char *) xmalloc (st.st_size), 2160 && (buf = (unsigned char *) xmalloc (st.st_size),
2163 fread (buf, 1, st.st_size, fp) == st.st_size)) 2161 fread (buf, 1, st.st_size, fp) == st.st_size))
2164 { 2162 {
@@ -2814,7 +2812,7 @@ xbm_load (struct frame *f, struct image *img)
2814 { 2812 {
2815 Lisp_Object file; 2813 Lisp_Object file;
2816 unsigned char *contents; 2814 unsigned char *contents;
2817 int size; 2815 ptrdiff_t size;
2818 2816
2819 file = x_find_image_file (file_name); 2817 file = x_find_image_file (file_name);
2820 if (!STRINGP (file)) 2818 if (!STRINGP (file))
@@ -4039,7 +4037,7 @@ xpm_load (struct frame *f,
4039 { 4037 {
4040 Lisp_Object file; 4038 Lisp_Object file;
4041 unsigned char *contents; 4039 unsigned char *contents;
4042 int size; 4040 ptrdiff_t size;
4043 4041
4044 file = x_find_image_file (file_name); 4042 file = x_find_image_file (file_name);
4045 if (!STRINGP (file)) 4043 if (!STRINGP (file))
@@ -5021,6 +5019,7 @@ pbm_read_file (file, size)
5021 5019
5022 if (stat (SDATA (file), &st) == 0 5020 if (stat (SDATA (file), &st) == 0
5023 && (fp = fopen (SDATA (file), "rb")) != NULL 5021 && (fp = fopen (SDATA (file), "rb")) != NULL
5022 && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX)
5024 && (buf = (char *) xmalloc (st.st_size), 5023 && (buf = (char *) xmalloc (st.st_size),
5025 fread (buf, 1, st.st_size, fp) == st.st_size)) 5024 fread (buf, 1, st.st_size, fp) == st.st_size))
5026 { 5025 {
@@ -5055,7 +5054,7 @@ pbm_load (struct frame *f, struct image *img)
5055 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 5054 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5056 unsigned char *contents = NULL; 5055 unsigned char *contents = NULL;
5057 unsigned char *end, *p; 5056 unsigned char *end, *p;
5058 int size; 5057 ptrdiff_t size;
5059 5058
5060 specified_file = image_spec_value (img->spec, QCfile, NULL); 5059 specified_file = image_spec_value (img->spec, QCfile, NULL);
5061 5060
@@ -7869,7 +7868,7 @@ static int svg_image_p (Lisp_Object object);
7869static int svg_load (struct frame *f, struct image *img); 7868static int svg_load (struct frame *f, struct image *img);
7870 7869
7871static int svg_load_image (struct frame *, struct image *, 7870static int svg_load_image (struct frame *, struct image *,
7872 unsigned char *, unsigned int); 7871 unsigned char *, ptrdiff_t);
7873 7872
7874/* The symbol `svg' identifying images of this type. */ 7873/* The symbol `svg' identifying images of this type. */
7875 7874
@@ -8047,7 +8046,7 @@ svg_load (struct frame *f, struct image *img)
8047 { 8046 {
8048 Lisp_Object file; 8047 Lisp_Object file;
8049 unsigned char *contents; 8048 unsigned char *contents;
8050 int size; 8049 ptrdiff_t size;
8051 8050
8052 file = x_find_image_file (file_name); 8051 file = x_find_image_file (file_name);
8053 if (!STRINGP (file)) 8052 if (!STRINGP (file))
@@ -8096,7 +8095,7 @@ static int
8096svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */ 8095svg_load_image (struct frame *f, /* Pointer to emacs frame structure. */
8097 struct image *img, /* Pointer to emacs image structure. */ 8096 struct image *img, /* Pointer to emacs image structure. */
8098 unsigned char *contents, /* String containing the SVG XML data to be parsed. */ 8097 unsigned char *contents, /* String containing the SVG XML data to be parsed. */
8099 unsigned int size) /* Size of data in bytes. */ 8098 ptrdiff_t size) /* Size of data in bytes. */
8100{ 8099{
8101 RsvgHandle *rsvg_handle; 8100 RsvgHandle *rsvg_handle;
8102 RsvgDimensionData dimension_data; 8101 RsvgDimensionData dimension_data;
diff --git a/src/keyboard.c b/src/keyboard.c
index 6eb3773af99..89483972a65 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2395,8 +2395,8 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
2395 2395
2396 c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index)); 2396 c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index));
2397 if (STRINGP (Vexecuting_kbd_macro) 2397 if (STRINGP (Vexecuting_kbd_macro)
2398 && (XINT (c) & 0x80) && (XUINT (c) <= 0xff)) 2398 && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff))
2399 XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80)); 2399 XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
2400 2400
2401 executing_kbd_macro_index++; 2401 executing_kbd_macro_index++;
2402 2402
@@ -3321,7 +3321,7 @@ record_char (Lisp_Object c)
3321 if (INTEGERP (c)) 3321 if (INTEGERP (c))
3322 { 3322 {
3323 if (XUINT (c) < 0x100) 3323 if (XUINT (c) < 0x100)
3324 putc (XINT (c), dribble); 3324 putc (XUINT (c), dribble);
3325 else 3325 else
3326 fprintf (dribble, " 0x%"pI"x", XUINT (c)); 3326 fprintf (dribble, " 0x%"pI"x", XUINT (c));
3327 } 3327 }
@@ -6370,7 +6370,7 @@ reorder_modifiers (Lisp_Object symbol)
6370 Lisp_Object parsed; 6370 Lisp_Object parsed;
6371 6371
6372 parsed = parse_modifiers (symbol); 6372 parsed = parse_modifiers (symbol);
6373 return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))), 6373 return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))),
6374 XCAR (parsed)); 6374 XCAR (parsed));
6375} 6375}
6376 6376
diff --git a/src/keymap.c b/src/keymap.c
index 79481833bde..6ef2a716b6d 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -462,7 +462,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
462 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); 462 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
463 463
464 /* Handle the special meta -> esc mapping. */ 464 /* Handle the special meta -> esc mapping. */
465 if (INTEGERP (idx) && XUINT (idx) & meta_modifier) 465 if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier)
466 { 466 {
467 /* See if there is a meta-map. If there's none, there is 467 /* See if there is a meta-map. If there's none, there is
468 no binding for IDX, unless a default binding exists in MAP. */ 468 no binding for IDX, unless a default binding exists in MAP. */
@@ -480,7 +480,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
480 if (CONSP (event_meta_map)) 480 if (CONSP (event_meta_map))
481 { 481 {
482 map = event_meta_map; 482 map = event_meta_map;
483 idx = make_number (XUINT (idx) & ~meta_modifier); 483 idx = make_number (XFASTINT (idx) & ~meta_modifier);
484 } 484 }
485 else if (t_ok) 485 else if (t_ok)
486 /* Set IDX to t, so that we only find a default binding. */ 486 /* Set IDX to t, so that we only find a default binding. */
@@ -529,7 +529,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
529 } 529 }
530 else if (VECTORP (binding)) 530 else if (VECTORP (binding))
531 { 531 {
532 if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (binding)) 532 if (INTEGERP (idx) && XFASTINT (idx) < ASIZE (binding))
533 val = AREF (binding, XFASTINT (idx)); 533 val = AREF (binding, XFASTINT (idx));
534 } 534 }
535 else if (CHAR_TABLE_P (binding)) 535 else if (CHAR_TABLE_P (binding))
@@ -537,7 +537,7 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
537 /* Character codes with modifiers 537 /* Character codes with modifiers
538 are not included in a char-table. 538 are not included in a char-table.
539 All character codes without modifiers are included. */ 539 All character codes without modifiers are included. */
540 if (NATNUMP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0) 540 if (INTEGERP (idx) && (XFASTINT (idx) & CHAR_MODIFIER_MASK) == 0)
541 { 541 {
542 val = Faref (binding, idx); 542 val = Faref (binding, idx);
543 /* `nil' has a special meaning for char-tables, so 543 /* `nil' has a special meaning for char-tables, so
@@ -1357,7 +1357,7 @@ silly_event_symbol_error (Lisp_Object c)
1357 int modifiers; 1357 int modifiers;
1358 1358
1359 parsed = parse_modifiers (c); 1359 parsed = parse_modifiers (c);
1360 modifiers = (int) XUINT (XCAR (XCDR (parsed))); 1360 modifiers = XFASTINT (XCAR (XCDR (parsed)));
1361 base = XCAR (parsed); 1361 base = XCAR (parsed);
1362 name = Fsymbol_name (base); 1362 name = Fsymbol_name (base);
1363 /* This alist includes elements such as ("RET" . "\\r"). */ 1363 /* This alist includes elements such as ("RET" . "\\r"). */
@@ -2416,7 +2416,7 @@ around function keys and event symbols. */)
2416 { 2416 {
2417 char tem[KEY_DESCRIPTION_SIZE]; 2417 char tem[KEY_DESCRIPTION_SIZE];
2418 2418
2419 *push_key_description (XUINT (key), tem, 1) = 0; 2419 *push_key_description (XINT (key), tem, 1) = 0;
2420 return build_string (tem); 2420 return build_string (tem);
2421 } 2421 }
2422 else if (SYMBOLP (key)) /* Function key or event-symbol */ 2422 else if (SYMBOLP (key)) /* Function key or event-symbol */
@@ -2515,7 +2515,7 @@ preferred_sequence_p (Lisp_Object seq)
2515 return 0; 2515 return 0;
2516 else 2516 else
2517 { 2517 {
2518 int modifiers = XUINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META); 2518 int modifiers = XINT (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
2519 if (modifiers == where_is_preferred_modifier) 2519 if (modifiers == where_is_preferred_modifier)
2520 result = 2; 2520 result = 2;
2521 else if (modifiers) 2521 else if (modifiers)
diff --git a/src/lisp.h b/src/lisp.h
index 7145c1a689b..c5f810a0746 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
@@ -763,6 +765,12 @@ extern EMACS_INT string_bytes (struct Lisp_String *);
763 765
764#endif /* not GC_CHECK_STRING_BYTES */ 766#endif /* not GC_CHECK_STRING_BYTES */
765 767
768/* A string cannot contain more bytes than a fixnum can represent,
769 nor can it be so long that C pointer arithmetic stops working on
770 the string plus a terminating null. */
771#define STRING_BYTES_MAX \
772 min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)
773
766/* Mark STR as a unibyte string. */ 774/* Mark STR as a unibyte string. */
767#define STRING_SET_UNIBYTE(STR) \ 775#define STRING_SET_UNIBYTE(STR) \
768 do { if (EQ (STR, empty_multibyte_string)) \ 776 do { if (EQ (STR, empty_multibyte_string)) \
@@ -2402,9 +2410,35 @@ EXFUN (Fadd1, 1);
2402EXFUN (Fsub1, 1); 2410EXFUN (Fsub1, 1);
2403EXFUN (Fmake_variable_buffer_local, 1); 2411EXFUN (Fmake_variable_buffer_local, 1);
2404 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))))
2438extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t);
2439extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t);
2440
2405extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); 2441extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
2406extern Lisp_Object long_to_cons (unsigned long);
2407extern unsigned long cons_to_long (Lisp_Object);
2408extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; 2442extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN;
2409extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, 2443extern void args_out_of_range_3 (Lisp_Object, Lisp_Object,
2410 Lisp_Object) NO_RETURN; 2444 Lisp_Object) NO_RETURN;
diff --git a/src/undo.c b/src/undo.c
index 80aff50d18a..e7e9ae5632e 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -212,7 +212,6 @@ record_change (EMACS_INT beg, EMACS_INT length)
212void 212void
213record_first_change (void) 213record_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 int 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