diff options
| author | Paul Eggert | 2018-12-08 16:56:32 -0800 |
|---|---|---|
| committer | Paul Eggert | 2018-12-08 16:58:40 -0800 |
| commit | 7bcea8f8c11d10fd189c4250042dfe68e2df8c3a (patch) | |
| tree | 3676ecf2fccc0b7c4dede99487274931c1214784 /src/alloc.c | |
| parent | a9732737f2b48a78de72d67f6ed950495788ed1d (diff) | |
| download | emacs-7bcea8f8c11d10fd189c4250042dfe68e2df8c3a.tar.gz emacs-7bcea8f8c11d10fd189c4250042dfe68e2df8c3a.zip | |
Streamline and fix vector-size checks
* src/alloc.c (VECTOR_ELTS_MAX): New constant.
(allocate_vectorlike): LEN now must be positive. Assume LEN
is in range. All callers changed.
(allocate_vector): Arg is now ptrdiff_t, not EMACS_INT.
All callers changed. Return zero vector here, not in
allocate_vectorlike.
* src/lisp.h (make_uninit_vector): Simplify.
* src/xwidget.c (webkit_js_to_lisp):
Check for overflow in ptrdiff_t calculations.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/src/alloc.c b/src/alloc.c index 8eaa810e53a..3bc9277a7b2 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2398,6 +2398,8 @@ make_uninit_bool_vector (EMACS_INT nbits) | |||
| 2398 | EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes | 2398 | EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes |
| 2399 | + word_size - 1) | 2399 | + word_size - 1) |
| 2400 | / word_size); | 2400 | / word_size); |
| 2401 | if (PTRDIFF_MAX < needed_elements) | ||
| 2402 | memory_full (SIZE_MAX); | ||
| 2401 | struct Lisp_Bool_Vector *p | 2403 | struct Lisp_Bool_Vector *p |
| 2402 | = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); | 2404 | = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); |
| 2403 | XSETVECTOR (val, p); | 2405 | XSETVECTOR (val, p); |
| @@ -3334,67 +3336,68 @@ sweep_vectors (void) | |||
| 3334 | } | 3336 | } |
| 3335 | } | 3337 | } |
| 3336 | 3338 | ||
| 3339 | static ptrdiff_t const VECTOR_ELTS_MAX | ||
| 3340 | = min (((min (PTRDIFF_MAX, SIZE_MAX) - header_size - large_vector_offset) | ||
| 3341 | / word_size), | ||
| 3342 | MOST_POSITIVE_FIXNUM); | ||
| 3343 | |||
| 3337 | /* Value is a pointer to a newly allocated Lisp_Vector structure | 3344 | /* Value is a pointer to a newly allocated Lisp_Vector structure |
| 3338 | with room for LEN Lisp_Objects. */ | 3345 | with room for LEN Lisp_Objects. LEN must be positive and |
| 3346 | at most VECTOR_ELTS_MAX. */ | ||
| 3339 | 3347 | ||
| 3340 | static struct Lisp_Vector * | 3348 | static struct Lisp_Vector * |
| 3341 | allocate_vectorlike (ptrdiff_t len) | 3349 | allocate_vectorlike (ptrdiff_t len) |
| 3342 | { | 3350 | { |
| 3343 | if (len == 0) | 3351 | eassert (0 < len && len <= VECTOR_ELTS_MAX); |
| 3344 | return XVECTOR (zero_vector); | 3352 | size_t nbytes = header_size + len * word_size; |
| 3345 | else | 3353 | struct Lisp_Vector *p; |
| 3346 | { | ||
| 3347 | size_t nbytes = header_size + len * word_size; | ||
| 3348 | struct Lisp_Vector *p; | ||
| 3349 | 3354 | ||
| 3350 | MALLOC_BLOCK_INPUT; | 3355 | MALLOC_BLOCK_INPUT; |
| 3351 | 3356 | ||
| 3352 | #ifdef DOUG_LEA_MALLOC | 3357 | #ifdef DOUG_LEA_MALLOC |
| 3353 | if (!mmap_lisp_allowed_p ()) | 3358 | if (!mmap_lisp_allowed_p ()) |
| 3354 | mallopt (M_MMAP_MAX, 0); | 3359 | mallopt (M_MMAP_MAX, 0); |
| 3355 | #endif | 3360 | #endif |
| 3356 | 3361 | ||
| 3357 | if (nbytes <= VBLOCK_BYTES_MAX) | 3362 | if (nbytes <= VBLOCK_BYTES_MAX) |
| 3358 | p = allocate_vector_from_block (vroundup (nbytes)); | 3363 | p = allocate_vector_from_block (vroundup (nbytes)); |
| 3359 | else | 3364 | else |
| 3360 | { | 3365 | { |
| 3361 | struct large_vector *lv = lisp_malloc (large_vector_offset + nbytes, | 3366 | struct large_vector *lv = lisp_malloc (large_vector_offset + nbytes, |
| 3362 | MEM_TYPE_VECTORLIKE); | 3367 | MEM_TYPE_VECTORLIKE); |
| 3363 | lv->next = large_vectors; | 3368 | lv->next = large_vectors; |
| 3364 | large_vectors = lv; | 3369 | large_vectors = lv; |
| 3365 | p = large_vector_vec (lv); | 3370 | p = large_vector_vec (lv); |
| 3366 | } | 3371 | } |
| 3367 | 3372 | ||
| 3368 | #ifdef DOUG_LEA_MALLOC | 3373 | #ifdef DOUG_LEA_MALLOC |
| 3369 | if (!mmap_lisp_allowed_p ()) | 3374 | if (!mmap_lisp_allowed_p ()) |
| 3370 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); | 3375 | mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
| 3371 | #endif | 3376 | #endif |
| 3372 | 3377 | ||
| 3373 | if (find_suspicious_object_in_range (p, (char *) p + nbytes)) | 3378 | if (find_suspicious_object_in_range (p, (char *) p + nbytes)) |
| 3374 | emacs_abort (); | 3379 | emacs_abort (); |
| 3375 | 3380 | ||
| 3376 | consing_since_gc += nbytes; | 3381 | consing_since_gc += nbytes; |
| 3377 | vector_cells_consed += len; | 3382 | vector_cells_consed += len; |
| 3378 | 3383 | ||
| 3379 | MALLOC_UNBLOCK_INPUT; | 3384 | MALLOC_UNBLOCK_INPUT; |
| 3380 | 3385 | ||
| 3381 | return ptr_bounds_clip (p, nbytes); | 3386 | return ptr_bounds_clip (p, nbytes); |
| 3382 | } | ||
| 3383 | } | 3387 | } |
| 3384 | 3388 | ||
| 3385 | 3389 | ||
| 3386 | /* Allocate a vector with LEN slots. */ | 3390 | /* Allocate a vector with LEN slots. */ |
| 3387 | 3391 | ||
| 3388 | struct Lisp_Vector * | 3392 | struct Lisp_Vector * |
| 3389 | allocate_vector (EMACS_INT len) | 3393 | allocate_vector (ptrdiff_t len) |
| 3390 | { | 3394 | { |
| 3391 | ptrdiff_t wordbytes_max = (min (PTRDIFF_MAX, SIZE_MAX) | 3395 | if (len == 0) |
| 3392 | - header_size - large_vector_offset); | 3396 | return XVECTOR (zero_vector); |
| 3393 | if (min (wordbytes_max / word_size, MOST_POSITIVE_FIXNUM) < len) | 3397 | if (VECTOR_ELTS_MAX < len) |
| 3394 | memory_full (SIZE_MAX); | 3398 | memory_full (SIZE_MAX); |
| 3395 | struct Lisp_Vector *v = allocate_vectorlike (len); | 3399 | struct Lisp_Vector *v = allocate_vectorlike (len); |
| 3396 | if (len) | 3400 | v->header.size = len; |
| 3397 | v->header.size = len; | ||
| 3398 | return v; | 3401 | return v; |
| 3399 | } | 3402 | } |
| 3400 | 3403 | ||
| @@ -3405,14 +3408,16 @@ struct Lisp_Vector * | |||
| 3405 | allocate_pseudovector (int memlen, int lisplen, | 3408 | allocate_pseudovector (int memlen, int lisplen, |
| 3406 | int zerolen, enum pvec_type tag) | 3409 | int zerolen, enum pvec_type tag) |
| 3407 | { | 3410 | { |
| 3408 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | ||
| 3409 | |||
| 3410 | /* Catch bogus values. */ | 3411 | /* Catch bogus values. */ |
| 3412 | enum { size_max = (1 << PSEUDOVECTOR_SIZE_BITS) - 1 }; | ||
| 3413 | enum { rest_max = (1 << PSEUDOVECTOR_REST_BITS) - 1 }; | ||
| 3414 | verify (size_max + rest_max <= VECTOR_ELTS_MAX); | ||
| 3411 | eassert (0 <= tag && tag <= PVEC_FONT); | 3415 | eassert (0 <= tag && tag <= PVEC_FONT); |
| 3412 | eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen); | 3416 | eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen); |
| 3413 | eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); | 3417 | eassert (lisplen <= size_max); |
| 3414 | eassert (lisplen <= PSEUDOVECTOR_SIZE_MASK); | 3418 | eassert (memlen <= size_max + rest_max); |
| 3415 | 3419 | ||
| 3420 | struct Lisp_Vector *v = allocate_vectorlike (memlen); | ||
| 3416 | /* Only the first LISPLEN slots will be traced normally by the GC. */ | 3421 | /* Only the first LISPLEN slots will be traced normally by the GC. */ |
| 3417 | memclear (v->contents, zerolen * word_size); | 3422 | memclear (v->contents, zerolen * word_size); |
| 3418 | XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); | 3423 | XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); |
| @@ -3485,7 +3490,8 @@ DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, | |||
| 3485 | See also the function `vector'. */) | 3490 | See also the function `vector'. */) |
| 3486 | (Lisp_Object length, Lisp_Object init) | 3491 | (Lisp_Object length, Lisp_Object init) |
| 3487 | { | 3492 | { |
| 3488 | CHECK_FIXNAT (length); | 3493 | CHECK_TYPE (FIXNATP (length) && XFIXNAT (length) <= PTRDIFF_MAX, |
| 3494 | Qwholenump, length); | ||
| 3489 | struct Lisp_Vector *p = allocate_vector (XFIXNAT (length)); | 3495 | struct Lisp_Vector *p = allocate_vector (XFIXNAT (length)); |
| 3490 | for (ptrdiff_t i = 0; i < XFIXNAT (length); i++) | 3496 | for (ptrdiff_t i = 0; i < XFIXNAT (length); i++) |
| 3491 | p->contents[i] = init; | 3497 | p->contents[i] = init; |