aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-08-03 16:16:39 -0700
committerPaul Eggert2014-08-03 16:16:39 -0700
commit8d2f19849a194934c05486e19a968d585f516fd6 (patch)
treee515b31d2e52922c4711e5ca2222f35ee97d01cc /src
parent3cc0c06094c8731c9e15536fefd3382d8ca1eba0 (diff)
downloademacs-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/ChangeLog4
-rw-r--r--src/dispnew.c87
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 @@
12014-08-03 Paul Eggert <eggert@cs.ucla.edu> 12014-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