aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert <[email protected]>2011-07-27 17:48:01 -0700
committerPaul Eggert <[email protected]>2011-07-27 17:48:01 -0700
commit044c22e545acef592ed95e4e3bb9f8aeff67291a (patch)
tree167a4c706b62b12ea979bdf6ad47e70b66bb0394
parentdbf38e02c9ade4979418f24a99962cfef170b957 (diff)
parent8265d3bb30544e58683fc16e23f9908f3d5d0abc (diff)
Merge: Integer signedness and overflow and related fixes.
Fixes: debbugs:9079
-rw-r--r--ChangeLog15
-rw-r--r--configure.in21
-rw-r--r--lib-src/ChangeLog13
-rw-r--r--lib-src/ebrowse.c4
-rw-r--r--lib-src/etags.c34
-rw-r--r--lib-src/makefile.w32-in2
-rw-r--r--lib-src/movemail.c2
-rw-r--r--lib-src/pop.c2
-rw-r--r--lib-src/update-game-score.c7
-rw-r--r--nt/ChangeLog7
-rw-r--r--nt/config.nt8
-rw-r--r--src/ChangeLog199
-rw-r--r--src/alloc.c147
-rw-r--r--src/bidi.c51
-rw-r--r--src/buffer.c8
-rw-r--r--src/callint.c2
-rw-r--r--src/data.c3
-rw-r--r--src/dispnew.c67
-rw-r--r--src/doprnt.c23
-rw-r--r--src/editfns.c40
-rw-r--r--src/emacs.c8
-rw-r--r--src/eval.c10
-rw-r--r--src/fileio.c6
-rw-r--r--src/filelock.c15
-rw-r--r--src/floatfns.c3
-rw-r--r--src/fns.c26
-rw-r--r--src/gmalloc.c158
-rw-r--r--src/gtkutil.c6
-rw-r--r--src/image.c230
-rw-r--r--src/keyboard.c4
-rw-r--r--src/keyboard.h4
-rw-r--r--src/lisp.h37
-rw-r--r--src/lread.c19
-rw-r--r--src/print.c3
-rw-r--r--src/regex.c69
-rw-r--r--src/s/aix4-2.h5
-rw-r--r--src/s/ms-w32.h5
-rw-r--r--src/sysdep.c55
-rw-r--r--src/xdisp.c8
-rw-r--r--src/xfaces.c10
-rw-r--r--src/xselect.c7
-rw-r--r--src/xterm.h4
42 files changed, 652 insertions, 695 deletions
diff --git a/ChangeLog b/ChangeLog
index 669a1edcda..7b084d7162 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2011-07-28 Paul Eggert <[email protected]>
+
+ Assume freestanding C89 headers, string.h, stdlib.h.
+ Again, this simplifies the code, and all current platforms have these.
+ * configure.in (AC_CHECK_HEADERS): Don't check for limits.h.
+ (AC_HEADER_STDC): Remove.
+ (AC_CHECK_FUNCS): No need to check for strchr, strrchr.
+ (strchr, strrchr): Remove fallback macros.
+
+ Assume support for memcmp, memcpy, memmove, memset.
+ This simplifies the code a bit. All current platforms have these,
+ as they are required for C89. If this turns into a problem we
+ can add the gnulib modules for these (a 1-line change to Makefile.in).
+ * configure.in: Don't check for memcmp, memcpy, memmove, memset.
+
2011-07-27 Paul Eggert <[email protected]>
* GNUmakefile: New file.
diff --git a/configure.in b/configure.in
index f88506fbb2..04a123d3e8 100644
--- a/configure.in
+++ b/configure.in
@@ -1093,7 +1093,7 @@ if test "x$crt_files" != x; then
dnl first there is no point asking gcc.
crt_gcc=no
- test -e $CRT_DIR/$file || crt_missing="$crt_missing $file"
+ test -e $CRT_DIR/$file || crt_missing="$crt_missing $file"
done # $crt_files
test "x$crt_missing" = x || \
@@ -1213,7 +1213,7 @@ fi
dnl checks for header files
AC_CHECK_HEADERS(sys/select.h sys/time.h unistd.h utime.h \
- linux/version.h sys/systeminfo.h limits.h \
+ linux/version.h sys/systeminfo.h \
stdio_ext.h fcntl.h coff.h pty.h sys/mman.h \
sys/vlimit.h sys/resource.h locale.h sys/_mbstate_t.h \
sys/utsname.h pwd.h utmp.h dirent.h util.h)
@@ -1232,7 +1232,6 @@ fi
dnl On Solaris 8 there's a compilation warning for term.h because
dnl it doesn't define `bool'.
AC_CHECK_HEADERS(term.h, , , -)
-AC_HEADER_STDC
AC_HEADER_TIME
AC_CHECK_DECLS([sys_siglist])
if test $ac_cv_have_decl_sys_siglist != yes; then
@@ -2704,10 +2703,10 @@ rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \
random lrand48 logb frexp fmod rint cbrt ftime setsid \
strerror fpathconf select euidaccess getpagesize tzset setlocale \
utimes getrlimit setrlimit setpgid getcwd getwd shutdown getaddrinfo \
-__fpending mblen mbrlen mbsinit strsignal setitimer ualarm strchr strrchr \
+__fpending mblen mbrlen mbsinit strsignal setitimer ualarm \
sendto recvfrom getsockopt setsockopt getsockname getpeername \
-gai_strerror mkstemp getline getdelim mremap memmove fsync sync \
-memset memcmp difftime memcpy mempcpy mblen mbrlen posix_memalign \
+gai_strerror mkstemp getline getdelim mremap fsync sync \
+difftime mempcpy mblen mbrlen posix_memalign \
cfmakeraw cfsetspeed isnan copysign __executable_start)
dnl Cannot use AC_CHECK_FUNCS
@@ -3106,8 +3105,6 @@ dnl and macros for terminal control.])
dnl AC_DEFINE(HAVE_TCATTR, 1, [Define to 1 if you have tcgetattr and tcsetattr.])
dnl fi
-dnl Fixme: Use AC_FUNC_MEMCMP since memcmp is used. (Needs libobj replacement.)
-
# Set up the CFLAGS for real compilation, so we can substitute it.
CFLAGS="$REAL_CFLAGS"
CPPFLAGS="$REAL_CPPFLAGS"
@@ -3585,14 +3582,6 @@ AH_BOTTOM([
#include <string.h>
#include <stdlib.h>
-#ifndef HAVE_STRCHR
-#define strchr(a, b) index (a, b)
-#endif
-
-#ifndef HAVE_STRRCHR
-#define strrchr(a, b) rindex (a, b)
-#endif
-
#if defined __GNUC__ && (__GNUC__ > 2 \
|| (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
#define NO_RETURN __attribute__ ((__noreturn__))
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 2a4c102429..c878d313b7 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,16 @@
+2011-07-28 Paul Eggert <[email protected]>
+
+ Assume freestanding C89 headers, string.h, stdlib.h.
+ * ebrowse.c: Include stdlib.h unconditionally.
+ * etags.c, update-game-score.c:
+ Include string.h and stdlib.h unconditionally.
+ * makefile.w32-in (LOCAL_CFLAGS): Don't define STDC_HEADERS.
+ * movemail.c, pop.c: Include string.h unconditionally.
+ * update-game-score.c: No need to include stdarg.h; not used.
+
+ Assume support for memcmp, memcpy, memmove, memset.
+ * etags.c (absolute_filename): Assume memmove exists.
+
2011-07-09 Andreas Schwab <[email protected]>
* update-game-score.c (usage): Update usage line.
diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c
index 7871a80499..a997e56cc9 100644
--- a/lib-src/ebrowse.c
+++ b/lib-src/ebrowse.c
@@ -20,11 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
-
#include <string.h>
#include <ctype.h>
#include <assert.h>
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 693c999047..522c54ee4a 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -138,9 +138,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
#endif /* MSDOS */
#ifdef WINDOWSNT
-# include <stdlib.h>
# include <fcntl.h>
-# include <string.h>
# include <direct.h>
# include <io.h>
# define MAXPATHLEN _MAX_PATH
@@ -151,27 +149,6 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
# define HAVE_GETCWD
# endif /* undef HAVE_GETCWD */
#else /* not WINDOWSNT */
-# ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-# else /* no standard C headers */
- extern char *getenv (const char *);
- extern char *strcpy (char *, const char *);
- extern char *strncpy (char *, const char *, unsigned long);
- extern char *strcat (char *, const char *);
- extern char *strncat (char *, const char *, unsigned long);
- extern int strcmp (const char *, const char *);
- extern int strncmp (const char *, const char *, unsigned long);
- extern int system (const char *);
- extern unsigned long strlen (const char *);
- extern void *malloc (unsigned long);
- extern void *realloc (void *, unsigned long);
- extern void exit (int);
- extern void free (void *);
- extern void *memmove (void *, const void *, unsigned long);
-# define EXIT_SUCCESS 0
-# define EXIT_FAILURE 1
-# endif
#endif /* !WINDOWSNT */
#include <unistd.h>
@@ -181,6 +158,8 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
# endif
#endif /* HAVE_UNISTD_H */
+#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
@@ -6567,22 +6546,13 @@ absolute_filename (char *file, char *dir)
else if (cp[0] != '/')
cp = slashp;
#endif
-#ifdef HAVE_MEMMOVE
memmove (cp, slashp + 3, strlen (slashp + 2));
-#else
- /* Overlapping copy isn't really okay */
- strcpy (cp, slashp + 3);
-#endif
slashp = cp;
continue;
}
else if (slashp[2] == '/' || slashp[2] == '\0')
{
-#ifdef HAVE_MEMMOVE
memmove (slashp, slashp + 2, strlen (slashp + 1));
-#else
- strcpy (slashp, slashp + 2);
-#endif
continue;
}
}
diff --git a/lib-src/makefile.w32-in b/lib-src/makefile.w32-in
index 07f6170afe..28f913a4df 100644
--- a/lib-src/makefile.w32-in
+++ b/lib-src/makefile.w32-in
@@ -21,7 +21,7 @@ ALL = make-docfile hexl ctags etags movemail ebrowse emacsclient
.PHONY: $(ALL)
-LOCAL_FLAGS = -DWINDOWSNT -DDOS_NT -DSTDC_HEADERS=1 -DNO_LDAV=1 \
+LOCAL_FLAGS = -DWINDOWSNT -DDOS_NT -DNO_LDAV=1 \
-DNO_ARCHIVES=1 -DHAVE_CONFIG_H=1 -I../lib \
-I../nt/inc -I../src
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index e8c09f090f..d70c655ade 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -68,9 +68,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#ifdef HAVE_STRING_H
#include <string.h>
-#endif
#include "syswait.h"
#ifdef MAIL_USE_POP
#include "pop.h"
diff --git a/lib-src/pop.c b/lib-src/pop.c
index 426b39bd1f..a94e06fbd8 100644
--- a/lib-src/pop.c
+++ b/lib-src/pop.c
@@ -65,9 +65,7 @@ extern struct servent *hes_getservbyname (/* char *, char * */);
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
-#ifdef STDC_HEADERS
#include <string.h>
-#endif
#include <unistd.h>
#ifdef KERBEROS
diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c
index 76483c371f..2a89379aef 100644
--- a/lib-src/update-game-score.c
+++ b/lib-src/update-game-score.c
@@ -35,12 +35,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <errno.h>
-#ifdef HAVE_STRING_H
#include <string.h>
-#endif
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
#include <stdio.h>
#include <time.h>
#include <pwd.h>
@@ -48,9 +44,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#ifdef STDC_HEADERS
-#include <stdarg.h>
-#endif
#include <sys/stat.h>
/* Needed for SunOS4, for instance. */
diff --git a/nt/ChangeLog b/nt/ChangeLog
index 087f006b88..edbd1a1c1d 100644
--- a/nt/ChangeLog
+++ b/nt/ChangeLog
@@ -1,3 +1,10 @@
+2011-07-28 Paul Eggert <[email protected]>
+
+ Assume freestanding C89 headers, string.h, stdlib.h.
+ * config.nt (HAVE_LIMITS_H, HAVE_STRING_H, HAVE_STDLIB_H)
+ (STDC_HEADERS): Remove.
+ Iinclude string.h, stdlib.h unconditionally.
+
2011-06-07 Eli Zaretskii <[email protected]>
* inc/stdint.h (INT32_MAX, INT64_MAX, INTPTR_MAX, PTRDIFF_MAX)
diff --git a/nt/config.nt b/nt/config.nt
index 2ba76df444..3436bc989e 100644
--- a/nt/config.nt
+++ b/nt/config.nt
@@ -131,12 +131,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef HAVE_LINUX_VERSION_H
#undef HAVE_SYS_SYSTEMINFO_H
#undef HAVE_TERMIOS_H
-#undef HAVE_LIMITS_H
-#undef HAVE_STRING_H
#undef HAVE_STRINGS_H
-#undef HAVE_STDLIB_H
#undef HAVE_PWD_H
-#undef STDC_HEADERS
#undef HAVE_LIBDNET
#undef HAVE_LIBPTHREADS
@@ -506,15 +502,11 @@ extern char *getenv ();
#define PROTOTYPES 1
#endif
-#ifdef HAVE_STRING_H
#include "string.h"
-#endif
#ifdef HAVE_STRINGS_H
#include "strings.h"
#endif
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
#ifndef NO_RETURN
#if defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR >= 5))
diff --git a/src/ChangeLog b/src/ChangeLog
index e204ff2040..10f6e32689 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,202 @@
+2011-07-28 Paul Eggert <[email protected]>
+
+ Integer signedness and overflow and related fixes. (Bug#9079)
+
+ * bidi.c: Integer size and overflow fixes.
+ (bidi_cache_size, bidi_cache_idx, bidi_cache_last_idx)
+ (bidi_cache_start, bidi_cache_fetch_state, bidi_cache_search)
+ (bidi_cache_find_level_change, bidi_cache_ensure_space)
+ (bidi_cache_iterator_state, bidi_cache_find, bidi_cache_start_stack)
+ (bidi_find_other_level_edge):
+ Use ptrdiff_t instead of EMACS_INT where either will do.
+ This works better on 32-bit hosts configured --with-wide-int.
+ (bidi_cache_ensure_space): Check for size-calculation overflow.
+ Use % rather than repeated addition, for better worst-case speed.
+ Don't set bidi_cache_size until after xrealloc returns, because it
+ might not return.
+ (bidi_dump_cached_states): Use ptrdiff_t, not int, to avoid overflow.
+ (bidi_cache_ensure_space): Also check that the bidi cache size
+ does not exceed that of the largest Lisp string or buffer. See Eli
+ Zaretskii in <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9079#29>.
+
+ * alloc.c (__malloc_size_t): Remove.
+ All uses replaced by size_t. See Andreas Schwab's note
+ <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9079#8>.
+
+ * image.c: Improve checking for integer overflow.
+ (check_image_size): Assume that f is nonnull, since
+ it is always nonnull in practice. This is one less thing to
+ worry about when checking for integer overflow later.
+ (x_check_image_size): New function, which checks for integer
+ overflow issues inside X.
+ (x_create_x_image_and_pixmap, xbm_read_bitmap_data): Use it.
+ This removes the need for a memory_full check.
+ (xbm_image_p): Rewrite to avoid integer multiplication overflow.
+ (Create_Pixmap_From_Bitmap_Data, xbm_load): Use x_check_image_size.
+ (xbm_read_bitmap_data): Change locals back to 'int', since
+ their values must fit in 'int'.
+ (xpm_load_image, png_load, tiff_load):
+ Invoke x_create_x_image_and_pixmap earlier,
+ to avoid much needless work if the image is too large.
+ (tiff_load): Treat overly large images as if
+ x_create_x_image_and_pixmap failed, not as malloc failures.
+ (gs_load): Use x_check_image_size.
+
+ * gtkutil.c: Omit integer casts.
+ (xg_get_pixbuf_from_pixmap): Remove unnecessary cast.
+ (xg_set_toolkit_scroll_bar_thumb): Rewrite to avoid need for cast.
+
+ * image.c (png_load): Don't assume height * row_bytes fits in 'int'.
+
+ * xfaces.c (Fbitmap_spec_p): Fix integer overflow bug.
+ Without this fix, (bitmap-spec-p '(34359738368 1 "x"))
+ would wrongly return t on a 64-bit host.
+
+ * dispnew.c (init_display): Use *_RANGE_OVERFLOW macros.
+ The plain *_OVERFLOW macros run afoul of GCC bug 49705
+ <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49705>
+ and therefore cause GCC to emit a bogus diagnostic in some cases.
+
+ * image.c: Integer signedness and overflow and related fixes.
+ This is not an exhaustive set of fixes, but it's time to
+ record what I've got.
+ (lookup_pixel_color, check_image_size): Remove redundant decls.
+ (check_image_size): Don't assume that arbitrary EMACS_INT values
+ fit in 'int', or that arbitrary 'double' values fit in 'int'.
+ (x_alloc_image_color, x_create_x_image_and_pixmap, png_load)
+ (tiff_load, imagemagick_load_image):
+ Check for overflow in size calculations.
+ (x_create_x_image_and_pixmap): Remove unnecessary test for
+ xmalloc returning NULL; that can't happen.
+ (xbm_read_bitmap_data): Don't assume sizes fit into 'int'.
+ (xpm_color_bucket): Use better integer hashing function.
+ (xpm_cache_color): Don't possibly over-allocate memory.
+ (struct png_memory_storage, tiff_memory_source, tiff_seek_in_memory)
+ (gif_memory_source):
+ Use ptrdiff_t, not int or size_t, to record sizes.
+ (png_load): Don't assume values greater than 2**31 fit in 'int'.
+ (our_stdio_fill_input_buffer): Prefer ptrdiff_t to size_t when
+ either works, as we prefer signed integers.
+ (tiff_read_from_memory, tiff_write_from_memory):
+ Return tsize_t, not size_t, since that's what the TIFF API wants.
+ (tiff_read_from_memory): Don't fail simply because the read would
+ go past EOF; instead, return a short read.
+ (tiff_load): Omit no-longer-needed casts.
+ (Fimagemagick_types): Don't assume size fits into 'int'.
+
+ Improve hashing quality when configured --with-wide-int.
+ * fns.c (hash_string): New function, taken from sxhash_string.
+ Do not discard information about ASCII character case; this
+ discarding is no longer needed.
+ (sxhash-string): Use it. Change sig to match it. Caller changed.
+ * lisp.h: Declare it.
+ * lread.c (hash_string): Remove, since we now use fns.c's version.
+ The fns.c version returns a wider integer if --with-wide-int is
+ specified, so this should help the quality of the hashing a bit.
+
+ * emacs.c: Integer overflow minor fix.
+ (heap_bss_diff): Now uprintmax_t, not unsigned long. All used changed.
+ Define only if GNU_LINUX.
+ (main, Fdump_emacs): Set and use heap_bss_diff only if GNU_LINUX.
+
+ * dispnew.c: Integer signedness and overflow fixes.
+ Remove unnecessary forward decls, that were a maintenance hassle.
+ (history_tick): Now uprintmax_t, so it's more likely to avoid overflow.
+ All uses changed.
+ (adjust_glyph_matrix, realloc_glyph_pool, adjust_frame_message_buffer)
+ (scrolling_window): Use ptrdiff_t, not int, for byte count.
+ (prepare_desired_row, line_draw_cost):
+ Use int, not unsigned, where either works.
+ (save_current_matrix, restore_current_matrix):
+ Use ptrdiff_t, not size_t, where either works.
+ (init_display): Check for overflow more accurately, and without
+ relying on undefined behavior.
+
+ * editfns.c (pWIDE, pWIDElen, signed_wide, unsigned_wide):
+ Remove, replacing with the new symbols in lisp.h. All uses changed.
+ * fileio.c (make_temp_name):
+ * filelock.c (lock_file_1, lock_file):
+ * xdisp.c (message_dolog):
+ Don't assume PRIdMAX etc. works; this isn't portable to pre-C99 hosts.
+ Use pMd etc. instead.
+ * lisp.h (printmax_t, uprintmax_t, pMd, pMu): New types and macros,
+ replacing the pWIDE etc. symbols removed from editfns.c.
+
+ * keyboard.h (num_input_events): Now uintmax_t.
+ This is (very slightly) less likely to mess up due to wraparound.
+ All uses changed.
+
+ * buffer.c: Integer signedness fixes.
+ (alloc_buffer_text, enlarge_buffer_text):
+ Use ptrdiff_t rather than size_t when either will do, as we prefer
+ signed integers.
+
+ * alloc.c: Integer signedness and overflow fixes.
+ Do not impose an arbitrary 32-bit limit on malloc sizes when debugging.
+ (__malloc_size_t): Default to size_t, not to int.
+ (pure_size, pure_bytes_used_before_overflow, stack_copy_size)
+ (Fgarbage_collect, mark_object_loop_halt, mark_object):
+ Prefer ptrdiff_t to size_t when either would do, as we prefer
+ signed integers.
+ (XMALLOC_OVERRUN_CHECK_OVERHEAD): New macro.
+ (xmalloc_overrun_check_header, xmalloc_overrun_check_trailer):
+ Now const. Initialize with values that are in range even if char
+ is signed.
+ (XMALLOC_PUT_SIZE, XMALLOC_GET_SIZE): Remove, replacing with ...
+ (xmalloc_put_size, xmalloc_get_size): New functions. All uses changed.
+ These functions do the right thing with sizes > 2**32.
+ (check_depth): Now ptrdiff_t, not int.
+ (overrun_check_malloc, overrun_check_realloc, overrun_check_free):
+ Adjust to new way of storing sizes. Check for size overflow bugs
+ in rest of code.
+ (STRING_BYTES_MAX): Adjust to new overheads. The old code was
+ slightly wrong anyway, as it missed one instance of
+ XMALLOC_OVERRUN_CHECK_OVERHEAD.
+ (refill_memory_reserve): Omit needless cast to size_t.
+ (mark_object_loop_halt): Mark as externally visible.
+
+ * xselect.c: Integer signedness and overflow fixes.
+ (Fx_register_dnd_atom, x_handle_dnd_message):
+ Use ptrdiff_t, not size_t, since we prefer signed.
+ (Fx_register_dnd_atom): Check for ptrdiff_t (and size_t) overflow.
+ * xterm.h (struct x_display_info): Use ptrdiff_t, not size_t, for
+ x_dnd_atoms_size and x_dnd_atoms_length.
+
+ * doprnt.c: Prefer signed to unsigned when either works.
+ * eval.c (verror):
+ * doprnt.c (doprnt):
+ * lisp.h (doprnt):
+ * xdisp.c (vmessage):
+ Use ptrdiff_t, not size_t, when using or implementing doprnt,
+ since the sizes cannot exceed ptrdiff_t bounds anyway, and we
+ prefer signed arithmetic to avoid comparison confusion.
+ * doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
+ but is a bit tricky.
+
+ Assume freestanding C89 headers, string.h, stdlib.h.
+ * data.c, doprnt.c, floatfns.c, print.c:
+ Include float.h unconditionally.
+ * gmalloc.c: Assume C89-at-least behavior for preprocessor,
+ limits.h, stddef.h, string.h. Use memset instead of 'flood'.
+ * regex.c: Likewise for stddef.h, string.h.
+ (ISASCII): Remove; can assume it returns 1 now. All uses removed.
+ * s/aix4-2.h (HAVE_STRING_H): Remove obsolete undef.
+ * s/ms-w32.h (HAVE_LIMITS_H, HAVE_STRING_H, HAVE_STDLIB_H)
+ (STDC_HEADERS): Remove obsolete defines.
+ * sysdep.c: Include limits.h unconditionally.
+
+ Assume support for memcmp, memcpy, memmove, memset.
+ * lisp.h, sysdep.c (memcmp, memcpy, memmove, memset):
+ * regex.c (memcmp, memcpy):
+ Remove; we assume C89 now.
+
+ * gmalloc.c (memcpy, memset, memmove): Remove; we assume C89 now.
+ (__malloc_safe_bcopy): Remove; no longer needed.
+
+ * lisp.h (struct vectorlike_header, struct Lisp_Subr): Signed sizes.
+ Use EMACS_INT, not EMACS_UINT, for sizes. The code works equally
+ well either way, and we prefer signed to unsigned.
+
2011-07-27 Lars Magne Ingebrigtsen <[email protected]>
* gnutls.c (emacs_gnutls_read): Don't message anything if the peer
diff --git a/src/alloc.c b/src/alloc.c
index d48d1f34db..eb0185a8e3 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -68,10 +68,6 @@ extern POINTER_TYPE *sbrk ();
#ifdef DOUG_LEA_MALLOC
#include <malloc.h>
-/* malloc.h #defines this as size_t, at least in glibc2. */
-#ifndef __malloc_size_t
-#define __malloc_size_t int
-#endif
/* Specify maximum number of areas to mmap. It would be nice to use a
value that explicitly means "no limit". */
@@ -82,9 +78,8 @@ extern POINTER_TYPE *sbrk ();
/* The following come from gmalloc.c. */
-#define __malloc_size_t size_t
-extern __malloc_size_t _bytes_used;
-extern __malloc_size_t __malloc_extra_blocks;
+extern size_t _bytes_used;
+extern size_t __malloc_extra_blocks;
#endif /* not DOUG_LEA_MALLOC */
@@ -214,12 +209,12 @@ EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,};
/* Pointer to the pure area, and its size. */
static char *purebeg;
-static size_t pure_size;
+static ptrdiff_t pure_size;
/* Number of bytes of pure storage used before pure storage overflowed.
If this is non-zero, this implies that an overflow occurred. */
-static size_t pure_bytes_used_before_overflow;
+static ptrdiff_t pure_bytes_used_before_overflow;
/* Value is non-zero if P points into pure space. */
@@ -252,7 +247,7 @@ const char *pending_malloc_warning;
#if MAX_SAVE_STACK > 0
static char *stack_copy;
-static size_t stack_copy_size;
+static ptrdiff_t stack_copy_size;
#endif
/* Non-zero means ignore malloc warnings. Set during initialization.
@@ -486,14 +481,15 @@ buffer_memory_full (EMACS_INT nbytes)
#ifndef XMALLOC_OVERRUN_CHECK
-#define XMALLOC_OVERRUN_CHECK_SIZE 0
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
#else
-/* Check for overrun in malloc'ed buffers by wrapping a 16 byte header
- and a 16 byte trailer around each block.
+/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
+ around each block.
- The header consists of 12 fixed bytes + a 4 byte integer contaning the
- original block size, while the trailer consists of 16 fixed bytes.
+ The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
+ containing the original block size in little-endian order,
+ while the trailer consists of 16 fixed bytes.
The header is used to detect whether this block has been allocated
through these functions -- as it seems that some low-level libc
@@ -502,31 +498,47 @@ buffer_memory_full (EMACS_INT nbytes)
#define XMALLOC_OVERRUN_CHECK_SIZE 16
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
+ (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t))
-static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] =
- { 0x9a, 0x9b, 0xae, 0xaf,
- 0xbf, 0xbe, 0xce, 0xcf,
- 0xea, 0xeb, 0xec, 0xed };
+static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
+ { '\x9a', '\x9b', '\xae', '\xaf',
+ '\xbf', '\xbe', '\xce', '\xcf',
+ '\xea', '\xeb', '\xec', '\xed',
+ '\xdf', '\xde', '\x9c', '\x9d' };
-static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
- { 0xaa, 0xab, 0xac, 0xad,
- 0xba, 0xbb, 0xbc, 0xbd,
- 0xca, 0xcb, 0xcc, 0xcd,
- 0xda, 0xdb, 0xdc, 0xdd };
+static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
+ { '\xaa', '\xab', '\xac', '\xad',
+ '\xba', '\xbb', '\xbc', '\xbd',
+ '\xca', '\xcb', '\xcc', '\xcd',
+ '\xda', '\xdb', '\xdc', '\xdd' };
-/* Macros to insert and extract the block size in the header. */
+/* Insert and extract the block size in the header. */
-#define XMALLOC_PUT_SIZE(ptr, size) \
- (ptr[-1] = (size & 0xff), \
- ptr[-2] = ((size >> 8) & 0xff), \
- ptr[-3] = ((size >> 16) & 0xff), \
- ptr[-4] = ((size >> 24) & 0xff))
+static void
+xmalloc_put_size (unsigned char *ptr, size_t size)
+{
+ int i;
+ for (i = 0; i < sizeof (size_t); i++)
+ {
+ *--ptr = size & (1 << CHAR_BIT) - 1;
+ size >>= CHAR_BIT;
+ }
+}
-#define XMALLOC_GET_SIZE(ptr) \
- (size_t)((unsigned)(ptr[-1]) | \
- ((unsigned)(ptr[-2]) << 8) | \
- ((unsigned)(ptr[-3]) << 16) | \
- ((unsigned)(ptr[-4]) << 24))
+static size_t
+xmalloc_get_size (unsigned char *ptr)
+{
+ size_t size = 0;
+ int i;
+ ptr -= sizeof (size_t);
+ for (i = 0; i < sizeof (size_t); i++)
+ {
+ size <<= CHAR_BIT;
+ size += *ptr++;
+ }
+ return size;
+}
/* The call depth in overrun_check functions. For example, this might happen:
@@ -545,10 +557,10 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
xfree(10032)
overrun_check_free(10032)
- decrease overhed
+ decrease overhead
free(10016) <- crash, because 10000 is the original pointer. */
-static int check_depth;
+static ptrdiff_t check_depth;
/* Like malloc, but wraps allocated block with header and trailer. */
@@ -556,15 +568,16 @@ static POINTER_TYPE *
overrun_check_malloc (size_t size)
{
register unsigned char *val;
- size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0;
+ int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
+ if (SIZE_MAX - overhead < size)
+ abort ();
val = (unsigned char *) malloc (size + overhead);
if (val && check_depth == 1)
{
- memcpy (val, xmalloc_overrun_check_header,
- XMALLOC_OVERRUN_CHECK_SIZE - 4);
- val += XMALLOC_OVERRUN_CHECK_SIZE;
- XMALLOC_PUT_SIZE(val, size);
+ memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
+ val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+ xmalloc_put_size (val, size);
memcpy (val + size, xmalloc_overrun_check_trailer,
XMALLOC_OVERRUN_CHECK_SIZE);
}
@@ -580,31 +593,32 @@ static POINTER_TYPE *
overrun_check_realloc (POINTER_TYPE *block, size_t size)
{
register unsigned char *val = (unsigned char *) block;
- size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0;
+ int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
+ if (SIZE_MAX - overhead < size)
+ abort ();
if (val
&& check_depth == 1
&& memcmp (xmalloc_overrun_check_header,
- val - XMALLOC_OVERRUN_CHECK_SIZE,
- XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
+ val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
+ XMALLOC_OVERRUN_CHECK_SIZE) == 0)
{
- size_t osize = XMALLOC_GET_SIZE (val);
+ size_t osize = xmalloc_get_size (val);
if (memcmp (xmalloc_overrun_check_trailer, val + osize,
XMALLOC_OVERRUN_CHECK_SIZE))
abort ();
memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
- val -= XMALLOC_OVERRUN_CHECK_SIZE;
- memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE);
+ val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+ memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
}
val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
if (val && check_depth == 1)
{
- memcpy (val, xmalloc_overrun_check_header,
- XMALLOC_OVERRUN_CHECK_SIZE - 4);
- val += XMALLOC_OVERRUN_CHECK_SIZE;
- XMALLOC_PUT_SIZE(val, size);
+ memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
+ val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+ xmalloc_put_size (val, size);
memcpy (val + size, xmalloc_overrun_check_trailer,
XMALLOC_OVERRUN_CHECK_SIZE);
}
@@ -623,20 +637,20 @@ overrun_check_free (POINTER_TYPE *block)
if (val
&& check_depth == 1
&& memcmp (xmalloc_overrun_check_header,
- val - XMALLOC_OVERRUN_CHECK_SIZE,
- XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
+ val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
+ XMALLOC_OVERRUN_CHECK_SIZE) == 0)
{
- size_t osize = XMALLOC_GET_SIZE (val);
+ size_t osize = xmalloc_get_size (val);
if (memcmp (xmalloc_overrun_check_trailer, val + osize,
XMALLOC_OVERRUN_CHECK_SIZE))
abort ();
#ifdef XMALLOC_CLEAR_FREE_MEMORY
- val -= XMALLOC_OVERRUN_CHECK_SIZE;
- memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_SIZE*2);
+ val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+ memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
#else
memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
- val -= XMALLOC_OVERRUN_CHECK_SIZE;
- memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE);
+ val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+ memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
#endif
}
@@ -1092,11 +1106,11 @@ static void (*old_free_hook) (void*, const void*);
# define BYTES_USED _bytes_used
#endif
-static __malloc_size_t bytes_used_when_reconsidered;
+static size_t bytes_used_when_reconsidered;
/* Value of _bytes_used, when spare_memory was freed. */
-static __malloc_size_t bytes_used_when_full;
+static size_t bytes_used_when_full;
/* This function is used as the hook for free to call. */
@@ -1661,7 +1675,8 @@ static char const string_overrun_cookie[GC_STRING_OVERRUN_COOKIE_SIZE] =
calculating a value to be passed to malloc. */
#define STRING_BYTES_MAX \
min (STRING_BYTES_BOUND, \
- ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_SIZE - GC_STRING_EXTRA \
+ ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD \
+ - GC_STRING_EXTRA \
- offsetof (struct sblock, first_data) \
- SDATA_DATA_OFFSET) \
& ~(sizeof (EMACS_INT) - 1)))
@@ -3320,7 +3335,7 @@ refill_memory_reserve (void)
{
#ifndef SYSTEM_MALLOC
if (spare_memory[0] == 0)
- spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY);
+ spare_memory[0] = (char *) malloc (SPARE_MEMORY);
if (spare_memory[1] == 0)
spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block),
MEM_TYPE_CONS);
@@ -4922,7 +4937,7 @@ returns nil, because real GC can't be done. */)
if (NILP (Vpurify_flag))
{
char *stack;
- size_t stack_size;
+ ptrdiff_t stack_size;
if (&stack_top_variable < stack_bottom)
{
stack = &stack_top_variable;
@@ -5233,7 +5248,7 @@ static int last_marked_index;
links of a list, in mark_object. In debugging,
the call to abort will hit a breakpoint.
Normally this is zero and the check never goes off. */
-static size_t mark_object_loop_halt;
+ptrdiff_t mark_object_loop_halt EXTERNALLY_VISIBLE;
static void
mark_vectorlike (struct Lisp_Vector *ptr)
@@ -5290,7 +5305,7 @@ mark_object (Lisp_Object arg)
void *po;
struct mem_node *m;
#endif
- size_t cdr_count = 0;
+ ptrdiff_t cdr_count = 0;
loop:
diff --git a/src/bidi.c b/src/bidi.c
index 412dc94cb8..697ebb9285 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -299,11 +299,11 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
#define BIDI_CACHE_CHUNK 200
static struct bidi_it *bidi_cache;
-static EMACS_INT bidi_cache_size = 0;
+static ptrdiff_t bidi_cache_size = 0;
enum { elsz = sizeof (struct bidi_it) };
-static EMACS_INT bidi_cache_idx; /* next unused cache slot */
-static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */
-static EMACS_INT bidi_cache_start = 0; /* start of cache for this
+static ptrdiff_t bidi_cache_idx; /* next unused cache slot */
+static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */
+static ptrdiff_t bidi_cache_start = 0; /* start of cache for this
"stack" level */
/* Reset the cache state to the empty state. We only reset the part
@@ -336,7 +336,7 @@ bidi_cache_shrink (void)
}
static inline void
-bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it)
+bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it)
{
int current_scan_dir = bidi_it->scan_dir;
@@ -352,10 +352,10 @@ bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it)
level less or equal to LEVEL. if LEVEL is -1, disregard the
resolved levels in cached states. DIR, if non-zero, means search
in that direction from the last cache hit. */
-static inline EMACS_INT
+static inline ptrdiff_t
bidi_cache_search (EMACS_INT charpos, int level, int dir)
{
- EMACS_INT i, i_start;
+ ptrdiff_t i, i_start;
if (bidi_cache_idx > bidi_cache_start)
{
@@ -417,12 +417,12 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir)
C, searching backwards (DIR = -1) for LEVEL = 2 will return the
index of slot B or A, depending whether BEFORE is, respectively,
non-zero or zero. */
-static EMACS_INT
+static ptrdiff_t
bidi_cache_find_level_change (int level, int dir, int before)
{
if (bidi_cache_idx)
{
- EMACS_INT i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
+ ptrdiff_t i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
int incr = before ? 1 : 0;
xassert (!dir || bidi_cache_last_idx >= 0);
@@ -458,22 +458,33 @@ bidi_cache_find_level_change (int level, int dir, int before)
}
static inline void
-bidi_cache_ensure_space (EMACS_INT idx)
+bidi_cache_ensure_space (ptrdiff_t idx)
{
/* Enlarge the cache as needed. */
if (idx >= bidi_cache_size)
{
- while (idx >= bidi_cache_size)
- bidi_cache_size += BIDI_CACHE_CHUNK;
- bidi_cache =
- (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
+ ptrdiff_t new_size;
+
+ /* The bidi cache cannot be larger than the largest Lisp string
+ or buffer. */
+ ptrdiff_t string_or_buffer_bound =
+ max (BUF_BYTES_MAX, STRING_BYTES_BOUND);
+
+ /* Also, it cannot be larger than what C can represent. */
+ ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz;
+
+ if (min (string_or_buffer_bound, c_bound) <= idx)
+ memory_full (SIZE_MAX);
+ new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK;
+ bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz);
+ bidi_cache_size = new_size;
}
}
static inline void
bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
{
- EMACS_INT idx;
+ ptrdiff_t idx;
/* We should never cache on backward scans. */
if (bidi_it->scan_dir == -1)
@@ -528,7 +539,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
static inline bidi_type_t
bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it)
{
- EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
+ ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
if (i >= bidi_cache_start)
{
@@ -560,7 +571,7 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it)
/* 5-slot stack for saving the start of the previous level of the
cache. xdisp.c maintains a 5-slot stack for its iterator state,
and we need the same size of our stack. */
-static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE];
+static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
static int bidi_cache_sp;
/* Push the bidi iterator state in preparation for reordering a
@@ -2123,7 +2134,7 @@ static void
bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag)
{
int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir;
- EMACS_INT idx;
+ ptrdiff_t idx;
/* Try the cache first. */
if ((idx = bidi_cache_find_level_change (level, dir, end_flag))
@@ -2300,7 +2311,7 @@ void bidi_dump_cached_states (void) EXTERNALLY_VISIBLE;
void
bidi_dump_cached_states (void)
{
- int i;
+ ptrdiff_t i;
int ndigits = 1;
if (bidi_cache_idx == 0)
@@ -2308,7 +2319,7 @@ bidi_dump_cached_states (void)
fprintf (stderr, "The cache is empty.\n");
return;
}
- fprintf (stderr, "Total of %"pI"d state%s in cache:\n",
+ fprintf (stderr, "Total of %"pD"d state%s in cache:\n",
bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s");
for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10)
diff --git a/src/buffer.c b/src/buffer.c
index 81c537b9c6..a40275db8d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -152,7 +152,7 @@ Lisp_Object Qmodification_hooks;
Lisp_Object Qinsert_in_front_hooks;
Lisp_Object Qinsert_behind_hooks;
-static void alloc_buffer_text (struct buffer *, size_t);
+static void alloc_buffer_text (struct buffer *, ptrdiff_t);
static void free_buffer_text (struct buffer *b);
static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT);
@@ -4796,7 +4796,7 @@ extern void r_alloc_free (POINTER_TYPE **ptr);
/* Allocate NBYTES bytes for buffer B's text buffer. */
static void
-alloc_buffer_text (struct buffer *b, size_t nbytes)
+alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
{
POINTER_TYPE *p;
@@ -4826,8 +4826,8 @@ void
enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
{
POINTER_TYPE *p;
- size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
- + delta);
+ ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+ + delta);
BLOCK_INPUT;
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
diff --git a/src/callint.c b/src/callint.c
index 26b161a25b..5cf9949567 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -339,7 +339,7 @@ invoke it. If KEYS is omitted or nil, the return value of
{
Lisp_Object input;
Lisp_Object funval = Findirect_function (function, Qt);
- size_t events = num_input_events;
+ uintmax_t events = num_input_events;
input = specs;
/* Compute the arg values using the user's expression. */
GCPRO2 (input, filter_specs);
diff --git a/src/data.c b/src/data.c
index 7bc04592c5..76a54547a5 100644
--- a/src/data.c
+++ b/src/data.c
@@ -35,10 +35,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */
#include "font.h"
-#ifdef STDC_HEADERS
#include <float.h>
-#endif
-
/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
#ifndef IEEE_FLOATING_POINT
#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
diff --git a/src/dispnew.c b/src/dispnew.c
index 0198942012..b2f416701c 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -103,57 +103,24 @@ struct dim
/* Function prototypes. */
-static struct glyph_matrix *save_current_matrix (struct frame *);
-static void restore_current_matrix (struct frame *, struct glyph_matrix *);
-static int showing_window_margins_p (struct window *);
-static void fake_current_matrices (Lisp_Object);
-static void redraw_overlapping_rows (struct window *, int);
-static void redraw_overlapped_rows (struct window *, int);
-static int count_blanks (struct glyph *, int);
-static int count_match (struct glyph *, struct glyph *,
- struct glyph *, struct glyph *);
-static unsigned line_draw_cost (struct glyph_matrix *, int);
static void update_frame_line (struct frame *, int);
-static struct dim allocate_matrices_for_frame_redisplay
- (Lisp_Object, int, int, int, int *);
static int required_matrix_height (struct window *);
static int required_matrix_width (struct window *);
-static void allocate_matrices_for_window_redisplay (struct window *);
-static int realloc_glyph_pool (struct glyph_pool *, struct dim);
static void adjust_frame_glyphs (struct frame *);
-static struct glyph_matrix *new_glyph_matrix (struct glyph_pool *);
-static void free_glyph_matrix (struct glyph_matrix *);
-static void adjust_glyph_matrix (struct window *, struct glyph_matrix *,
- int, int, struct dim);
static void change_frame_size_1 (struct frame *, int, int, int, int, int);
static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
-static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *);
-#if GLYPH_DEBUG
-static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *);
-#endif
static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
struct window *);
static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
struct window *);
-static struct glyph_pool *new_glyph_pool (void);
-static void free_glyph_pool (struct glyph_pool *);
-static void adjust_frame_glyphs_initially (void);
static void adjust_frame_message_buffer (struct frame *);
static void adjust_decode_mode_spec_buffer (struct frame *);
static void fill_up_glyph_row_with_spaces (struct glyph_row *);
-static void build_frame_matrix (struct frame *);
-void clear_current_matrices (struct frame *);
-void scroll_glyph_matrix_range (struct glyph_matrix *, int, int,
- int, int);
static void clear_window_matrices (struct window *, int);
static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
static int scrolling_window (struct window *, int);
static int update_window_line (struct window *, int, int *);
-static void update_marginal_area (struct window *, int, int);
-static int update_text_area (struct window *, int);
-static void make_current (struct glyph_matrix *, struct glyph_matrix *,
- int);
static void mirror_make_current (struct window *, int);
#if GLYPH_DEBUG
static void check_matrix_pointers (struct glyph_matrix *,
@@ -286,7 +253,7 @@ static int history_idx;
/* A tick that's incremented each time something is added to the
history. */
-static unsigned history_tick;
+static uprintmax_t history_tick;
static void add_frame_display_history (struct frame *, int);
@@ -305,7 +272,7 @@ add_window_display_history (struct window *w, const char *msg, int paused_p)
buf = redisplay_history[history_idx].trace;
++history_idx;
- sprintf (buf, "%d: window %p (`%s')%s\n",
+ sprintf (buf, "%"pMu": window %p (`%s')%s\n",
history_tick++,
w,
((BUFFERP (w->buffer)
@@ -331,7 +298,7 @@ add_frame_display_history (struct frame *f, int paused_p)
buf = redisplay_history[history_idx].trace;
++history_idx;
- sprintf (buf, "%d: update frame %p%s",
+ sprintf (buf, "%"pMu": update frame %p%s",
history_tick++,
f, paused_p ? " ***paused***" : "");
}
@@ -532,7 +499,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
/* Enlarge MATRIX->rows if necessary. New rows are cleared. */
if (matrix->rows_allocated < dim.height)
{
- int size = dim.height * sizeof (struct glyph_row);
+ ptrdiff_t size = dim.height * sizeof (struct glyph_row);
new_rows = dim.height - matrix->rows_allocated;
matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
memset (matrix->rows + matrix->rows_allocated, 0,
@@ -1198,7 +1165,7 @@ prepare_desired_row (struct glyph_row *row)
{
if (!row->enabled_p)
{
- unsigned rp = row->reversed_p;
+ int rp = row->reversed_p;
clear_glyph_row (row);
row->enabled_p = 1;
@@ -1242,7 +1209,7 @@ line_hash_code (struct glyph_row *row)
the number of characters in the line. If must_write_spaces is
zero, leading and trailing spaces are ignored. */
-static unsigned int
+static int
line_draw_cost (struct glyph_matrix *matrix, int vpos)
{
struct glyph_row *row = matrix->rows + vpos;
@@ -1435,7 +1402,7 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
needed = matrix_dim.width * matrix_dim.height;
if (needed > pool->nglyphs)
{
- int size = needed * sizeof (struct glyph);
+ ptrdiff_t size = needed * sizeof (struct glyph);
if (pool->glyphs)
{
@@ -2061,7 +2028,7 @@ save_current_matrix (struct frame *f)
{
struct glyph_row *from = f->current_matrix->rows + i;
struct glyph_row *to = saved->rows + i;
- size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+ ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
@@ -2083,7 +2050,7 @@ restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
{
struct glyph_row *from = saved->rows + i;
struct glyph_row *to = f->current_matrix->rows + i;
- size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+ ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
to->used[TEXT_AREA] = from->used[TEXT_AREA];
xfree (from->glyphs[TEXT_AREA]);
@@ -2271,7 +2238,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f)
static void
adjust_frame_message_buffer (struct frame *f)
{
- int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
+ ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
if (FRAME_MESSAGE_BUF (f))
{
@@ -4301,7 +4268,8 @@ scrolling_window (struct window *w, int header_line_p)
struct glyph_matrix *current_matrix = w->current_matrix;
int yb = window_text_bottom_y (w);
int i, j, first_old, first_new, last_old, last_new;
- int nruns, nbytes, n, run_idx;
+ int nruns, n, run_idx;
+ ptrdiff_t nbytes;
struct row_entry *entry;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
@@ -6329,11 +6297,14 @@ init_display (void)
int width = FRAME_TOTAL_COLS (sf);
int height = FRAME_LINES (sf);
- unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
-
/* If these sizes are so big they cause overflow, just ignore the
- change. It's not clear what better we could do. */
- if (total_glyphs / sizeof (struct glyph) / height != width + 2)
+ change. It's not clear what better we could do. The rest of
+ the code assumes that (width + 2) * height * sizeof (struct glyph)
+ does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */
+ if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
+ || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
+ || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
+ < (width + 2) * height))
fatal ("screen size %dx%d too big", width, height);
}
diff --git a/src/doprnt.c b/src/doprnt.c
index 195598c07e..79f9f36e46 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -102,13 +102,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
-
-#ifdef STDC_HEADERS
#include <float.h>
-#endif
-
#include <unistd.h>
-
#include <limits.h>
#include "lisp.h"
@@ -134,8 +129,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
String arguments are passed as C strings.
Integers are passed as C integers. */
-size_t
-doprnt (char *buffer, register size_t bufsize, const char *format,
+ptrdiff_t
+doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
const char *format_end, va_list ap)
{
const char *fmt = format; /* Pointer into format string */
@@ -145,7 +140,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
char tembuf[DBL_MAX_10_EXP + 100];
/* Size of sprintf_buffer. */
- size_t size_allocated = sizeof (tembuf);
+ ptrdiff_t size_allocated = sizeof (tembuf);
/* Buffer to use for sprintf. Either tembuf or same as BIG_BUFFER. */
char *sprintf_buffer = tembuf;
@@ -164,7 +159,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
if (format_end == 0)
format_end = format + strlen (format);
- if ((format_end - format + 1) < sizeof (fixed_buffer))
+ if (format_end - format < sizeof (fixed_buffer) - 1)
fmtcpy = fixed_buffer;
else
SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
@@ -176,7 +171,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
{
if (*fmt == '%') /* Check for a '%' character */
{
- size_t size_bound = 0;
+ ptrdiff_t size_bound = 0;
EMACS_INT width; /* Columns occupied by STRING on display. */
int long_flag = 0;
int pIlen = sizeof pI - 1;
@@ -194,16 +189,16 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
This might be a field width or a precision; e.g.
%1.1000f and %1000.1f both might need 1000+ bytes.
Parse the width or precision, checking for overflow. */
- size_t n = *fmt - '0';
+ ptrdiff_t n = *fmt - '0';
while (fmt + 1 < format_end
&& '0' <= fmt[1] && fmt[1] <= '9')
{
- /* Avoid size_t overflow. Avoid int overflow too, as
+ /* Avoid ptrdiff_t, size_t, and int overflow, as
many sprintfs mishandle widths greater than INT_MAX.
This test is simple but slightly conservative: e.g.,
(INT_MAX - INT_MAX % 10) is reported as an overflow
even when it's not. */
- if (n >= min (INT_MAX, SIZE_MAX) / 10)
+ if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
error ("Format width or precision too large");
n = n * 10 + fmt[1] - '0';
*string++ = *++fmt;
@@ -235,7 +230,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
/* Make the size bound large enough to handle floating point formats
with large numbers. */
- if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50)
+ if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
error ("Format width or precision too large");
size_bound += DBL_MAX_10_EXP + 50;
diff --git a/src/editfns.c b/src/editfns.c
index 56ad99d199..577263c5ae 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3504,22 +3504,6 @@ usage: (propertize STRING &rest PROPERTIES) */)
RETURN_UNGCPRO (string);
}
-/* pWIDE is a conversion for printing large decimal integers (possibly with a
- trailing "d" that is ignored). pWIDElen is its length. signed_wide and
- unsigned_wide are signed and unsigned types for printing them. Use widest
- integers if available so that more floating point values can be converted. */
-#ifdef PRIdMAX
-# define pWIDE PRIdMAX
-enum { pWIDElen = sizeof PRIdMAX - 2 }; /* Don't count trailing "d". */
-typedef intmax_t signed_wide;
-typedef uintmax_t unsigned_wide;
-#else
-# define pWIDE pI
-enum { pWIDElen = sizeof pI - 1 };
-typedef EMACS_INT signed_wide;
-typedef EMACS_UINT unsigned_wide;
-#endif
-
DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
doc: /* Format a string out of a format-string and arguments.
The first argument is a format control string.
@@ -3901,7 +3885,11 @@ usage: (format STRING &rest OBJECTS) */)
precision is no more than DBL_USEFUL_PRECISION_MAX.
On all practical hosts, %f is the worst case. */
SPRINTF_BUFSIZE =
- sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX
+ sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX,
+
+ /* Length of pM (that is, of pMd without the
+ trailing "d"). */
+ pMlen = sizeof pMd - 2
};
verify (0 < USEFUL_PRECISION_MAX);
@@ -3914,7 +3902,7 @@ usage: (format STRING &rest OBJECTS) */)
/* Copy of conversion specification, modified somewhat.
At most three flags F can be specified at once. */
- char convspec[sizeof "%FFF.*d" + pWIDElen];
+ char convspec[sizeof "%FFF.*d" + pMlen];
/* Avoid undefined behavior in underlying sprintf. */
if (conversion == 'd' || conversion == 'i')
@@ -3922,7 +3910,7 @@ usage: (format STRING &rest OBJECTS) */)
/* Create the copy of the conversion specification, with
any width and precision removed, with ".*" inserted,
- and with pWIDE inserted for integer formats. */
+ and with pM inserted for integer formats. */
{
char *f = convspec;
*f++ = '%';
@@ -3937,8 +3925,8 @@ usage: (format STRING &rest OBJECTS) */)
|| conversion == 'o' || conversion == 'x'
|| conversion == 'X')
{
- memcpy (f, pWIDE, pWIDElen);
- f += pWIDElen;
+ memcpy (f, pMd, pMlen);
+ f += pMlen;
zero_flag &= ~ precision_given;
}
*f++ = conversion;
@@ -3978,7 +3966,7 @@ usage: (format STRING &rest OBJECTS) */)
/* For float, maybe we should use "%1.0f"
instead so it also works for values outside
the integer range. */
- signed_wide x;
+ printmax_t x;
if (INTEGERP (args[n]))
x = XINT (args[n]);
else
@@ -3986,13 +3974,13 @@ usage: (format STRING &rest OBJECTS) */)
double d = XFLOAT_DATA (args[n]);
if (d < 0)
{
- x = TYPE_MINIMUM (signed_wide);
+ x = TYPE_MINIMUM (printmax_t);
if (x < d)
x = d;
}
else
{
- x = TYPE_MAXIMUM (signed_wide);
+ x = TYPE_MAXIMUM (printmax_t);
if (d < x)
x = d;
}
@@ -4002,7 +3990,7 @@ usage: (format STRING &rest OBJECTS) */)
else
{
/* Don't sign-extend for octal or hex printing. */
- unsigned_wide x;
+ uprintmax_t x;
if (INTEGERP (args[n]))
x = XUINT (args[n]);
else
@@ -4012,7 +4000,7 @@ usage: (format STRING &rest OBJECTS) */)
x = 0;
else
{
- x = TYPE_MAXIMUM (unsigned_wide);
+ x = TYPE_MAXIMUM (uprintmax_t);
if (d < x)
x = d;
}
diff --git a/src/emacs.c b/src/emacs.c
index bc62735ab8..39870ec007 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -170,8 +170,10 @@ char *stack_bottom;
/* The address where the heap starts (from the first sbrk (0) call). */
static void *my_heap_start;
+#ifdef GNU_LINUX
/* The gap between BSS end and heap start as far as we can tell. */
-static unsigned long heap_bss_diff;
+static uprintmax_t heap_bss_diff;
+#endif
/* Nonzero means running Emacs without interactive terminal. */
int noninteractive;
@@ -716,6 +718,7 @@ main (int argc, char **argv)
setenv ("G_SLICE", "always-malloc", 1);
#endif
+#ifdef GNU_LINUX
if (!initialized)
{
extern char my_endbss[];
@@ -726,6 +729,7 @@ main (int argc, char **argv)
heap_bss_diff = (char *)my_heap_start - max (my_endbss, my_endbss_static);
}
+#endif
#ifdef RUN_TIME_REMAP
if (initialized)
@@ -2134,7 +2138,7 @@ You must run Emacs in batch mode in order to dump it. */)
{
fprintf (stderr, "**************************************************\n");
fprintf (stderr, "Warning: Your system has a gap between BSS and the\n");
- fprintf (stderr, "heap (%lu bytes). This usually means that exec-shield\n",
+ fprintf (stderr, "heap (%"pMu" bytes). This usually means that exec-shield\n",
heap_bss_diff);
fprintf (stderr, "or something similar is in effect. The dump may\n");
fprintf (stderr, "fail because of this. See the section about\n");
diff --git a/src/eval.c b/src/eval.c
index 90d0df6185..ef169e80e2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1968,18 +1968,18 @@ void
verror (const char *m, va_list ap)
{
char buf[4000];
- size_t size = sizeof buf;
- size_t size_max = STRING_BYTES_BOUND + 1;
- size_t mlen = strlen (m);
+ ptrdiff_t size = sizeof buf;
+ ptrdiff_t size_max = STRING_BYTES_BOUND + 1;
+ char const *m_end = m + strlen (m);
char *buffer = buf;
- size_t used;
+ ptrdiff_t used;
Lisp_Object string;
while (1)
{
va_list ap_copy;
va_copy (ap_copy, ap);
- used = doprnt (buffer, size, m, m + mlen, ap_copy);
+ used = doprnt (buffer, size, m, m_end, ap_copy);
va_end (ap_copy);
/* Note: the -1 below is because `doprnt' returns the number of bytes
diff --git a/src/fileio.c b/src/fileio.c
index 3e1aa54462..6171368935 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -587,9 +587,9 @@ make_temp_name (Lisp_Object prefix, int base64_p)
{
Lisp_Object val;
int len, clen;
- intmax_t pid;
+ printmax_t pid;
char *p, *data;
- char pidbuf[INT_BUFSIZE_BOUND (pid_t)];
+ char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
int pidlen;
CHECK_STRING (prefix);
@@ -611,7 +611,7 @@ make_temp_name (Lisp_Object prefix, int base64_p)
else
{
#ifdef HAVE_LONG_FILE_NAMES
- pidlen = sprintf (pidbuf, "%"PRIdMAX, pid);
+ pidlen = sprintf (pidbuf, "%"pMd, pid);
#else
pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
diff --git a/src/filelock.c b/src/filelock.c
index 18483b6f3f..c28ee7837f 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -337,7 +337,7 @@ static int
lock_file_1 (char *lfname, int force)
{
register int err;
- intmax_t boot, pid;
+ printmax_t boot, pid;
const char *user_name;
const char *host_name;
char *lock_info_str;
@@ -354,15 +354,15 @@ lock_file_1 (char *lfname, int force)
else
host_name = "";
lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
- + 2 * INT_STRLEN_BOUND (intmax_t)
+ + 2 * INT_STRLEN_BOUND (printmax_t)
+ sizeof "@.:");
pid = getpid ();
if (boot)
- sprintf (lock_info_str, "%s@%s.%"PRIdMAX":%"PRIdMAX,
+ sprintf (lock_info_str, "%s@%s.%"pMd":%"pMd,
user_name, host_name, pid, boot);
else
- sprintf (lock_info_str, "%s@%s.%"PRIdMAX,
+ sprintf (lock_info_str, "%s@%s.%"pMd,
user_name, host_name, pid);
err = symlink (lock_info_str, lfname);
@@ -542,7 +542,7 @@ lock_file (Lisp_Object fn)
register Lisp_Object attack, orig_fn, encoded_fn;
register char *lfname, *locker;
lock_info_type lock_info;
- intmax_t pid;
+ printmax_t pid;
struct gcpro gcpro1;
/* Don't do locking while dumping Emacs.
@@ -581,9 +581,10 @@ lock_file (Lisp_Object fn)
/* Else consider breaking the lock */
locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host)
- + INT_STRLEN_BOUND (intmax_t) + sizeof "@ (pid )");
+ + INT_STRLEN_BOUND (printmax_t)
+ + sizeof "@ (pid )");
pid = lock_info.pid;
- sprintf (locker, "%s@%s (pid %"PRIdMAX")",
+ sprintf (locker, "%s@%s (pid %"pMd")",
lock_info.user, lock_info.host, pid);
FREE_LOCK_INFO (lock_info);
diff --git a/src/floatfns.c b/src/floatfns.c
index e003f492fe..89aa052e8b 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -53,10 +53,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "syssignal.h"
-#if STDC_HEADERS
#include <float.h>
-#endif
-
/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
#ifndef IEEE_FLOATING_POINT
#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
diff --git a/src/fns.c b/src/fns.c
index 0ca731ed33..9c9d19fe26 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4098,25 +4098,33 @@ sweep_weak_hash_tables (void)
#define SXHASH_REDUCE(X) \
((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
-/* Return a hash for string PTR which has length LEN. The hash
- code returned is guaranteed to fit in a Lisp integer. */
+/* Return a hash for string PTR which has length LEN. The hash value
+ can be any EMACS_UINT value. */
-static EMACS_UINT
-sxhash_string (unsigned char *ptr, EMACS_INT len)
+EMACS_UINT
+hash_string (char const *ptr, ptrdiff_t len)
{
- unsigned char *p = ptr;
- unsigned char *end = p + len;
+ char const *p = ptr;
+ char const *end = p + len;
unsigned char c;
EMACS_UINT hash = 0;
while (p != end)
{
c = *p++;
- if (c >= 0140)
- c -= 40;
hash = SXHASH_COMBINE (hash, c);
}
+ return hash;
+}
+
+/* Return a hash for string PTR which has length LEN. The hash
+ code returned is guaranteed to fit in a Lisp integer. */
+
+static EMACS_UINT
+sxhash_string (char const *ptr, ptrdiff_t len)
+{
+ EMACS_UINT hash = hash_string (ptr, len);
return SXHASH_REDUCE (hash);
}
@@ -4231,7 +4239,7 @@ sxhash (Lisp_Object obj, int depth)
/* Fall through. */
case Lisp_String:
- hash = sxhash_string (SDATA (obj), SCHARS (obj));
+ hash = sxhash_string (SSDATA (obj), SBYTES (obj));
break;
/* This can be everything from a vector to an overlay. */
diff --git a/src/gmalloc.c b/src/gmalloc.c
index a023d2d78e..fa4aa1fdf6 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -41,37 +41,13 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#define USE_PTHREAD
#endif
-#if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
- || defined STDC_HEADERS || defined PROTOTYPES))
#undef PP
#define PP(args) args
#undef __ptr_t
#define __ptr_t void *
-#else /* Not C++ or ANSI C. */
-#undef PP
-#define PP(args) ()
-#undef __ptr_t
-#define __ptr_t char *
-#endif /* C++ or ANSI C. */
-#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
#include <string.h>
-#else
-#ifndef memset
-#define memset(s, zero, n) bzero ((s), (n))
-#endif
-#ifndef memcpy
-#define memcpy(d, s, n) bcopy ((s), (d), (n))
-#endif
-#endif
-
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
#include <unistd.h>
#ifdef USE_PTHREAD
@@ -86,26 +62,9 @@ extern "C"
{
#endif
-#ifdef STDC_HEADERS
#include <stddef.h>
#define __malloc_size_t size_t
#define __malloc_ptrdiff_t ptrdiff_t
-#else
-#ifdef __GNUC__
-#include <stddef.h>
-#ifdef __SIZE_TYPE__
-#define __malloc_size_t __SIZE_TYPE__
-#endif
-#endif
-#ifndef __malloc_size_t
-#define __malloc_size_t unsigned int
-#endif
-#define __malloc_ptrdiff_t int
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
/* Allocate SIZE bytes of memory. */
@@ -1069,20 +1028,6 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#endif
-/* Cope with systems lacking `memmove'. */
-#ifndef memmove
-#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
-#ifdef emacs
-#undef __malloc_safe_bcopy
-#define __malloc_safe_bcopy safe_bcopy
-#endif
-/* This function is defined in realloc.c. */
-extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
-#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
-#endif
-#endif
-
-
/* Debugging hook for free. */
void (*__free_hook) PP ((__ptr_t __ptr));
@@ -1402,85 +1347,6 @@ Fifth Floor, Boston, MA 02110-1301, USA.
#endif
-
-/* Cope with systems lacking `memmove'. */
-#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
-
-#ifdef emacs
-#undef __malloc_safe_bcopy
-#define __malloc_safe_bcopy safe_bcopy
-#else
-
-/* Snarfed directly from Emacs src/dispnew.c:
- XXX Should use system bcopy if it handles overlap. */
-
-/* Like bcopy except never gets confused by overlap. */
-
-void
-__malloc_safe_bcopy (afrom, ato, size)
- __ptr_t afrom;
- __ptr_t ato;
- __malloc_size_t size;
-{
- char *from = afrom, *to = ato;
-
- if (size <= 0 || from == to)
- return;
-
- /* If the source and destination don't overlap, then bcopy can
- handle it. If they do overlap, but the destination is lower in
- memory than the source, we'll assume bcopy can handle that. */
- if (to < from || from + size <= to)
- bcopy (from, to, size);
-
- /* Otherwise, we'll copy from the end. */
- else
- {
- register char *endf = from + size;
- register char *endt = to + size;
-
- /* If TO - FROM is large, then we should break the copy into
- nonoverlapping chunks of TO - FROM bytes each. However, if
- TO - FROM is small, then the bcopy function call overhead
- makes this not worth it. The crossover point could be about
- anywhere. Since I don't think the obvious copy loop is too
- bad, I'm trying to err in its favor. */
- if (to - from < 64)
- {
- do
- *--endt = *--endf;
- while (endf != from);
- }
- else
- {
- for (;;)
- {
- endt -= (to - from);
- endf -= (to - from);
-
- if (endt < to)
- break;
-
- bcopy (endf, endt, to - from);
- }
-
- /* If SIZE wasn't a multiple of TO - FROM, there will be a
- little left over. The amount left over is
- (endt + (to - from)) - to, which is endt - from. */
- bcopy (from, to, endt - from);
- }
- }
-}
-#endif /* emacs */
-
-#ifndef memmove
-extern void __malloc_safe_bcopy PP ((__ptr_t, __ptr_t, __malloc_size_t));
-#define memmove(to, from, size) __malloc_safe_bcopy ((from), (to), (size))
-#endif
-
-#endif
-
-
#define min(A, B) ((A) < (B) ? (A) : (B))
/* Debugging hook for realloc. */
@@ -1983,22 +1849,6 @@ struct hdr
unsigned long int magic; /* Magic number to check header integrity. */
};
-#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
-#define flood memset
-#else
-static void flood (__ptr_t, int, __malloc_size_t);
-static void
-flood (ptr, val, size)
- __ptr_t ptr;
- int val;
- __malloc_size_t size;
-{
- char *cp = ptr;
- while (size--)
- *cp++ = val;
-}
-#endif
-
static enum mcheck_status checkhdr (const struct hdr *);
static enum mcheck_status
checkhdr (hdr)
@@ -2037,7 +1887,7 @@ freehook (ptr)
hdr = ((struct hdr *) ptr) - 1;
checkhdr (hdr);
hdr->magic = MAGICFREE;
- flood (ptr, FREEFLOOD, hdr->size);
+ memset (ptr, FREEFLOOD, hdr->size);
}
else
hdr = NULL;
@@ -2063,7 +1913,7 @@ mallochook (size)
hdr->size = size;
hdr->magic = MAGICWORD;
((char *) &hdr[1])[size] = MAGICBYTE;
- flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
+ memset ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
return (__ptr_t) (hdr + 1);
}
@@ -2083,7 +1933,7 @@ reallochook (ptr, size)
checkhdr (hdr);
if (size < osize)
- flood ((char *) ptr + size, FREEFLOOD, osize - size);
+ memset ((char *) ptr + size, FREEFLOOD, osize - size);
}
__free_hook = old_free_hook;
@@ -2100,7 +1950,7 @@ reallochook (ptr, size)
hdr->magic = MAGICWORD;
((char *) &hdr[1])[size] = MAGICBYTE;
if (size > osize)
- flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
+ memset ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
return (__ptr_t) (hdr + 1);
}
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 35b366222d..8826b08851 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -269,8 +269,8 @@ xg_get_pixbuf_from_pixmap (FRAME_PTR f, Pixmap pix)
GDK_COLORSPACE_RGB,
FALSE,
xim->bitmap_unit,
- (int) width,
- (int) height,
+ width,
+ height,
xim->bytes_per_line,
NULL,
NULL);
@@ -3646,7 +3646,7 @@ xg_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar,
gtk_adjustment_set_page_size (adj, size);
gtk_adjustment_set_step_increment (adj, new_step);
/* Assume a page increment is about 95% of the page size */
- gtk_adjustment_set_page_increment (adj,(int) (0.95*size));
+ gtk_adjustment_set_page_increment (adj, size - size / 20);
changed = 1;
}
}
diff --git a/src/image.c b/src/image.c
index fa39ff1268..7a5ac40b3d 100644
--- a/src/image.c
+++ b/src/image.c
@@ -136,7 +136,6 @@ static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
#ifdef COLOR_TABLE_SUPPORT
static void free_color_table (void);
static unsigned long *colors_in_color_table (int *n);
-static unsigned long lookup_pixel_color (struct frame *f, unsigned long p);
#endif
static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
@@ -987,7 +986,6 @@ or omitted means use the selected frame. */)
***********************************************************************/
static void free_image (struct frame *f, struct image *img);
-static int check_image_size (struct frame *f, int width, int height);
#define MAX_IMAGE_SIZE 6.0
/* Allocate and return a new image structure for image specification
@@ -1042,7 +1040,7 @@ free_image (struct frame *f, struct image *img)
/* Return 1 if the given widths and heights are valid for display;
otherwise, return 0. */
-int
+static int
check_image_size (struct frame *f, int width, int height)
{
int w, h;
@@ -1051,23 +1049,18 @@ check_image_size (struct frame *f, int width, int height)
return 0;
if (INTEGERP (Vmax_image_size))
- w = h = XINT (Vmax_image_size);
+ return (width <= XINT (Vmax_image_size)
+ && height <= XINT (Vmax_image_size));
else if (FLOATP (Vmax_image_size))
{
- if (f != NULL)
- {
- w = FRAME_PIXEL_WIDTH (f);
- h = FRAME_PIXEL_HEIGHT (f);
- }
- else
- w = h = 1024; /* Arbitrary size for unknown frame. */
- w = (int) (XFLOAT_DATA (Vmax_image_size) * w);
- h = (int) (XFLOAT_DATA (Vmax_image_size) * h);
+ xassert (f);
+ w = FRAME_PIXEL_WIDTH (f);
+ h = FRAME_PIXEL_HEIGHT (f);
+ return (width <= XFLOAT_DATA (Vmax_image_size) * w
+ && height <= XFLOAT_DATA (Vmax_image_size) * h);
}
else
return 1;
-
- return (width <= w && height <= h);
}
/* Prepare image IMG for display on frame F. Must be called before
@@ -1368,7 +1361,9 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
xassert (STRINGP (color_name));
- if (x_defined_color (f, SSDATA (color_name), &color, 1))
+ if (x_defined_color (f, SSDATA (color_name), &color, 1)
+ && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
+ INT_MAX))
{
/* This isn't called frequently so we get away with simply
reallocating the color vector to the needed size, here. */
@@ -1911,6 +1906,38 @@ static int x_create_x_image_and_pixmap (struct frame *, int, int, int,
static void x_destroy_x_image (XImagePtr);
static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
+/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break X.
+ WIDTH and HEIGHT must both be positive.
+ If XIMG is null, assume it is a bitmap. */
+static int
+x_check_image_size (XImagePtr ximg, int width, int height)
+{
+ /* Respect Xlib's limits: it cannot deal with images that have more
+ than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
+ of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. For now,
+ assume all windowing systems have the same limits that X does. */
+ enum
+ {
+ XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
+ X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
+ };
+
+ int bitmap_pad, depth, bytes_per_line;
+ if (ximg)
+ {
+ bitmap_pad = ximg->bitmap_pad;
+ depth = ximg->depth;
+ bytes_per_line = ximg->bytes_per_line;
+ }
+ else
+ {
+ bitmap_pad = 8;
+ depth = 1;
+ bytes_per_line = (width >> 3) + ((width & 7) != 0);
+ }
+ return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
+ && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
+}
/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
@@ -1943,6 +1970,15 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
return 0;
}
+ if (! x_check_image_size (*ximg, width, height))
+ {
+ x_destroy_x_image (*ximg);
+ *ximg = NULL;
+ image_error ("Image too large (%dx%d)",
+ make_number (width), make_number (height));
+ return 0;
+ }
+
/* Allocate image raster. */
(*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
@@ -1989,11 +2025,6 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
palette_colors = 1 << depth - 1;
*ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
- if (*ximg == NULL)
- {
- image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
- return 0;
- }
header = &(*ximg)->info.bmiHeader;
memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
@@ -2365,7 +2396,7 @@ xbm_image_p (Lisp_Object object)
}
else if (BOOL_VECTOR_P (data))
{
- if (XBOOL_VECTOR (data)->size < width * height)
+ if (XBOOL_VECTOR (data)->size / height < width)
return 0;
}
else
@@ -2561,13 +2592,15 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
img->pixmap = ns_image_from_XBM (data, img->width, img->height);
#else
- img->pixmap
- = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
+ img->pixmap =
+ (x_check_image_size (0, img->width, img->height)
+ ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
FRAME_X_WINDOW (f),
data,
img->width, img->height,
fg, bg,
- DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+ DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
+ : NO_PIXMAP);
#endif /* !HAVE_NTGUI && !HAVE_NS */
}
@@ -2674,6 +2707,13 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
expect ('=');
expect ('{');
+ if (! x_check_image_size (0, *width, *height))
+ {
+ if (!inhibit_image_error)
+ image_error ("Image too large (%dx%d)",
+ make_number (*width), make_number (*height));
+ goto failure;
+ }
bytes_per_line = (*width + 7) / 8 + padding_p;
nbytes = bytes_per_line * *height;
p = *data = (char *) xmalloc (nbytes);
@@ -2864,6 +2904,12 @@ xbm_load (struct frame *f, struct image *img)
img->width = XFASTINT (fmt[XBM_WIDTH].value);
img->height = XFASTINT (fmt[XBM_HEIGHT].value);
xassert (img->width > 0 && img->height > 0);
+ if (!check_image_size (f, img->width, img->height))
+ {
+ image_error ("Invalid image size (see `max-image-size')",
+ Qnil, Qnil);
+ return 0;
+ }
}
/* Get foreground and background colors, maybe allocate colors. */
@@ -2925,9 +2971,13 @@ xbm_load (struct frame *f, struct image *img)
#endif
/* Create the pixmap. */
- Create_Pixmap_From_Bitmap_Data (f, img, bits,
- foreground, background,
- non_default_colors);
+ if (x_check_image_size (0, img->width, img->height))
+ Create_Pixmap_From_Bitmap_Data (f, img, bits,
+ foreground, background,
+ non_default_colors);
+ else
+ img->pixmap = NO_PIXMAP;
+
if (img->pixmap)
success_p = 1;
else
@@ -3125,12 +3175,8 @@ xpm_free_color_cache (void)
static int
xpm_color_bucket (char *color_name)
{
- unsigned h = 0;
- char *s;
-
- for (s = color_name; *s; ++s)
- h = (h << 2) ^ *s;
- return h %= XPM_COLOR_CACHE_BUCKETS;
+ EMACS_UINT hash = hash_string (color_name, strlen (color_name));
+ return hash % XPM_COLOR_CACHE_BUCKETS;
}
@@ -3147,7 +3193,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
if (bucket < 0)
bucket = xpm_color_bucket (color_name);
- nbytes = sizeof *p + strlen (color_name);
+ nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
p = (struct xpm_cached_color *) xmalloc (nbytes);
strcpy (p->name, color_name);
p->color = *color;
@@ -3849,6 +3895,18 @@ xpm_load_image (struct frame *f,
goto failure;
}
+ if (!x_create_x_image_and_pixmap (f, width, height, 0,
+ &ximg, &img->pixmap)
+#ifndef HAVE_NS
+ || !x_create_x_image_and_pixmap (f, width, height, 1,
+ &mask_img, &img->mask)
+#endif
+ )
+ {
+ image_error ("Image too large", Qnil, Qnil);
+ goto failure;
+ }
+
expect (',');
XSETFRAME (frame, f);
@@ -3942,18 +4000,6 @@ xpm_load_image (struct frame *f,
expect (',');
}
- if (!x_create_x_image_and_pixmap (f, width, height, 0,
- &ximg, &img->pixmap)
-#ifndef HAVE_NS
- || !x_create_x_image_and_pixmap (f, width, height, 1,
- &mask_img, &img->mask)
-#endif
- )
- {
- image_error ("Out of memory (%s)", img->spec, Qnil);
- goto error;
- }
-
for (y = 0; y < height; y++)
{
expect (XPM_TK_STRING);
@@ -5518,8 +5564,8 @@ my_png_warning (png_struct *png_ptr, const char *msg)
struct png_memory_storage
{
unsigned char *bytes; /* The data */
- size_t len; /* How big is it? */
- int index; /* Where are we? */
+ ptrdiff_t len; /* How big is it? */
+ ptrdiff_t index; /* Where are we? */
};
@@ -5563,7 +5609,8 @@ png_load (struct frame *f, struct image *img)
{
Lisp_Object file, specified_file;
Lisp_Object specified_data;
- int x, y, i;
+ int x, y;
+ ptrdiff_t i;
XImagePtr ximg, mask_img = NULL;
png_struct *png_ptr = NULL;
png_info *info_ptr = NULL, *end_info = NULL;
@@ -5683,11 +5730,19 @@ png_load (struct frame *f, struct image *img)
fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, NULL, NULL);
- if (!check_image_size (f, width, height))
+ if (! (width <= INT_MAX && height <= INT_MAX
+ && check_image_size (f, width, height)))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
goto error;
}
+
+ /* Create the X image and pixmap now, so that the work below can be
+ omitted if the image is too large for X. */
+ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
+ &img->pixmap))
+ goto error;
+
/* If image contains simply transparency data, we prefer to
construct a clipping mask. */
if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
@@ -5776,7 +5831,10 @@ png_load (struct frame *f, struct image *img)
row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
/* Allocate memory for the image. */
- pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
+ || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
+ memory_full (SIZE_MAX);
+ pixels = (png_byte *) xmalloc (sizeof *pixels * row_bytes * height);
rows = (png_byte **) xmalloc (height * sizeof *rows);
for (i = 0; i < height; ++i)
rows[i] = pixels + i * row_bytes;
@@ -5790,11 +5848,6 @@ png_load (struct frame *f, struct image *img)
fp = NULL;
}
- /* Create the X image and pixmap. */
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
- &img->pixmap))
- goto error;
-
/* Create an image and pixmap serving as mask if the PNG image
contains an alpha channel. */
if (channels == 4
@@ -6192,7 +6245,7 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
src = (struct jpeg_stdio_mgr *) cinfo->src;
if (!src->finished)
{
- size_t bytes;
+ ptrdiff_t bytes;
bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
if (bytes > 0)
@@ -6602,34 +6655,33 @@ init_tiff_functions (Lisp_Object libraries)
typedef struct
{
unsigned char *bytes;
- size_t len;
- int index;
+ ptrdiff_t len;
+ ptrdiff_t index;
}
tiff_memory_source;
-static size_t
+static tsize_t
tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
{
tiff_memory_source *src = (tiff_memory_source *) data;
- if (size > src->len - src->index)
- return (size_t) -1;
+ size = min (size, src->len - src->index);
memcpy (buf, src->bytes + src->index, size);
src->index += size;
return size;
}
-static size_t
+static tsize_t
tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
{
- return (size_t) -1;
+ return -1;
}
static toff_t
tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
{
tiff_memory_source *src = (tiff_memory_source *) data;
- int idx;
+ ptrdiff_t idx;
switch (whence)
{
@@ -6765,8 +6817,8 @@ tiff_load (struct frame *f, struct image *img)
memsrc.index = 0;
tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
- (TIFFReadWriteProc) tiff_read_from_memory,
- (TIFFReadWriteProc) tiff_write_from_memory,
+ tiff_read_from_memory,
+ tiff_write_from_memory,
tiff_seek_in_memory,
tiff_close_memory,
tiff_size_of_memory,
@@ -6805,7 +6857,16 @@ tiff_load (struct frame *f, struct image *img)
return 0;
}
- buf = (uint32 *) xmalloc (width * height * sizeof *buf);
+ /* Create the X image and pixmap. */
+ if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
+ && x_create_x_image_and_pixmap (f, width, height, 0,
+ &ximg, &img->pixmap)))
+ {
+ fn_TIFFClose (tiff);
+ return 0;
+ }
+
+ buf = (uint32 *) xmalloc (sizeof *buf * width * height);
rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
@@ -6826,13 +6887,6 @@ tiff_load (struct frame *f, struct image *img)
return 0;
}
- /* Create the X image and pixmap. */
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- {
- xfree (buf);
- return 0;
- }
-
/* Initialize the color table. */
init_color_table ();
@@ -7034,8 +7088,8 @@ init_gif_functions (Lisp_Object libraries)
typedef struct
{
unsigned char *bytes;
- size_t len;
- int index;
+ ptrdiff_t len;
+ ptrdiff_t index;
}
gif_memory_source;
@@ -7668,7 +7722,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
height = MagickGetImageHeight (image_wand);
width = MagickGetImageWidth (image_wand);
- if (! check_image_size (f, width, height))
+ if (! (width <= INT_MAX && height <= INT_MAX
+ && check_image_size (f, width, height)))
{
image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
goto imagemagick_error;
@@ -7872,7 +7927,7 @@ recognize as images, such as C. See `imagemagick-types-inhibit'. */)
size_t numf = 0;
ExceptionInfo ex;
char **imtypes = GetMagickList ("*", &numf, &ex);
- int i;
+ size_t i;
Lisp_Object Qimagemagicktype;
for (i = 0; i < numf; i++)
{
@@ -8426,12 +8481,15 @@ gs_load (struct frame *f, struct image *img)
/* Create the pixmap. */
xassert (img->pixmap == NO_PIXMAP);
- /* Only W32 version did BLOCK_INPUT here. ++kfs */
- BLOCK_INPUT;
- img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- img->width, img->height,
- DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
- UNBLOCK_INPUT;
+ if (x_check_image_size (0, img->width, img->height))
+ {
+ /* Only W32 version did BLOCK_INPUT here. ++kfs */
+ BLOCK_INPUT;
+ img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ img->width, img->height,
+ DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+ UNBLOCK_INPUT;
+ }
if (!img->pixmap)
{
diff --git a/src/keyboard.c b/src/keyboard.c
index a6fa90163c..7e144b80a0 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -210,8 +210,8 @@ Lisp_Object unread_switch_frame;
/* Last size recorded for a current buffer which is not a minibuffer. */
static EMACS_INT last_non_minibuf_size;
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1. */
-size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
+uintmax_t num_input_events;
/* Value of num_nonmacro_input_events as of last auto save. */
diff --git a/src/keyboard.h b/src/keyboard.h
index 91008a3ea2..69c804c873 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -191,8 +191,8 @@ extern KBOARD *current_kboard;
/* A list of all kboard objects, linked through next_kboard. */
extern KBOARD *all_kboards;
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1. */
-extern size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
+extern uintmax_t num_input_events;
/* Nonzero means polling for input is temporarily suppressed. */
extern int poll_suppress_count;
diff --git a/src/lisp.h b/src/lisp.h
index 762d34abb9..1e141dbb5d 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -61,6 +61,23 @@ extern void check_cons_list (void);
# define EMACS_UINT unsigned EMACS_INT
#endif
+/* printmax_t and uprintmax_t are types for printing large integers.
+ These are the widest integers that are supported for printing.
+ pMd etc. are conversions for printing them.
+ On C99 hosts, there's no problem, as even the widest integers work.
+ Fall back on EMACS_INT on pre-C99 hosts. */
+#ifdef PRIdMAX
+typedef intmax_t printmax_t;
+typedef uintmax_t uprintmax_t;
+# define pMd PRIdMAX
+# define pMu PRIuMAX
+#else
+typedef EMACS_INT printmax_t;
+typedef EMACS_UINT uprintmax_t;
+# define pMd pI"d"
+# define pMu pI"u"
+#endif
+
/* Use pD to format ptrdiff_t values, which suffice for indexes into
buffers and strings. Emacs never allocates objects larger than
PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
@@ -833,7 +850,7 @@ struct Lisp_String
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
struct vectorlike_header
{
- EMACS_UINT size;
+ EMACS_INT size;
/* Pointer to the next vector-like object. It is generally a buffer or a
Lisp_Vector alias, so for convenience it is a union instead of a
@@ -1028,7 +1045,7 @@ struct Lisp_Bool_Vector
struct Lisp_Subr
{
- EMACS_UINT size;
+ EMACS_INT size;
union {
Lisp_Object (*a0) (void);
Lisp_Object (*a1) (Lisp_Object);
@@ -2540,6 +2557,7 @@ extern void sweep_weak_hash_tables (void);
extern Lisp_Object Qcursor_in_echo_area;
extern Lisp_Object Qstring_lessp;
extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql;
+EMACS_UINT hash_string (char const *, ptrdiff_t);
EMACS_UINT sxhash (Lisp_Object, int);
Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
@@ -2868,7 +2886,8 @@ extern void float_to_string (char *, double);
extern void syms_of_print (void);
/* Defined in doprnt.c */
-extern size_t doprnt (char *, size_t, const char *, const char *, va_list);
+extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *,
+ va_list);
/* Defined in lread.c. */
extern Lisp_Object Qvariable_documentation, Qstandard_input;
@@ -3429,18 +3448,6 @@ extern EMACS_INT emacs_read (int, char *, EMACS_INT);
extern EMACS_INT emacs_write (int, const char *, EMACS_INT);
enum { READLINK_BUFSIZE = 1024 };
extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]);
-#ifndef HAVE_MEMSET
-extern void *memset (void *, int, size_t);
-#endif
-#ifndef HAVE_MEMCPY
-extern void *memcpy (void *, void *, size_t);
-#endif
-#ifndef HAVE_MEMMOVE
-extern void *memmove (void *, void *, size_t);
-#endif
-#ifndef HAVE_MEMCMP
-extern int memcmp (void *, void *, size_t);
-#endif
EXFUN (Funlock_buffer, 0);
extern void unlock_all_files (void);
diff --git a/src/lread.c b/src/lread.c
index 83b158d97d..0613ad037b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3648,8 +3648,6 @@ static Lisp_Object initial_obarray;
static size_t oblookup_last_bucket_number;
-static size_t hash_string (const char *ptr, size_t len);
-
/* Get an error if OBARRAY is not an obarray.
If it is one, return it. */
@@ -3892,23 +3890,6 @@ oblookup (Lisp_Object obarray, register const char *ptr, EMACS_INT size, EMACS_I
XSETINT (tem, hash);
return tem;
}
-
-static size_t
-hash_string (const char *ptr, size_t len)
-{
- register const char *p = ptr;
- register const char *end = p + len;
- register unsigned char c;
- register size_t hash = 0;
-
- while (p != end)
- {
- c = *p++;
- if (c >= 0140) c -= 40;
- hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c;
- }
- return hash;
-}
void
map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg)
diff --git a/src/print.c b/src/print.c
index 14b4326bb6..f1907a3146 100644
--- a/src/print.c
+++ b/src/print.c
@@ -46,10 +46,7 @@ static Lisp_Object Qtemp_buffer_setup_hook;
static Lisp_Object Qfloat_output_format;
#include <math.h>
-
-#if STDC_HEADERS
#include <float.h>
-#endif
#include <ftoastr.h>
/* Default to values appropriate for IEEE floating point. */
diff --git a/src/regex.c b/src/regex.c
index 625c59ccf0..190d1d0fe2 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -37,9 +37,9 @@
# include <config.h>
#endif
-#if defined STDC_HEADERS && !defined emacs
-# include <stddef.h>
-#else
+#include <stddef.h>
+
+#ifdef emacs
/* We need this for `regex.h', and perhaps for the Emacs include files. */
# include <sys/types.h>
#endif
@@ -238,18 +238,7 @@ xrealloc (void *block, size_t size)
# endif
# define realloc xrealloc
-/* This is the normal way of making sure we have memcpy, memcmp and memset. */
-# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
-# include <string.h>
-# else
-# include <strings.h>
-# ifndef memcmp
-# define memcmp(s1, s2, n) bcmp (s1, s2, n)
-# endif
-# ifndef memcpy
-# define memcpy(d, s, n) (bcopy (s, d, n), (d))
-# endif
-# endif
+# include <string.h>
/* Define the syntax stuff for \<, \>, etc. */
@@ -357,25 +346,6 @@ enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 };
#else /* not emacs */
-/* Jim Meyering writes:
-
- "... Some ctype macros are valid only for character codes that
- isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
- using /bin/cc or gcc but without giving an ansi option). So, all
- ctype uses should be through macros like ISPRINT... If
- STDC_HEADERS is defined, then autoconf has verified that the ctype
- macros don't need to be guarded with references to isascii. ...
- Defining isascii to 1 should let any compiler worth its salt
- eliminate the && through constant folding."
- Solaris defines some of these symbols so we must undefine them first. */
-
-# undef ISASCII
-# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
-# define ISASCII(c) 1
-# else
-# define ISASCII(c) isascii(c)
-# endif
-
/* 1 if C is an ASCII character. */
# define IS_REAL_ASCII(c) ((c) < 0200)
@@ -383,27 +353,28 @@ enum syntaxcode { Swhitespace = 0, Sword = 1, Ssymbol = 2 };
# define ISUNIBYTE(c) 1
# ifdef isblank
-# define ISBLANK(c) (ISASCII (c) && isblank (c))
+# define ISBLANK(c) isblank (c)
# else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
# endif
# ifdef isgraph
-# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+# define ISGRAPH(c) isgraph (c)
# else
-# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+# define ISGRAPH(c) (isprint (c) && !isspace (c))
# endif
+/* Solaris defines ISPRINT so we must undefine it first. */
# undef ISPRINT
-# define ISPRINT(c) (ISASCII (c) && isprint (c))
-# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
-# define ISALNUM(c) (ISASCII (c) && isalnum (c))
-# define ISALPHA(c) (ISASCII (c) && isalpha (c))
-# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
-# define ISLOWER(c) (ISASCII (c) && islower (c))
-# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
-# define ISSPACE(c) (ISASCII (c) && isspace (c))
-# define ISUPPER(c) (ISASCII (c) && isupper (c))
-# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+# define ISPRINT(c) isprint (c)
+# define ISDIGIT(c) isdigit (c)
+# define ISALNUM(c) isalnum (c)
+# define ISALPHA(c) isalpha (c)
+# define ISCNTRL(c) iscntrl (c)
+# define ISLOWER(c) islower (c)
+# define ISPUNCT(c) ispunct (c)
+# define ISSPACE(c) isspace (c)
+# define ISUPPER(c) isupper (c)
+# define ISXDIGIT(c) isxdigit (c)
# define ISWORD(c) ISALPHA(c)
@@ -450,10 +421,6 @@ init_syntax_once (void)
#endif /* not emacs */
-#ifndef NULL
-# define NULL (void *)0
-#endif
-
/* We remove any previous definition of `SIGN_EXTEND_CHAR',
since ours (we hope) works properly with all combinations of
machines, compilers, `char' and `unsigned char' argument types.
diff --git a/src/s/aix4-2.h b/src/s/aix4-2.h
index c2715fffe0..b44bd0308a 100644
--- a/src/s/aix4-2.h
+++ b/src/s/aix4-2.h
@@ -47,11 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* AIX doesn't define this. */
#define unix 1
-/* string.h defines rindex as a macro, at least with native cc, so we
- lose declaring char * rindex without this.
- It is just a guess which versions of AIX need this definition. */
-#undef HAVE_STRING_H
-
/* Perry Smith <[email protected]> says these are correct. */
#define SIGNALS_VIA_CHARACTERS
#define CLASH_DETECTION
diff --git a/src/s/ms-w32.h b/src/s/ms-w32.h
index bf6cc66798..813c3cef11 100644
--- a/src/s/ms-w32.h
+++ b/src/s/ms-w32.h
@@ -111,11 +111,7 @@ struct sigaction {
#undef HAVE_UTIME_H
#undef HAVE_LINUX_VERSION_H
#undef HAVE_SYS_SYSTEMINFO_H
-#define HAVE_LIMITS_H 1
-#define HAVE_STRING_H 1
-#define HAVE_STDLIB_H 1
#define HAVE_PWD_H 1
-#define STDC_HEADERS 1
#define TIME_WITH_SYS_TIME 1
#define HAVE_GETTIMEOFDAY 1
@@ -386,4 +382,3 @@ extern void _DebPrint (const char *fmt, ...);
/* ============================================================ */
-
diff --git a/src/sysdep.c b/src/sysdep.c
index fc2f846b0d..4bd1f54b9e 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -26,9 +26,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <pwd.h>
#include <grp.h>
#endif /* HAVE_PWD_H */
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif /* HAVE_LIMITS_H */
#include <unistd.h>
#include <allocator.h>
@@ -2215,59 +2213,6 @@ rmdir (char *dpath)
#endif /* !HAVE_RMDIR */
-#ifndef HAVE_MEMSET
-void *
-memset (void *b, int n, size_t length)
-{
- unsigned char *p = b;
- while (length-- > 0)
- *p++ = n;
- return b;
-}
-#endif /* !HAVE_MEMSET */
-
-#ifndef HAVE_MEMCPY
-void *
-memcpy (void *b1, void *b2, size_t length)
-{
- unsigned char *p1 = b1, *p2 = b2;
- while (length-- > 0)
- *p1++ = *p2++;
- return b1;
-}
-#endif /* !HAVE_MEMCPY */
-
-#ifndef HAVE_MEMMOVE
-void *
-memmove (void *b1, void *b2, size_t length)
-{
- unsigned char *p1 = b1, *p2 = b2;
- if (p1 < p2 || p1 >= p2 + length)
- while (length-- > 0)
- *p1++ = *p2++;
- else
- {
- p1 += length;
- p2 += length;
- while (length-- > 0)
- *--p1 = *--p2;
- }
- return b1;
-}
-#endif /* !HAVE_MEMCPY */
-
-#ifndef HAVE_MEMCMP
-int
-memcmp (void *b1, void *b2, size_t length)
-{
- unsigned char *p1 = b1, *p2 = b2;
- while (length-- > 0)
- if (*p1++ != *p2++)
- return p1[-1] < p2[-1] ? -1 : 1;
- return 0;
-}
-#endif /* !HAVE_MEMCMP */
-
#ifndef HAVE_STRSIGNAL
char *
strsignal (int code)
diff --git a/src/xdisp.c b/src/xdisp.c
index 7493fbff00..8f35256171 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8842,7 +8842,7 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
if (nlflag)
{
EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
- intmax_t dups;
+ printmax_t dups;
insert_1 ("\n", 1, 1, 0, 0);
scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
@@ -8866,12 +8866,12 @@ message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
if (dups > 1)
{
char dupstr[sizeof " [ times]"
- + INT_STRLEN_BOUND (intmax_t)];
+ + INT_STRLEN_BOUND (printmax_t)];
int duplen;
/* If you change this format, don't forget to also
change message_log_check_duplicate. */
- sprintf (dupstr, " [%"PRIdMAX" times]", dups);
+ sprintf (dupstr, " [%"pMd" times]", dups);
duplen = strlen (dupstr);
TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
insert_1 (dupstr, duplen, 1, 0, 1);
@@ -9264,7 +9264,7 @@ vmessage (const char *m, va_list ap)
{
if (m)
{
- size_t len;
+ ptrdiff_t len;
len = doprnt (FRAME_MESSAGE_BUF (f),
FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
diff --git a/src/xfaces.c b/src/xfaces.c
index 32729ce6f8..52b125b42e 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -940,11 +940,13 @@ the pixmap. Bits are stored row by row, each row occupies
}
}
- if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
+ if (STRINGP (data)
+ && INTEGERP (width) && 0 < XINT (width)
+ && INTEGERP (height) && 0 < XINT (height))
{
- int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
- / BITS_PER_CHAR);
- if (SBYTES (data) >= bytes_per_row * XINT (height))
+ EMACS_INT bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
+ / BITS_PER_CHAR);
+ if (XINT (height) <= SBYTES (data) / bytes_per_row)
pixmap_p = 1;
}
}
diff --git a/src/xselect.c b/src/xselect.c
index 5e5bdb55ec..f63977a73d 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2381,7 +2381,7 @@ FRAME is on. If FRAME is nil, the selected frame is used. */)
{
Atom x_atom;
struct frame *f = check_x_frame (frame);
- size_t i;
+ ptrdiff_t i;
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -2402,6 +2402,9 @@ FRAME is on. If FRAME is nil, the selected frame is used. */)
if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
{
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2
+ < dpyinfo->x_dnd_atoms_size)
+ memory_full (SIZE_MAX);
dpyinfo->x_dnd_atoms_size *= 2;
dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
sizeof (*dpyinfo->x_dnd_atoms)
@@ -2424,7 +2427,7 @@ x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_disp
int x, y;
unsigned char *data = (unsigned char *) event->data.b;
int idata[5];
- size_t i;
+ ptrdiff_t i;
for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
diff --git a/src/xterm.h b/src/xterm.h
index a4767361bb..3086765671 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -326,8 +326,8 @@ struct x_display_info
/* Atoms that are drag and drop atoms */
Atom *x_dnd_atoms;
- size_t x_dnd_atoms_size;
- size_t x_dnd_atoms_length;
+ ptrdiff_t x_dnd_atoms_size;
+ ptrdiff_t x_dnd_atoms_length;
/* Extended window manager hints, Atoms supported by the window manager and
atoms for settig the window type. */