aboutsummaryrefslogtreecommitdiffstats
path: root/src/dired.c
diff options
context:
space:
mode:
authorPaul Eggert2011-06-06 01:29:01 -0700
committerPaul Eggert2011-06-06 01:29:01 -0700
commitbe44ca6cd47bff4cb0dfcfd71aa14f10fdab5434 (patch)
tree34110ed6783c1314604f3382e8cd6d0812b939e3 /src/dired.c
parentd1f3d2afe1057a99b9dec6d1bd5b57bfee81fdff (diff)
downloademacs-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.
Diffstat (limited to 'src/dired.c')
-rw-r--r--src/dired.c39
1 files changed, 6 insertions, 33 deletions
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}