aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorPaul Eggert2015-04-13 23:26:13 -0700
committerPaul Eggert2015-04-13 23:26:59 -0700
commitb80c5ebc4f6afd54597012583c6a1390db0ade9c (patch)
tree96d02d47732d4dd9fd3c16f66db9fd929b4efd41 /src/window.c
parente84d1ca3c6a643370c4273ad569b618d8cd72b53 (diff)
downloademacs-b80c5ebc4f6afd54597012583c6a1390db0ade9c.tar.gz
emacs-b80c5ebc4f6afd54597012583c6a1390db0ade9c.zip
Avoid some int overflows in window.c
* src/print.c (print_object): * src/window.c (sequence_number): * src/window.h (struct window.sequence_number): Don't assume window sequence number fits in int. * src/window.c (window_select_count): * src/window.h (struct window.use_time, window_select_count): Don't assume window use time fits in int. * src/window.c (Fsplit_window_internal): Don't assume user-supplied integer, or sum, fits in int. (Fset_window_configuration, count_windows, get_leaf_windows) (save_window_save, Fcurrent_window_configuration): Use ptrdiff_t for object counts. (Fset_window_configuration): Omit unused local 'n'. (count_windows): Simplify by writing in terms of get_leaf_windows. (get_leaf_windows): Don't store through FLAT if it's null. (extract_dimension): New static function. (set_window_margins, set_window_fringes, set_window_scroll_bars): Use it to avoid undefined behavior when converting user-supplied integer to 'int'.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c109
1 files changed, 51 insertions, 58 deletions
diff --git a/src/window.c b/src/window.c
index eb68672e2e0..461bb627df7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -45,8 +45,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45#include "msdos.h" 45#include "msdos.h"
46#endif 46#endif
47 47
48static int count_windows (struct window *); 48static ptrdiff_t count_windows (struct window *);
49static int get_leaf_windows (struct window *, struct window **, int); 49static ptrdiff_t get_leaf_windows (struct window *, struct window **,
50 ptrdiff_t);
50static void window_scroll_pixel_based (Lisp_Object, int, bool, bool); 51static void window_scroll_pixel_based (Lisp_Object, int, bool, bool);
51static void window_scroll_line_based (Lisp_Object, int, bool, bool); 52static void window_scroll_line_based (Lisp_Object, int, bool, bool);
52static void foreach_window (struct frame *, 53static void foreach_window (struct frame *,
@@ -93,7 +94,7 @@ Lisp_Object minibuf_window;
93Lisp_Object minibuf_selected_window; 94Lisp_Object minibuf_selected_window;
94 95
95/* Incremented for each window created. */ 96/* Incremented for each window created. */
96static int sequence_number; 97static EMACS_INT sequence_number;
97 98
98/* Used by the function window_scroll_pixel_based. */ 99/* Used by the function window_scroll_pixel_based. */
99static int window_scroll_pixel_based_preserve_x; 100static int window_scroll_pixel_based_preserve_x;
@@ -451,7 +452,7 @@ selected windows appears and to which many commands apply. */)
451 return selected_window; 452 return selected_window;
452} 453}
453 454
454int window_select_count; 455EMACS_INT window_select_count;
455 456
456/* If select_window is called with inhibit_point_swap true it will 457/* If select_window is called with inhibit_point_swap true it will
457 not store point of the old selected window's buffer back into that 458 not store point of the old selected window's buffer back into that
@@ -4275,7 +4276,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
4275DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, 4276DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4276 doc: /* Split window OLD. 4277 doc: /* Split window OLD.
4277Second argument PIXEL-SIZE specifies the number of pixels of the 4278Second argument PIXEL-SIZE specifies the number of pixels of the
4278new window. In any case TOTAL-SIZE must be a positive integer. 4279new window. It must be a positive integer.
4279 4280
4280Third argument SIDE nil (or `below') specifies that the new window shall 4281Third argument SIDE nil (or `below') specifies that the new window shall
4281be located below WINDOW. SIDE `above' means the new window shall be 4282be located below WINDOW. SIDE `above' means the new window shall be
@@ -4315,7 +4316,7 @@ set correctly. See the code of `split-window' for how this is done. */)
4315 f = XFRAME (frame); 4316 f = XFRAME (frame);
4316 4317
4317 CHECK_NUMBER (pixel_size); 4318 CHECK_NUMBER (pixel_size);
4318 int total_size 4319 EMACS_INT total_size
4319 = XINT (pixel_size) / (horflag 4320 = XINT (pixel_size) / (horflag
4320 ? FRAME_COLUMN_WIDTH (f) 4321 ? FRAME_COLUMN_WIDTH (f)
4321 : FRAME_LINE_HEIGHT (f)); 4322 : FRAME_LINE_HEIGHT (f));
@@ -4452,7 +4453,7 @@ set correctly. See the code of `split-window' for how this is done. */)
4452 /* Iso-coordinates and sizes are assigned by window_resize_apply, 4453 /* Iso-coordinates and sizes are assigned by window_resize_apply,
4453 get them ready here. */ 4454 get them ready here. */
4454 wset_new_pixel (n, pixel_size); 4455 wset_new_pixel (n, pixel_size);
4455 int sum = 0; 4456 EMACS_INT sum = 0;
4456 c = XWINDOW (p->contents); 4457 c = XWINDOW (p->contents);
4457 while (c) 4458 while (c)
4458 { 4459 {
@@ -6204,14 +6205,12 @@ the return value is nil. Otherwise the value is t. */)
6204 { 6205 {
6205 Lisp_Object window; 6206 Lisp_Object window;
6206 Lisp_Object dead_windows = Qnil; 6207 Lisp_Object dead_windows = Qnil;
6207 register Lisp_Object tem, par, pers; 6208 Lisp_Object tem, par, pers;
6208 register struct window *w; 6209 struct window *w;
6209 register struct saved_window *p; 6210 struct saved_window *p;
6210 struct window *root_window; 6211 struct window *root_window;
6211 struct window **leaf_windows; 6212 struct window **leaf_windows;
6212 int n_leaf_windows; 6213 ptrdiff_t i, k, n_leaf_windows;
6213 ptrdiff_t k;
6214 int i, n;
6215 6214
6216 /* Don't do this within the main loop below: This may call Lisp 6215 /* Don't do this within the main loop below: This may call Lisp
6217 code and is thus potentially unsafe while input is blocked. */ 6216 code and is thus potentially unsafe while input is blocked. */
@@ -6256,7 +6255,7 @@ the return value is nil. Otherwise the value is t. */)
6256 really like to do is to free only those matrices not reused 6255 really like to do is to free only those matrices not reused
6257 below. */ 6256 below. */
6258 root_window = XWINDOW (FRAME_ROOT_WINDOW (f)); 6257 root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
6259 int nwindows = count_windows (root_window); 6258 ptrdiff_t nwindows = count_windows (root_window);
6260 SAFE_NALLOCA (leaf_windows, 1, nwindows); 6259 SAFE_NALLOCA (leaf_windows, 1, nwindows);
6261 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0); 6260 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6262 6261
@@ -6430,13 +6429,9 @@ the return value is nil. Otherwise the value is t. */)
6430 Fredirect_frame_focus (frame, data->focus_frame); 6429 Fredirect_frame_focus (frame, data->focus_frame);
6431 6430
6432 /* Now, free glyph matrices in windows that were not reused. */ 6431 /* Now, free glyph matrices in windows that were not reused. */
6433 for (i = n = 0; i < n_leaf_windows; ++i) 6432 for (i = 0; i < n_leaf_windows; i++)
6434 { 6433 if (NILP (leaf_windows[i]->contents))
6435 if (NILP (leaf_windows[i]->contents)) 6434 free_window_matrices (leaf_windows[i]);
6436 free_window_matrices (leaf_windows[i]);
6437 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
6438 ++n;
6439 }
6440 6435
6441 /* Allow x_set_window_size again and apply frame size changes if 6436 /* Allow x_set_window_size again and apply frame size changes if
6442 needed. */ 6437 needed. */
@@ -6529,29 +6524,27 @@ delete_all_child_windows (Lisp_Object window)
6529 Vwindow_list = Qnil; 6524 Vwindow_list = Qnil;
6530} 6525}
6531 6526
6532static int 6527static ptrdiff_t
6533count_windows (register struct window *window) 6528count_windows (struct window *window)
6534{ 6529{
6535 register int count = 1; 6530 return get_leaf_windows (window, NULL, 0);
6536 if (!NILP (window->next))
6537 count += count_windows (XWINDOW (window->next));
6538 if (WINDOWP (window->contents))
6539 count += count_windows (XWINDOW (window->contents));
6540 return count;
6541} 6531}
6542 6532
6543 6533/* If vector FLAT is non-null, fill it with leaf windows under W,
6544/* Fill vector FLAT with leaf windows under W, starting at index I. 6534 starting at index I. Value is last index + 1. */
6545 Value is last index + 1. */ 6535static ptrdiff_t
6546static int 6536get_leaf_windows (struct window *w, struct window **flat, ptrdiff_t i)
6547get_leaf_windows (struct window *w, struct window **flat, int i)
6548{ 6537{
6549 while (w) 6538 while (w)
6550 { 6539 {
6551 if (WINDOWP (w->contents)) 6540 if (WINDOWP (w->contents))
6552 i = get_leaf_windows (XWINDOW (w->contents), flat, i); 6541 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
6553 else 6542 else
6554 flat[i++] = w; 6543 {
6544 if (flat)
6545 flat[i] = w;
6546 i++;
6547 }
6555 6548
6556 w = NILP (w->next) ? 0 : XWINDOW (w->next); 6549 w = NILP (w->next) ? 0 : XWINDOW (w->next);
6557 } 6550 }
@@ -6598,12 +6591,12 @@ get_phys_cursor_glyph (struct window *w)
6598} 6591}
6599 6592
6600 6593
6601static int 6594static ptrdiff_t
6602save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) 6595save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
6603{ 6596{
6604 register struct saved_window *p; 6597 struct saved_window *p;
6605 register struct window *w; 6598 struct window *w;
6606 register Lisp_Object tem, pers, par; 6599 Lisp_Object tem, pers, par;
6607 6600
6608 for (; !NILP (window); window = w->next) 6601 for (; !NILP (window); window = w->next)
6609 { 6602 {
@@ -6741,10 +6734,9 @@ redirection (see `redirect-frame-focus'). The variable
6741saved by this function. */) 6734saved by this function. */)
6742 (Lisp_Object frame) 6735 (Lisp_Object frame)
6743{ 6736{
6744 register Lisp_Object tem; 6737 Lisp_Object tem;
6745 register int n_windows; 6738 ptrdiff_t i, n_windows;
6746 register struct save_window_data *data; 6739 struct save_window_data *data;
6747 register int i;
6748 struct frame *f = decode_live_frame (frame); 6740 struct frame *f = decode_live_frame (frame);
6749 6741
6750 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); 6742 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
@@ -6794,17 +6786,22 @@ apply_window_adjustment (struct window *w)
6794 Marginal Areas 6786 Marginal Areas
6795 ***********************************************************************/ 6787 ***********************************************************************/
6796 6788
6789static int
6790extract_dimension (Lisp_Object dimension)
6791{
6792 if (NILP (dimension))
6793 return -1;
6794 CHECK_RANGED_INTEGER (dimension, 0, INT_MAX);
6795 return XINT (dimension);
6796}
6797
6797static struct window * 6798static struct window *
6798set_window_margins (struct window *w, Lisp_Object left_width, 6799set_window_margins (struct window *w, Lisp_Object left_width,
6799 Lisp_Object right_width) 6800 Lisp_Object right_width)
6800{ 6801{
6801 int left, right;
6802 int unit = WINDOW_FRAME_COLUMN_WIDTH (w); 6802 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
6803 6803 int left = NILP (left_width) ? 0 : extract_dimension (left_width);
6804 left = (NILP (left_width) ? 0 6804 int right = NILP (right_width) ? 0 : extract_dimension (right_width);
6805 : (CHECK_NATNUM (left_width), XINT (left_width)));
6806 right = (NILP (right_width) ? 0
6807 : (CHECK_NATNUM (right_width), XINT (right_width)));
6808 6805
6809 if (w->left_margin_cols != left || w->right_margin_cols != right) 6806 if (w->left_margin_cols != left || w->right_margin_cols != right)
6810 { 6807 {
@@ -6873,13 +6870,9 @@ static struct window *
6873set_window_fringes (struct window *w, Lisp_Object left_width, 6870set_window_fringes (struct window *w, Lisp_Object left_width,
6874 Lisp_Object right_width, Lisp_Object outside_margins) 6871 Lisp_Object right_width, Lisp_Object outside_margins)
6875{ 6872{
6876 int left, right;
6877 bool outside = !NILP (outside_margins); 6873 bool outside = !NILP (outside_margins);
6878 6874 int left = extract_dimension (left_width);
6879 left = (NILP (left_width) ? -1 6875 int right = extract_dimension (right_width);
6880 : (CHECK_NATNUM (left_width), XINT (left_width)));
6881 right = (NILP (right_width) ? -1
6882 : (CHECK_NATNUM (right_width), XINT (right_width)));
6883 6876
6884 /* Do nothing on a tty or if nothing to actually change. */ 6877 /* Do nothing on a tty or if nothing to actually change. */
6885 if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) 6878 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
@@ -6959,7 +6952,7 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
6959 Lisp_Object vertical_type, Lisp_Object height, 6952 Lisp_Object vertical_type, Lisp_Object height,
6960 Lisp_Object horizontal_type) 6953 Lisp_Object horizontal_type)
6961{ 6954{
6962 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width))); 6955 int iwidth = extract_dimension (width);
6963 bool changed = false; 6956 bool changed = false;
6964 6957
6965 if (iwidth == 0) 6958 if (iwidth == 0)
@@ -6989,7 +6982,7 @@ set_window_scroll_bars (struct window *w, Lisp_Object width,
6989 6982
6990#if USE_HORIZONTAL_SCROLL_BARS 6983#if USE_HORIZONTAL_SCROLL_BARS
6991 { 6984 {
6992 int iheight = (NILP (height) ? -1 : (CHECK_NATNUM (height), XINT (height))); 6985 int iheight = extract_dimension (height);
6993 6986
6994 if (MINI_WINDOW_P (w) || iheight == 0) 6987 if (MINI_WINDOW_P (w) || iheight == 0)
6995 horizontal_type = Qnil; 6988 horizontal_type = Qnil;