aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2018-12-08 16:56:32 -0800
committerPaul Eggert2018-12-08 16:58:40 -0800
commit7bcea8f8c11d10fd189c4250042dfe68e2df8c3a (patch)
tree3676ecf2fccc0b7c4dede99487274931c1214784 /src/alloc.c
parenta9732737f2b48a78de72d67f6ed950495788ed1d (diff)
downloademacs-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.c86
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
3339static 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
3340static struct Lisp_Vector * 3348static struct Lisp_Vector *
3341allocate_vectorlike (ptrdiff_t len) 3349allocate_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
3388struct Lisp_Vector * 3392struct Lisp_Vector *
3389allocate_vector (EMACS_INT len) 3393allocate_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 *
3405allocate_pseudovector (int memlen, int lisplen, 3408allocate_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,
3485See also the function `vector'. */) 3490See 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;