diff options
| author | Paul Eggert | 2019-01-10 21:35:31 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-01-10 21:39:56 -0800 |
| commit | 470082de55f7b1c1cde8aabbb5b8de55b4b08f83 (patch) | |
| tree | 73f67a8951cdeb998a822fd38a6abd242b16199a /src/alloc.c | |
| parent | 9609db9d98babfe8782a03aebe46176e57905c63 (diff) | |
| download | emacs-470082de55f7b1c1cde8aabbb5b8de55b4b08f83.tar.gz emacs-470082de55f7b1c1cde8aabbb5b8de55b4b08f83.zip | |
List lengths are always fixnums now
Without this patch, it was theoretically possible for a list
length to be a bignum, which means that safe-length could
signal an error (due to generating a too-large bignum) contrary
to its documentation. Fix things to remove the theoretical
possibility, so that list lengths are always fixnums (and so
that list lenghts are always ptrdiff_t values too, since that
is assumed internally anyway).
* src/alloc.c (Fcons): Do not allocate so many conses that
a list length won’t fit into ptrdiff_t or into fixnum.
This matters only on weird platforms; on typical platforms,
list lengths always fit anyway.
* src/fns.c (list_length, Fsafe_length, proper-list-p):
Remove integer overflow checks that are no longer needed.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/alloc.c b/src/alloc.c index 407ac725414..31e8da70161 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2774,6 +2774,19 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2774 | { | 2774 | { |
| 2775 | if (cons_block_index == CONS_BLOCK_SIZE) | 2775 | if (cons_block_index == CONS_BLOCK_SIZE) |
| 2776 | { | 2776 | { |
| 2777 | /* Maximum number of conses that should be active at any | ||
| 2778 | given time, so that list lengths fit into a ptrdiff_t and | ||
| 2779 | into a fixnum. */ | ||
| 2780 | ptrdiff_t max_conses = min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM); | ||
| 2781 | |||
| 2782 | /* This check is typically optimized away, as a runtime | ||
| 2783 | check is needed only on weird platforms where a count of | ||
| 2784 | distinct conses might not fit. */ | ||
| 2785 | if (max_conses < INTPTR_MAX / sizeof (struct Lisp_Cons) | ||
| 2786 | && (max_conses - CONS_BLOCK_SIZE | ||
| 2787 | < total_free_conses + total_conses)) | ||
| 2788 | memory_full (sizeof (struct cons_block)); | ||
| 2789 | |||
| 2777 | struct cons_block *new | 2790 | struct cons_block *new |
| 2778 | = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); | 2791 | = lisp_align_malloc (sizeof *new, MEM_TYPE_CONS); |
| 2779 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); | 2792 | memset (new->gcmarkbits, 0, sizeof new->gcmarkbits); |