aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog30
-rw-r--r--src/charset.c38
-rw-r--r--src/composite.h16
-rw-r--r--src/data.c121
-rw-r--r--src/dired.c39
-rw-r--r--src/fileio.c2
-rw-r--r--src/font.c10
-rw-r--r--src/fontset.c8
-rw-r--r--src/lisp.h32
-rw-r--r--src/undo.c15
-rw-r--r--src/xfns.c15
-rw-r--r--src/xselect.c88
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 @@
12011-06-06 Paul Eggert <eggert@cs.ucla.edu> 12011-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. */
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 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.
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,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);
2408EXFUN (Fsub1, 1); 2410EXFUN (Fsub1, 1);
2409EXFUN (Fmake_variable_buffer_local, 1); 2411EXFUN (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))))
2438extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t);
2439extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t);
2440
2411extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); 2441extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
2412extern Lisp_Object long_to_cons (unsigned long);
2413extern unsigned long cons_to_long (Lisp_Object);
2414extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; 2442extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN;
2415extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, 2443extern 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)
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 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