diff options
| author | Paul Eggert | 2011-07-28 14:42:59 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 14:42:59 -0700 |
| commit | 98e8eae1372c6656c82ec0f9600128a2ecb522cc (patch) | |
| tree | 230fab21f1d8b64a48f7ceb3b497fc77312b29f2 /src | |
| parent | b4fb63147af14661b28c59d07987f8306deb5ed1 (diff) | |
| download | emacs-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/ChangeLog | 4 | ||||
| -rw-r--r-- | src/eval.c | 26 |
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 @@ | |||
| 1 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-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); | |||
| 133 | void | 133 | void |
| 134 | init_eval_once (void) | 134 | init_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 | |||
| 3274 | grow_specpdl (void) | 3275 | grow_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 | ||