summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2026-05-23 09:59:25 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2026-05-23 19:18:53 -0700
commit2e91ed5f129a4c03f7345d15d61232bd15028a4e (patch)
treec0e4eb4ba15603ba56762a3b23c77162284d5121
parent82ad01b631a4ff4508bb3d37d32925d0cc6771ee (diff)
Prefer ptrdiff_t to size_t when either will do
Signed types are a bit safer, as they avoid some comparison confusion and -fsanitize=undefined can check more misuses of them. * src/alloc.c (lisp_malloc, lisp_align_malloc) (allocate_string_data, allocate_vector_from_block, object_bytes): * src/coding.c (from_unicode_buffer): * src/decompress.c (acc_size, accumulate_and_process_md5): * src/emacs.c (load_seccomp, shut_down_emacs): * src/fns.c (sxhash_bignum): * src/ftfont.c (get_adstyle_property): * src/image.c (lookup_image, xpm_init_color_cache) (xpm_cache_color): * src/json.c (json_out_str, struct json_parser) (json_make_object_workspace_for_slow_path) (json_make_object_workspace_for, json_parse_array) (json_parse_object): * src/sysdep.c (get_current_dir_name_or_unreachable) (init_sys_modes, convert_speed): * src/termchar.h (struct tty_display_info): * src/textconv.h (struct textconv_conversion_text): * src/xfns.c (struct x_xim_text_conversion_data) (x_encode_xim_text): * src/xselect.c (struct transfer, c_size_for_format) (x_size_for_format, selection_data_for_offset) (selection_data_size, x_start_selection_transfer) (x_continue_selection_transfer): Prefer ptrdiff_t to size_t when either will do. * src/term.c (Ftty__set_output_buffer_size): Limit output buffer size to PTRDIFF_MAX as well as to SIZE_MAX.
-rw-r--r--src/alloc.c16
-rw-r--r--src/coding.c12
-rw-r--r--src/decompress.c4
-rw-r--r--src/emacs.c28
-rw-r--r--src/fns.c6
-rw-r--r--src/ftfont.c3
-rw-r--r--src/image.c8
-rw-r--r--src/json.c26
-rw-r--r--src/sysdep.c10
-rw-r--r--src/term.c2
-rw-r--r--src/termchar.h2
-rw-r--r--src/textconv.h2
-rw-r--r--src/xfns.c4
-rw-r--r--src/xselect.c30
14 files changed, 71 insertions, 82 deletions
diff --git a/src/alloc.c b/src/alloc.c
index d6f11d06766..ed0d6f4976d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -899,7 +899,7 @@ void *lisp_malloc_loser EXTERNALLY_VISIBLE;
L == make_lisp_ptr (P, T), then XPNTR (L) == P and XTYPE (L) == T. */
static void *
-lisp_malloc (size_t nbytes, bool clearit, enum mem_type type)
+lisp_malloc (ptrdiff_t nbytes, bool clearit, enum mem_type type)
{
register void *val;
@@ -1083,7 +1083,7 @@ pointer_align (void *ptr, int alignment)
Alignment is on a multiple of BLOCK_ALIGN and `nbytes' has to be
smaller or equal to BLOCK_BYTES. */
static void *
-lisp_align_malloc (size_t nbytes, enum mem_type type)
+lisp_align_malloc (ptrdiff_t nbytes, enum mem_type type)
{
void *base, *val;
struct ablocks *abase;
@@ -1522,7 +1522,7 @@ sdata_size (ptrdiff_t n)
/* Exact bound on the number of bytes in a string, not counting the
terminating null. A string cannot contain more bytes than
- STRING_BYTES_BOUND, nor can it be so long that the size_t
+ STRING_BYTES_BOUND, nor can it be so long that the
arithmetic in allocate_string_data would overflow while it is
calculating a value to be passed to malloc. */
static ptrdiff_t const STRING_BYTES_MAX =
@@ -1768,7 +1768,7 @@ allocate_string_data (struct Lisp_String *s,
if (nbytes > LARGE_STRING_BYTES || immovable)
{
- size_t size = FLEXSIZEOF (struct sblock, data, needed);
+ ptrdiff_t size = FLEXSIZEOF (struct sblock, data, needed);
#ifdef DOUG_LEA_MALLOC
if (!mmap_lisp_allowed_p ())
@@ -2996,7 +2996,7 @@ allocate_vector_from_block (ptrdiff_t nbytes)
{
struct Lisp_Vector *vector;
struct vector_block *block;
- size_t index, restbytes;
+ ptrdiff_t index, restbytes;
eassume (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX);
eassume (nbytes % roundup_size == 0);
@@ -3022,7 +3022,7 @@ allocate_vector_from_block (ptrdiff_t nbytes)
{
/* This vector is larger than requested. */
vector = vector_free_lists[index];
- size_t vector_nbytes = pseudovector_nbytes (&vector->header);
+ ptrdiff_t vector_nbytes = pseudovector_nbytes (&vector->header);
eassert (vector_nbytes > nbytes);
ASAN_UNPOISON_VECTOR_CONTENTS (vector, nbytes - header_size);
vector_free_lists[index] = next_vector (vector);
@@ -5465,10 +5465,10 @@ inhibit_garbage_collection (void)
}
/* Return the number of bytes in N objects each of size S, guarding
- against overflow if size_t is narrower than byte_ct. */
+ against overflow if ptrdiff_t is narrower than byte_ct. */
static byte_ct
-object_bytes (object_ct n, size_t s)
+object_bytes (object_ct n, ptrdiff_t s)
{
byte_ct b = s;
return n * b;
diff --git a/src/coding.c b/src/coding.c
index 9aba2a7eacc..7d2c7040ab8 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -8554,19 +8554,17 @@ from_unicode_buffer (const wchar_t *wstr)
strings are extended to 32-bit wchar_t. */
uint16_t *words;
- size_t length, i;
-
- length = wcslen (wstr) + 1;
+ ptrdiff_t length = wcslen (wstr);
USE_SAFE_ALLOCA;
- SAFE_NALLOCA (words, sizeof *words, length);
+ SAFE_NALLOCA (words, sizeof *words, length + 1);
- for (i = 0; i < length - 1; ++i)
+ for (ptrdiff_t i = 0; i < length; i++)
words[i] = wstr[i];
+ words[length] = '\0';
- words[i] = '\0';
AUTO_STRING_WITH_LEN (str, (char *) words,
- (length - 1) * sizeof *words);
+ length * sizeof *words);
return unbind_to (sa_count, from_unicode (str));
#endif
}
diff --git a/src/decompress.c b/src/decompress.c
index c81559c25f0..bb3ed6d7d6d 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -70,10 +70,10 @@ init_zlib_functions (void)
# define MD5_BLOCKSIZE 32768 /* From md5.c */
static char acc_buff[2 * MD5_BLOCKSIZE];
-static size_t acc_size;
+static ptrdiff_t acc_size;
static void
-accumulate_and_process_md5 (void *data, size_t len, struct md5_ctx *ctxt)
+accumulate_and_process_md5 (void *data, ptrdiff_t len, struct md5_ctx *ctxt)
{
eassert (len <= MD5_BLOCKSIZE);
/* We may optimize this saving some of these memcpy/move using
diff --git a/src/emacs.c b/src/emacs.c
index a9b970effb4..d50f817cefc 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1235,39 +1235,33 @@ load_seccomp (const char *file)
file, (long) stat.st_size);
goto out;
}
- size_t size = stat.st_size;
- size_t count = size / sizeof *program.filter;
- eassert (0 < count && count < SIZE_MAX);
- if (USHRT_MAX < count)
+ if (ckd_add (&program.len, stat.st_size / sizeof *program.filter, 0))
{
fprintf (stderr, "seccomp filter %s is too big\n", file);
goto out;
}
/* Try reading one more byte to detect file size changes. */
+ ptrdiff_t size = stat.st_size;
buffer = malloc (size + 1);
if (buffer == NULL)
{
emacs_perror ("malloc");
goto out;
}
- ptrdiff_t read = read_full (fd, buffer, size + 1);
- if (read < 0)
+ ptrdiff_t nread = read_full (fd, buffer, size + 1);
+ if (nread != size)
{
- emacs_perror ("read");
- goto out;
- }
- eassert (read <= SIZE_MAX);
- if (read != size)
- {
- fprintf (stderr,
- "seccomp filter %s changed size while reading\n",
- file);
+ if (nread < 0)
+ emacs_perror ("read");
+ else
+ fprintf (stderr,
+ "seccomp filter %s changed size while reading\n",
+ file);
goto out;
}
if (emacs_close (fd) != 0)
emacs_perror ("close"); /* not a fatal error */
fd = -1;
- program.len = count;
program.filter = buffer;
/* See man page of `seccomp' why this is necessary. Note that we
@@ -3131,7 +3125,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
+ INT_STRLEN_BOUND (int) + 1),
min (PIPE_BUF, MAX_ALLOCA))];
char const *sig_desc = safe_strsignal (sig);
- size_t sig_desclen = strlen (sig_desc);
+ ptrdiff_t sig_desclen = strlen (sig_desc);
int nlen = sprintf (buf, fmt, sig);
if (nlen + sig_desclen < sizeof buf - 1)
{
diff --git a/src/fns.c b/src/fns.c
index 98671fc1318..e3d297102ca 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5480,10 +5480,10 @@ static EMACS_UINT
sxhash_bignum (Lisp_Object bignum)
{
mpz_t const *n = xbignum_val (bignum);
- size_t i, nlimbs = mpz_size (*n);
- EMACS_UINT hash = mpz_sgn(*n) < 0;
+ ptrdiff_t nlimbs = mpz_size (*n);
+ EMACS_UINT hash = mpz_sgn (*n) < 0;
- for (i = 0; i < nlimbs; ++i)
+ for (ptrdiff_t i = 0; i < nlimbs; i++)
hash = sxhash_combine (hash, mpz_getlimbn (*n, i));
return hash;
diff --git a/src/ftfont.c b/src/ftfont.c
index 6de7110e5bb..44c22d359b5 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -150,7 +150,6 @@ get_adstyle_property (FcPattern *p)
{
FcChar8 *fcstr;
char *str, *end, *tmp;
- size_t i;
Lisp_Object adstyle;
#ifdef FC_FONTFORMAT
@@ -173,7 +172,7 @@ get_adstyle_property (FcPattern *p)
and therefore must be replaced by substitutes. (bug#70989) */
USE_SAFE_ALLOCA;
tmp = SAFE_ALLOCA (end - str);
- for (i = 0; i < end - str; ++i)
+ for (ptrdiff_t i = 0; i < end - str; i++)
tmp[i] = ((str[i] != '?'
&& str[i] != '*'
&& str[i] != '"'
diff --git a/src/image.c b/src/image.c
index 38f9d1416a7..f41a08eb1a8 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3562,7 +3562,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
img->face_font_size = font_size;
img->face_font_height = face->font->height;
img->face_font_width = face->font->average_width;
- size_t len = strlen (font_family) + 1;
+ ptrdiff_t len = strlen (font_family) + 1;
img->face_font_family = xmalloc (len);
memcpy (img->face_font_family, font_family, len);
img->load_failed_p = ! img->type->load_img (f, img);
@@ -5538,7 +5538,7 @@ static struct xpm_cached_color **xpm_color_cache;
static void
xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
{
- size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
+ ptrdiff_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
xpm_color_cache = xzalloc (nbytes);
init_color_table ();
@@ -5598,8 +5598,8 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
if (bucket < 0)
bucket = xpm_color_bucket (color_name);
- size_t len = strlen (color_name) + 1;
- size_t nbytes = FLEXSIZEOF (struct xpm_cached_color, name, len);
+ ptrdiff_t len = strlen (color_name) + 1;
+ ptrdiff_t nbytes = FLEXSIZEOF (struct xpm_cached_color, name, len);
struct xpm_cached_color *p = xmalloc (nbytes);
memcpy (p->name, color_name, len);
p->color = *color;
diff --git a/src/json.c b/src/json.c
index 720654bac43..5186667a9d2 100644
--- a/src/json.c
+++ b/src/json.c
@@ -273,7 +273,7 @@ json_make_room (json_out_t *jo, ptrdiff_t bytes)
/* Add `bytes` bytes from `str` to the buffer. */
static void
-json_out_str (json_out_t *jo, const char *str, size_t bytes)
+json_out_str (json_out_t *jo, const char *str, ptrdiff_t bytes)
{
json_make_room (jo, bytes);
memcpy (jo->buf + jo->size, str, bytes);
@@ -693,7 +693,7 @@ struct json_parser
struct json_configuration conf;
- size_t additional_bytes_count;
+ ptrdiff_t additional_bytes_count;
/* Lisp_Objects are collected in this area during object/array
parsing. To avoid allocations, initially
@@ -704,8 +704,8 @@ struct json_parser
Lisp_Object internal_object_workspace
[JSON_PARSER_INTERNAL_OBJECT_WORKSPACE_SIZE];
Lisp_Object *object_workspace;
- size_t object_workspace_size;
- size_t object_workspace_current;
+ ptrdiff_t object_workspace_size;
+ ptrdiff_t object_workspace_current;
/* String and number parsing uses this workspace. The idea behind
internal_byte_workspace is the same as the idea behind
@@ -805,10 +805,9 @@ json_make_object_workspace_for_slow_path (struct json_parser *parser,
{
bool internal = (parser->object_workspace_size
== JSON_PARSER_INTERNAL_OBJECT_WORKSPACE_SIZE);
- ptrdiff_t new_workspace_size = parser->object_workspace_size;
Lisp_Object *new_workspace_ptr
= xpalloc (internal ? NULL : parser->object_workspace,
- &new_workspace_size,
+ &parser->object_workspace_size,
size - (parser->object_workspace_size
- parser->object_workspace_current),
-1, sizeof (Lisp_Object));
@@ -816,12 +815,11 @@ json_make_object_workspace_for_slow_path (struct json_parser *parser,
memcpy (new_workspace_ptr, parser->object_workspace,
sizeof (Lisp_Object) * parser->object_workspace_current);
parser->object_workspace = new_workspace_ptr;
- parser->object_workspace_size = new_workspace_size;
}
INLINE void
json_make_object_workspace_for (struct json_parser *parser,
- size_t size)
+ ptrdiff_t size)
{
if (parser->object_workspace_size - parser->object_workspace_current
< size)
@@ -1350,7 +1348,7 @@ json_parse_array (struct json_parser *parser)
{
int c = json_skip_whitespace (parser);
- const size_t first = parser->object_workspace_current;
+ const ptrdiff_t first = parser->object_workspace_current;
Lisp_Object result = Qnil;
if (c != ']')
@@ -1402,10 +1400,10 @@ json_parse_array (struct json_parser *parser)
{
case json_array_array:
{
- size_t number_of_elements
+ ptrdiff_t number_of_elements
= parser->object_workspace_current - first;
result = make_vector (number_of_elements, Qnil);
- for (size_t i = 0; i < number_of_elements; i++)
+ for (ptrdiff_t i = 0; i < number_of_elements; i++)
{
rarely_quit (i);
ASET (result, i, parser->object_workspace[first + i]);
@@ -1441,7 +1439,7 @@ json_parse_object (struct json_parser *parser)
{
int c = json_skip_whitespace (parser);
- const size_t first = parser->object_workspace_current;
+ const ptrdiff_t first = parser->object_workspace_current;
Lisp_Object result = Qnil;
if (c != '}')
@@ -1517,10 +1515,10 @@ json_parse_object (struct json_parser *parser)
{
case json_object_hashtable:
{
- EMACS_INT value = (parser->object_workspace_current - first) / 2;
+ EMACS_INT value = (parser->object_workspace_current - first) >> 1;
result = make_hash_table (&hashtest_equal, value, Weak_None);
struct Lisp_Hash_Table *h = XHASH_TABLE (result);
- for (size_t i = first; i < parser->object_workspace_current; i += 2)
+ for (ptrdiff_t i = first; i < parser->object_workspace_current; i += 2)
{
hash_hash_t hash;
Lisp_Object key = parser->object_workspace[i];
diff --git a/src/sysdep.c b/src/sysdep.c
index b2cd769784c..2f48b7c6681 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -304,7 +304,7 @@ get_current_dir_name_or_unreachable (void)
}
# endif
- size_t pwdlen;
+ ptrdiff_t pwdlen;
struct stat dotstat, pwdstat;
pwd = getenv ("PWD");
@@ -1310,9 +1310,9 @@ init_sys_modes (struct tty_display_info *tty_out)
}
#endif /* F_GETOWN */
- const size_t buffer_size = (tty_out->output_buffer_size
- ? tty_out->output_buffer_size
- : BUFSIZ);
+ const ptrdiff_t buffer_size = (tty_out->output_buffer_size
+ ? tty_out->output_buffer_size
+ : BUFSIZ);
setvbuf (tty_out->output, NULL, _IOFBF, buffer_size);
if (tty_out->terminal->set_terminal_modes_hook)
@@ -3136,7 +3136,7 @@ static const struct speed_struct speeds[] =
static speed_t
convert_speed (speed_t speed)
{
- for (size_t i = 0; i < ARRAYELTS (speeds); i++)
+ for (ptrdiff_t i = 0; i < ARRAYELTS (speeds); i++)
{
if (speed == speeds[i].internal)
return speed;
diff --git a/src/term.c b/src/term.c
index e4fdb85831c..8047e4102a1 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2613,7 +2613,7 @@ This function temporarily suspends and resumes the terminal
device. */)
(Lisp_Object size, Lisp_Object tty)
{
- if (!TYPE_RANGED_FIXNUMP (size_t, size))
+ if (!RANGED_FIXNUMP (0, size, min (PTRDIFF_MAX, SIZE_MAX)))
error ("Invalid output buffer size");
Fsuspend_tty (tty);
struct terminal *terminal = decode_tty_terminal (tty);
diff --git a/src/termchar.h b/src/termchar.h
index d9390db17b2..5bc2dd84bee 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -56,7 +56,7 @@ struct tty_display_info
/* Size of output buffer. A value of zero means use the default of
BUFIZE. If non-zero, also minimize writes to the tty by avoiding
calls to flush. */
- size_t output_buffer_size;
+ ptrdiff_t output_buffer_size;
FILE *termscript; /* If nonzero, send all terminal output
characters to this stream also. */
diff --git a/src/textconv.h b/src/textconv.h
index bd6bf06bb76..5ab2c052fa3 100644
--- a/src/textconv.h
+++ b/src/textconv.h
@@ -80,7 +80,7 @@ enum textconv_operation
struct textconv_conversion_text
{
/* Length of the text in characters and bytes. */
- size_t length, bytes;
+ ptrdiff_t length, bytes;
/* Pointer to the text data. This must be deallocated by the
caller. */
diff --git a/src/xfns.c b/src/xfns.c
index ba3bf211f55..976218819dd 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3467,7 +3467,7 @@ struct x_xim_text_conversion_data
struct coding_system *coding;
char *source;
struct x_display_info *dpyinfo;
- size_t size;
+ ptrdiff_t size;
};
static Lisp_Object
@@ -3600,7 +3600,7 @@ x_xim_text_to_utf8_unix (struct x_display_info *dpyinfo,
static char *
x_encode_xim_text (struct x_display_info *dpyinfo, char *text,
- size_t size, ptrdiff_t *length,
+ ptrdiff_t size, ptrdiff_t *length,
ptrdiff_t *chars)
{
struct coding_system coding;
diff --git a/src/xselect.c b/src/xselect.c
index 9e343f16544..27b83825b34 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -522,7 +522,7 @@ struct transfer
/* The current offset in items into the selection data, and the
number of items to send with each ChangeProperty request. */
- size_t offset, items_per_request;
+ ptrdiff_t offset, items_per_request;
/* The display info associated with the transfer. */
struct x_display_info *dpyinfo;
@@ -669,7 +669,7 @@ x_selection_request_lisp_error (void)
-static size_t
+static ptrdiff_t
c_size_for_format (int format)
{
switch (format)
@@ -687,7 +687,7 @@ c_size_for_format (int format)
emacs_abort ();
}
-static size_t
+static ptrdiff_t
x_size_for_format (int format)
{
switch (format)
@@ -712,10 +712,10 @@ x_size_for_format (int format)
static unsigned char *
selection_data_for_offset (struct selection_data *data,
- size_t offset, size_t *remaining)
+ ptrdiff_t offset, ptrdiff_t *remaining)
{
unsigned char *base;
- size_t size;
+ ptrdiff_t size;
if (!NILP (data->string))
{
@@ -746,10 +746,10 @@ selection_data_for_offset (struct selection_data *data,
FIXME: Silent truncation is bad. */
-static size_t
+static ptrdiff_t
selection_data_size (struct selection_data *data)
{
- size_t scratch;
+ ptrdiff_t scratch;
ptrdiff_t max_selection_size = min (min (PTRDIFF_MAX, SIZE_MAX),
X_ULONG_MAX);
@@ -856,7 +856,7 @@ x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
intmax_t timeout;
intmax_t secs;
int nsecs;
- size_t remaining, max_size;
+ ptrdiff_t remaining, max_size;
unsigned char *xdata;
unsigned long data_size;
@@ -892,9 +892,9 @@ x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
max_size = selection_quantum (dpyinfo->display);
- size_t seldata_size = selection_data_size (&transfer->data);
+ ptrdiff_t seldata_size = selection_data_size (&transfer->data);
TRACE3 (" x_start_selection_transfer: transferring to 0x%lx. "
- "transfer consists of %zu bytes, quantum being %zu",
+ "transfer consists of %tu bytes, quantum being %tu",
requestor, seldata_size, max_size);
if (max_size < seldata_size)
@@ -905,7 +905,7 @@ x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
transfer->items_per_request
= (max_size / x_size_for_format (transfer->data.format));
TRACE1 (" x_start_selection_transfer: starting incremental"
- " selection transfer, with %zu items per request",
+ " selection transfer, with %tu items per request",
transfer->items_per_request);
/* Next, link the transfer onto the list of pending selection
@@ -954,7 +954,7 @@ x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
eassert (remaining <= INT_MAX);
TRACE1 (" x_start_selection_transfer: writing"
- " %zu elements directly to requestor window",
+ " %tu elements directly to requestor window",
remaining);
x_ignore_errors_for_next_request (dpyinfo, 0);
@@ -977,7 +977,7 @@ x_start_selection_transfer (struct x_display_info *dpyinfo, Window requestor,
static void
x_continue_selection_transfer (struct transfer *transfer)
{
- size_t remaining;
+ ptrdiff_t remaining;
unsigned char *xdata;
xdata = selection_data_for_offset (&transfer->data,
@@ -1006,8 +1006,8 @@ x_continue_selection_transfer (struct transfer *transfer)
}
else
{
- TRACE2 (" x_continue_selection_transfer: writing %zu items"
- "; current offset is %zu", remaining, transfer->offset);
+ TRACE2 (" x_continue_selection_transfer: writing %tu items"
+ "; current offset is %tu", remaining, transfer->offset);
eassert (remaining <= INT_MAX);
transfer->offset += remaining;