diff options
| author | Paul Eggert | 2014-08-03 16:16:39 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-08-03 16:16:39 -0700 |
| commit | 8d2f19849a194934c05486e19a968d585f516fd6 (patch) | |
| tree | e515b31d2e52922c4711e5ca2222f35ee97d01cc /src | |
| parent | 3cc0c06094c8731c9e15536fefd3382d8ca1eba0 (diff) | |
| download | emacs-8d2f19849a194934c05486e19a968d585f516fd6.tar.gz emacs-8d2f19849a194934c05486e19a968d585f516fd6.zip | |
Don't let big frames overrun the stack.
* dispnew.c (mirrored_line_dance, mirror_line_dance, scrolling):
Use SAFE_NALLOCA, not alloca.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 4 | ||||
| -rw-r--r-- | src/dispnew.c | 87 |
2 files changed, 55 insertions, 36 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index da3d197d6f3..70f77f8f0cd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | 2014-08-03 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2014-08-03 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Don't let big frames overrun the stack. | ||
| 4 | * dispnew.c (mirrored_line_dance, mirror_line_dance, scrolling): | ||
| 5 | Use SAFE_NALLOCA, not alloca. | ||
| 6 | |||
| 3 | Fix bug with clang + directory_files_internal + GC (Bug#16986). | 7 | Fix bug with clang + directory_files_internal + GC (Bug#16986). |
| 4 | * dired.c (directory_files_internal): Use a volatile variable | 8 | * dired.c (directory_files_internal): Use a volatile variable |
| 5 | to prevent the compiler from optimizing away all copies of a local. | 9 | to prevent the compiler from optimizing away all copies of a local. |
diff --git a/src/dispnew.c b/src/dispnew.c index 78df22ddbe2..0e49530c71d 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -2684,7 +2684,8 @@ mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlin | |||
| 2684 | int i; | 2684 | int i; |
| 2685 | 2685 | ||
| 2686 | /* Make a copy of the original rows. */ | 2686 | /* Make a copy of the original rows. */ |
| 2687 | old_rows = alloca (nlines * sizeof *old_rows); | 2687 | USE_SAFE_ALLOCA; |
| 2688 | SAFE_NALLOCA (old_rows, 1, nlines); | ||
| 2688 | memcpy (old_rows, new_rows, nlines * sizeof *old_rows); | 2689 | memcpy (old_rows, new_rows, nlines * sizeof *old_rows); |
| 2689 | 2690 | ||
| 2690 | /* Assign new rows, maybe clear lines. */ | 2691 | /* Assign new rows, maybe clear lines. */ |
| @@ -2706,6 +2707,8 @@ mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlin | |||
| 2706 | if (frame_matrix_frame) | 2707 | if (frame_matrix_frame) |
| 2707 | mirror_line_dance (XWINDOW (frame_matrix_frame->root_window), | 2708 | mirror_line_dance (XWINDOW (frame_matrix_frame->root_window), |
| 2708 | unchanged_at_top, nlines, copy_from, retained_p); | 2709 | unchanged_at_top, nlines, copy_from, retained_p); |
| 2710 | |||
| 2711 | SAFE_FREE (); | ||
| 2709 | } | 2712 | } |
| 2710 | 2713 | ||
| 2711 | 2714 | ||
| @@ -2798,7 +2801,8 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy | |||
| 2798 | struct glyph_row *old_rows; | 2801 | struct glyph_row *old_rows; |
| 2799 | 2802 | ||
| 2800 | /* Make a copy of the original rows of matrix m. */ | 2803 | /* Make a copy of the original rows of matrix m. */ |
| 2801 | old_rows = alloca (m->nrows * sizeof *old_rows); | 2804 | USE_SAFE_ALLOCA; |
| 2805 | SAFE_NALLOCA (old_rows, 1, m->nrows); | ||
| 2802 | memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows); | 2806 | memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows); |
| 2803 | 2807 | ||
| 2804 | for (i = 0; i < nlines; ++i) | 2808 | for (i = 0; i < nlines; ++i) |
| @@ -2874,6 +2878,8 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy | |||
| 2874 | 2878 | ||
| 2875 | /* Check that no pointers are lost. */ | 2879 | /* Check that no pointers are lost. */ |
| 2876 | CHECK_MATRIX (m); | 2880 | CHECK_MATRIX (m); |
| 2881 | |||
| 2882 | SAFE_FREE (); | ||
| 2877 | } | 2883 | } |
| 2878 | 2884 | ||
| 2879 | /* Next window on same level. */ | 2885 | /* Next window on same level. */ |
| @@ -4647,14 +4653,19 @@ scrolling (struct frame *frame) | |||
| 4647 | int unchanged_at_top, unchanged_at_bottom; | 4653 | int unchanged_at_top, unchanged_at_bottom; |
| 4648 | int window_size; | 4654 | int window_size; |
| 4649 | int changed_lines; | 4655 | int changed_lines; |
| 4650 | unsigned *old_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4656 | int i; |
| 4651 | unsigned *new_hash = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4657 | int height = FRAME_TOTAL_LINES (frame); |
| 4652 | int *draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | 4658 | int free_at_end_vpos = height; |
| 4653 | int *old_draw_cost = alloca (FRAME_TOTAL_LINES (frame) * sizeof (int)); | ||
| 4654 | register int i; | ||
| 4655 | int free_at_end_vpos = FRAME_TOTAL_LINES (frame); | ||
| 4656 | struct glyph_matrix *current_matrix = frame->current_matrix; | 4659 | struct glyph_matrix *current_matrix = frame->current_matrix; |
| 4657 | struct glyph_matrix *desired_matrix = frame->desired_matrix; | 4660 | struct glyph_matrix *desired_matrix = frame->desired_matrix; |
| 4661 | verify (sizeof (int) <= sizeof (unsigned)); | ||
| 4662 | verify (alignof (unsigned) % alignof (int) == 0); | ||
| 4663 | unsigned *old_hash; | ||
| 4664 | USE_SAFE_ALLOCA; | ||
| 4665 | SAFE_NALLOCA (old_hash, 4, height); | ||
| 4666 | unsigned *new_hash = old_hash + height; | ||
| 4667 | int *draw_cost = (int *) (new_hash + height); | ||
| 4668 | int *old_draw_cost = draw_cost + height; | ||
| 4658 | 4669 | ||
| 4659 | eassert (current_matrix); | 4670 | eassert (current_matrix); |
| 4660 | 4671 | ||
| @@ -4663,12 +4674,15 @@ scrolling (struct frame *frame) | |||
| 4663 | number of unchanged lines at the end. */ | 4674 | number of unchanged lines at the end. */ |
| 4664 | changed_lines = 0; | 4675 | changed_lines = 0; |
| 4665 | unchanged_at_top = 0; | 4676 | unchanged_at_top = 0; |
| 4666 | unchanged_at_bottom = FRAME_TOTAL_LINES (frame); | 4677 | unchanged_at_bottom = height; |
| 4667 | for (i = 0; i < FRAME_TOTAL_LINES (frame); i++) | 4678 | for (i = 0; i < height; i++) |
| 4668 | { | 4679 | { |
| 4669 | /* Give up on this scrolling if some old lines are not enabled. */ | 4680 | /* Give up on this scrolling if some old lines are not enabled. */ |
| 4670 | if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) | 4681 | if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) |
| 4671 | return 0; | 4682 | { |
| 4683 | SAFE_FREE (); | ||
| 4684 | return false; | ||
| 4685 | } | ||
| 4672 | old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i)); | 4686 | old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i)); |
| 4673 | if (! MATRIX_ROW_ENABLED_P (desired_matrix, i)) | 4687 | if (! MATRIX_ROW_ENABLED_P (desired_matrix, i)) |
| 4674 | { | 4688 | { |
| @@ -4686,7 +4700,7 @@ scrolling (struct frame *frame) | |||
| 4686 | if (old_hash[i] != new_hash[i]) | 4700 | if (old_hash[i] != new_hash[i]) |
| 4687 | { | 4701 | { |
| 4688 | changed_lines++; | 4702 | changed_lines++; |
| 4689 | unchanged_at_bottom = FRAME_TOTAL_LINES (frame) - i - 1; | 4703 | unchanged_at_bottom = height - i - 1; |
| 4690 | } | 4704 | } |
| 4691 | else if (i == unchanged_at_top) | 4705 | else if (i == unchanged_at_top) |
| 4692 | unchanged_at_top++; | 4706 | unchanged_at_top++; |
| @@ -4696,10 +4710,13 @@ scrolling (struct frame *frame) | |||
| 4696 | /* If changed lines are few, don't allow preemption, don't scroll. */ | 4710 | /* If changed lines are few, don't allow preemption, don't scroll. */ |
| 4697 | if ((!FRAME_SCROLL_REGION_OK (frame) | 4711 | if ((!FRAME_SCROLL_REGION_OK (frame) |
| 4698 | && changed_lines < baud_rate / 2400) | 4712 | && changed_lines < baud_rate / 2400) |
| 4699 | || unchanged_at_bottom == FRAME_TOTAL_LINES (frame)) | 4713 | || unchanged_at_bottom == height) |
| 4700 | return 1; | 4714 | { |
| 4715 | SAFE_FREE (); | ||
| 4716 | return true; | ||
| 4717 | } | ||
| 4701 | 4718 | ||
| 4702 | window_size = (FRAME_TOTAL_LINES (frame) - unchanged_at_top | 4719 | window_size = (height - unchanged_at_top |
| 4703 | - unchanged_at_bottom); | 4720 | - unchanged_at_bottom); |
| 4704 | 4721 | ||
| 4705 | if (FRAME_SCROLL_REGION_OK (frame)) | 4722 | if (FRAME_SCROLL_REGION_OK (frame)) |
| @@ -4707,27 +4724,25 @@ scrolling (struct frame *frame) | |||
| 4707 | else if (FRAME_MEMORY_BELOW_FRAME (frame)) | 4724 | else if (FRAME_MEMORY_BELOW_FRAME (frame)) |
| 4708 | free_at_end_vpos = -1; | 4725 | free_at_end_vpos = -1; |
| 4709 | 4726 | ||
| 4710 | /* If large window, fast terminal and few lines in common between | 4727 | /* Do id/calc only if small window, or slow terminal, or many lines |
| 4711 | current frame and desired frame, don't bother with i/d calc. */ | 4728 | in common between current frame and desired frame. But the |
| 4712 | if (!FRAME_SCROLL_REGION_OK (frame) | 4729 | window size must be at least 2. */ |
| 4713 | && window_size >= 18 && baud_rate > 2400 | 4730 | if ((FRAME_SCROLL_REGION_OK (frame) |
| 4714 | && (window_size >= | 4731 | || window_size < 18 || baud_rate <= 2400 |
| 4715 | 10 * scrolling_max_lines_saved (unchanged_at_top, | 4732 | || (window_size |
| 4716 | FRAME_TOTAL_LINES (frame) - unchanged_at_bottom, | 4733 | < 10 * scrolling_max_lines_saved (unchanged_at_top, |
| 4717 | old_hash, new_hash, draw_cost))) | 4734 | height - unchanged_at_bottom, |
| 4718 | return 0; | 4735 | old_hash, new_hash, draw_cost))) |
| 4719 | 4736 | && 2 <= window_size) | |
| 4720 | if (window_size < 2) | 4737 | scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom, |
| 4721 | return 0; | 4738 | draw_cost + unchanged_at_top - 1, |
| 4722 | 4739 | old_draw_cost + unchanged_at_top - 1, | |
| 4723 | scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom, | 4740 | old_hash + unchanged_at_top - 1, |
| 4724 | draw_cost + unchanged_at_top - 1, | 4741 | new_hash + unchanged_at_top - 1, |
| 4725 | old_draw_cost + unchanged_at_top - 1, | 4742 | free_at_end_vpos - unchanged_at_top); |
| 4726 | old_hash + unchanged_at_top - 1, | 4743 | |
| 4727 | new_hash + unchanged_at_top - 1, | 4744 | SAFE_FREE (); |
| 4728 | free_at_end_vpos - unchanged_at_top); | 4745 | return false; |
| 4729 | |||
| 4730 | return 0; | ||
| 4731 | } | 4746 | } |
| 4732 | 4747 | ||
| 4733 | 4748 | ||