aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/print.c5
-rw-r--r--src/window.c109
-rw-r--r--src/window.h6
3 files changed, 56 insertions, 64 deletions
diff --git a/src/print.c b/src/print.c
index 838d03666d4..58b9c706bae 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1774,9 +1774,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1774 } 1774 }
1775 else if (WINDOWP (obj)) 1775 else if (WINDOWP (obj))
1776 { 1776 {
1777 int len; 1777 int len = sprintf (buf, "#<window %"pI"d",
1778 strout ("#<window ", -1, -1, printcharfun); 1778 XWINDOW (obj)->sequence_number);
1779 len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number);
1780 strout (buf, len, len, printcharfun); 1779 strout (buf, len, len, printcharfun);
1781 if (BUFFERP (XWINDOW (obj)->contents)) 1780 if (BUFFERP (XWINDOW (obj)->contents))
1782 { 1781 {
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;
diff --git a/src/window.h b/src/window.h
index 96e7438f46e..eaff57eaedf 100644
--- a/src/window.h
+++ b/src/window.h
@@ -195,10 +195,10 @@ struct window
195 Lisp_Object next_buffers; 195 Lisp_Object next_buffers;
196 196
197 /* Number saying how recently window was selected. */ 197 /* Number saying how recently window was selected. */
198 int use_time; 198 EMACS_INT use_time;
199 199
200 /* Unique number of window assigned when it was created. */ 200 /* Unique number of window assigned when it was created. */
201 int sequence_number; 201 EMACS_INT sequence_number;
202 202
203 /* The upper left corner pixel coordinates of this window, as 203 /* The upper left corner pixel coordinates of this window, as
204 integers relative to upper left corner of frame = 0, 0. */ 204 integers relative to upper left corner of frame = 0, 0. */
@@ -990,7 +990,7 @@ extern Lisp_Object selected_window;
990 recently used window. Its only users are Fselect_window, 990 recently used window. Its only users are Fselect_window,
991 init_window_once, and make_frame. */ 991 init_window_once, and make_frame. */
992 992
993extern int window_select_count; 993extern EMACS_INT window_select_count;
994 994
995/* The minibuffer window of the selected frame. 995/* The minibuffer window of the selected frame.
996 Note that you cannot test for minibufferness of an arbitrary window 996 Note that you cannot test for minibufferness of an arbitrary window