aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-28 14:42:59 -0700
committerPaul Eggert2011-07-28 14:42:59 -0700
commit98e8eae1372c6656c82ec0f9600128a2ecb522cc (patch)
tree230fab21f1d8b64a48f7ceb3b497fc77312b29f2 /src
parentb4fb63147af14661b28c59d07987f8306deb5ed1 (diff)
downloademacs-98e8eae1372c6656c82ec0f9600128a2ecb522cc.tar.gz
emacs-98e8eae1372c6656c82ec0f9600128a2ecb522cc.zip
* eval.c: Integer and memory overflow fixes.
(init_eval_once, grow_specpdl): Don't update size until alloc succeeds. (call_debugger, grow_specpdl): Redo calculations to avoid overflow.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog4
-rw-r--r--src/eval.c26
2 files changed, 20 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 52f1a76e54c..7a7c8c14407 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
12011-07-28 Paul Eggert <eggert@cs.ucla.edu> 12011-07-28 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * eval.c: Integer and memory overflow fixes.
4 (init_eval_once, grow_specpdl): Don't update size until alloc succeeds.
5 (call_debugger, grow_specpdl): Redo calculations to avoid overflow.
6
3 * emacs.c (main, sort_args): Check for size-calculation overflow. 7 * emacs.c (main, sort_args): Check for size-calculation overflow.
4 8
5 * editfns.c: Integer and memory overflow fixes. 9 * editfns.c: Integer and memory overflow fixes.
diff --git a/src/eval.c b/src/eval.c
index ef169e80e27..bcb77574fee 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -133,8 +133,9 @@ static Lisp_Object Ffetch_bytecode (Lisp_Object);
133void 133void
134init_eval_once (void) 134init_eval_once (void)
135{ 135{
136 specpdl_size = 50; 136 enum { size = 50 };
137 specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding)); 137 specpdl = (struct specbinding *) xmalloc (size * sizeof (struct specbinding));
138 specpdl_size = size;
138 specpdl_ptr = specpdl; 139 specpdl_ptr = specpdl;
139 /* Don't forget to update docs (lispref node "Local Variables"). */ 140 /* Don't forget to update docs (lispref node "Local Variables"). */
140 max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */ 141 max_specpdl_size = 1300; /* 1000 is not enough for CEDET's c-by.el. */
@@ -192,7 +193,7 @@ call_debugger (Lisp_Object arg)
192 if (lisp_eval_depth + 40 > max_lisp_eval_depth) 193 if (lisp_eval_depth + 40 > max_lisp_eval_depth)
193 max_lisp_eval_depth = lisp_eval_depth + 40; 194 max_lisp_eval_depth = lisp_eval_depth + 40;
194 195
195 if (SPECPDL_INDEX () + 100 > max_specpdl_size) 196 if (max_specpdl_size - 100 < SPECPDL_INDEX ())
196 max_specpdl_size = SPECPDL_INDEX () + 100; 197 max_specpdl_size = SPECPDL_INDEX () + 100;
197 198
198#ifdef HAVE_WINDOW_SYSTEM 199#ifdef HAVE_WINDOW_SYSTEM
@@ -3274,17 +3275,22 @@ static void
3274grow_specpdl (void) 3275grow_specpdl (void)
3275{ 3276{
3276 register int count = SPECPDL_INDEX (); 3277 register int count = SPECPDL_INDEX ();
3277 if (specpdl_size >= max_specpdl_size) 3278 int max_size =
3279 min (max_specpdl_size,
3280 min (max (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct specbinding),
3281 INT_MAX));
3282 int size;
3283 if (max_size <= specpdl_size)
3278 { 3284 {
3279 if (max_specpdl_size < 400) 3285 if (max_specpdl_size < 400)
3280 max_specpdl_size = 400; 3286 max_size = max_specpdl_size = 400;
3281 if (specpdl_size >= max_specpdl_size) 3287 if (max_size <= specpdl_size)
3282 signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); 3288 signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
3283 } 3289 }
3284 specpdl_size *= 2; 3290 size = specpdl_size < max_size / 2 ? 2 * specpdl_size : max_size;
3285 if (specpdl_size > max_specpdl_size) 3291 specpdl = ((struct specbinding *)
3286 specpdl_size = max_specpdl_size; 3292 xrealloc (specpdl, size * sizeof (struct specbinding)));
3287 specpdl = (struct specbinding *) xrealloc (specpdl, specpdl_size * sizeof (struct specbinding)); 3293 specpdl_size = size;
3288 specpdl_ptr = specpdl + count; 3294 specpdl_ptr = specpdl + count;
3289} 3295}
3290 3296