[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 7bcea8f: Streamline and fix vector-size checks
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 7bcea8f: Streamline and fix vector-size checks |
Date: |
Sat, 8 Dec 2018 19:58:46 -0500 (EST) |
branch: master
commit 7bcea8f8c11d10fd189c4250042dfe68e2df8c3a
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
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.
---
src/alloc.c | 86 ++++++++++++++++++++++++++++++++---------------------------
src/lisp.h | 9 ++-----
src/xwidget.c | 12 ++++++---
3 files changed, 57 insertions(+), 50 deletions(-)
diff --git a/src/alloc.c b/src/alloc.c
index 8eaa810..3bc9277 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2398,6 +2398,8 @@ make_uninit_bool_vector (EMACS_INT nbits)
EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes
+ word_size - 1)
/ word_size);
+ if (PTRDIFF_MAX < needed_elements)
+ memory_full (SIZE_MAX);
struct Lisp_Bool_Vector *p
= (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
XSETVECTOR (val, p);
@@ -3334,67 +3336,68 @@ sweep_vectors (void)
}
}
+static ptrdiff_t const VECTOR_ELTS_MAX
+ = min (((min (PTRDIFF_MAX, SIZE_MAX) - header_size - large_vector_offset)
+ / word_size),
+ MOST_POSITIVE_FIXNUM);
+
/* Value is a pointer to a newly allocated Lisp_Vector structure
- with room for LEN Lisp_Objects. */
+ with room for LEN Lisp_Objects. LEN must be positive and
+ at most VECTOR_ELTS_MAX. */
static struct Lisp_Vector *
allocate_vectorlike (ptrdiff_t len)
{
- if (len == 0)
- return XVECTOR (zero_vector);
- else
- {
- size_t nbytes = header_size + len * word_size;
- struct Lisp_Vector *p;
+ eassert (0 < len && len <= VECTOR_ELTS_MAX);
+ size_t nbytes = header_size + len * word_size;
+ struct Lisp_Vector *p;
- MALLOC_BLOCK_INPUT;
+ MALLOC_BLOCK_INPUT;
#ifdef DOUG_LEA_MALLOC
- if (!mmap_lisp_allowed_p ())
- mallopt (M_MMAP_MAX, 0);
+ if (!mmap_lisp_allowed_p ())
+ mallopt (M_MMAP_MAX, 0);
#endif
- if (nbytes <= VBLOCK_BYTES_MAX)
- p = allocate_vector_from_block (vroundup (nbytes));
- else
- {
- struct large_vector *lv = lisp_malloc (large_vector_offset + nbytes,
- MEM_TYPE_VECTORLIKE);
- lv->next = large_vectors;
- large_vectors = lv;
- p = large_vector_vec (lv);
- }
+ if (nbytes <= VBLOCK_BYTES_MAX)
+ p = allocate_vector_from_block (vroundup (nbytes));
+ else
+ {
+ struct large_vector *lv = lisp_malloc (large_vector_offset + nbytes,
+ MEM_TYPE_VECTORLIKE);
+ lv->next = large_vectors;
+ large_vectors = lv;
+ p = large_vector_vec (lv);
+ }
#ifdef DOUG_LEA_MALLOC
- if (!mmap_lisp_allowed_p ())
- mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
+ if (!mmap_lisp_allowed_p ())
+ mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
#endif
- if (find_suspicious_object_in_range (p, (char *) p + nbytes))
- emacs_abort ();
+ if (find_suspicious_object_in_range (p, (char *) p + nbytes))
+ emacs_abort ();
- consing_since_gc += nbytes;
- vector_cells_consed += len;
+ consing_since_gc += nbytes;
+ vector_cells_consed += len;
- MALLOC_UNBLOCK_INPUT;
+ MALLOC_UNBLOCK_INPUT;
- return ptr_bounds_clip (p, nbytes);
- }
+ return ptr_bounds_clip (p, nbytes);
}
/* Allocate a vector with LEN slots. */
struct Lisp_Vector *
-allocate_vector (EMACS_INT len)
+allocate_vector (ptrdiff_t len)
{
- ptrdiff_t wordbytes_max = (min (PTRDIFF_MAX, SIZE_MAX)
- - header_size - large_vector_offset);
- if (min (wordbytes_max / word_size, MOST_POSITIVE_FIXNUM) < len)
+ if (len == 0)
+ return XVECTOR (zero_vector);
+ if (VECTOR_ELTS_MAX < len)
memory_full (SIZE_MAX);
struct Lisp_Vector *v = allocate_vectorlike (len);
- if (len)
- v->header.size = len;
+ v->header.size = len;
return v;
}
@@ -3405,14 +3408,16 @@ struct Lisp_Vector *
allocate_pseudovector (int memlen, int lisplen,
int zerolen, enum pvec_type tag)
{
- struct Lisp_Vector *v = allocate_vectorlike (memlen);
-
/* Catch bogus values. */
+ enum { size_max = (1 << PSEUDOVECTOR_SIZE_BITS) - 1 };
+ enum { rest_max = (1 << PSEUDOVECTOR_REST_BITS) - 1 };
+ verify (size_max + rest_max <= VECTOR_ELTS_MAX);
eassert (0 <= tag && tag <= PVEC_FONT);
eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen);
- eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
- eassert (lisplen <= PSEUDOVECTOR_SIZE_MASK);
+ eassert (lisplen <= size_max);
+ eassert (memlen <= size_max + rest_max);
+ struct Lisp_Vector *v = allocate_vectorlike (memlen);
/* Only the first LISPLEN slots will be traced normally by the GC. */
memclear (v->contents, zerolen * word_size);
XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
@@ -3485,7 +3490,8 @@ DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0,
See also the function `vector'. */)
(Lisp_Object length, Lisp_Object init)
{
- CHECK_FIXNAT (length);
+ CHECK_TYPE (FIXNATP (length) && XFIXNAT (length) <= PTRDIFF_MAX,
+ Qwholenump, length);
struct Lisp_Vector *p = allocate_vector (XFIXNAT (length));
for (ptrdiff_t i = 0; i < XFIXNAT (length); i++)
p->contents[i] = init;
diff --git a/src/lisp.h b/src/lisp.h
index 7e7dba6..77b8b63 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3695,7 +3695,7 @@ build_string (const char *str)
extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
extern void make_byte_code (struct Lisp_Vector *);
-extern struct Lisp_Vector *allocate_vector (EMACS_INT);
+extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
/* Make an uninitialized vector for SIZE objects. NOTE: you must
be sure that GC cannot happen until the vector is completely
@@ -3709,12 +3709,7 @@ extern struct Lisp_Vector *allocate_vector (EMACS_INT);
INLINE Lisp_Object
make_uninit_vector (ptrdiff_t size)
{
- Lisp_Object v;
- struct Lisp_Vector *p;
-
- p = allocate_vector (size);
- XSETVECTOR (v, p);
- return v;
+ return make_lisp_ptr (allocate_vector (size), Lisp_Vectorlike);
}
/* Like above, but special for sub char-tables. */
diff --git a/src/xwidget.c b/src/xwidget.c
index 5a8b105..791dad4 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -310,11 +310,15 @@ webkit_js_to_lisp (JSContextRef context, JSValueRef value)
if (JSValueIsArray (context, value))
{
JSStringRef pname = JSStringCreateWithUTF8CString("length");
- JSValueRef len = JSObjectGetProperty (context, (JSObjectRef)
value, pname, NULL);
- EMACS_INT n = JSValueToNumber (context, len, NULL);
+ JSValueRef len = JSObjectGetProperty (context, (JSObjectRef) value,
+ pname, NULL);
+ double dlen = JSValueToNumber (context, len, NULL);
JSStringRelease(pname);
Lisp_Object obj;
+ if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0))
+ memory_full (SIZE_MAX);
+ ptrdiff_t n = dlen;
struct Lisp_Vector *p = allocate_vector (n);
for (ptrdiff_t i = 0; i < n; ++i)
@@ -333,10 +337,12 @@ webkit_js_to_lisp (JSContextRef context, JSValueRef value)
JSPropertyNameArrayRef properties =
JSObjectCopyPropertyNames (context, (JSObjectRef) value);
- ptrdiff_t n = JSPropertyNameArrayGetCount (properties);
+ size_t n = JSPropertyNameArrayGetCount (properties);
Lisp_Object obj;
/* TODO: can we use a regular list here? */
+ if (PTRDIFF_MAX < n)
+ memory_full (n);
struct Lisp_Vector *p = allocate_vector (n);
for (ptrdiff_t i = 0; i < n; ++i)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 7bcea8f: Streamline and fix vector-size checks,
Paul Eggert <=