diff options
| author | Paul Eggert | 2011-07-07 15:14:22 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-07 15:14:22 -0700 |
| commit | dfd153ae803962a5eaffe8a65e77f749c0574edf (patch) | |
| tree | 805e38cc8bd718dadc992e7abc62350e1aeedcae | |
| parent | a81d11a3efb4d511c5c34c8983dc6aab5d619ea1 (diff) | |
| download | emacs-dfd153ae803962a5eaffe8a65e77f749c0574edf.tar.gz emacs-dfd153ae803962a5eaffe8a65e77f749c0574edf.zip | |
* dispnew.c: Integer signedness and overflow fixes.
Remove unnecessary forward decls, that were a maintenance hassle.
(history_tick): Now uprintmax_t, so it's more likely to avoid overflow.
All uses changed.
(adjust_glyph_matrix, realloc_glyph_pool, adjust_frame_message_buffer)
(scrolling_window): Use ptrdiff_t, not int, for byte count.
(prepare_desired_row, line_draw_cost):
Use int, not unsigned, where either works.
(save_current_matrix, restore_current_matrix):
Use ptrdiff_t, not size_t, where either works.
(init_display): Check for overflow more accurately, and without
relying on undefined behavior.
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/dispnew.c | 67 |
2 files changed, 32 insertions, 48 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 62bf5712621..e2cf24fc173 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,18 @@ | |||
| 1 | 2011-07-07 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-07-07 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * dispnew.c: Integer signedness and overflow fixes. | ||
| 4 | Remove unnecessary forward decls, that were a maintenance hassle. | ||
| 5 | (history_tick): Now uprintmax_t, so it's more likely to avoid overflow. | ||
| 6 | All uses changed. | ||
| 7 | (adjust_glyph_matrix, realloc_glyph_pool, adjust_frame_message_buffer) | ||
| 8 | (scrolling_window): Use ptrdiff_t, not int, for byte count. | ||
| 9 | (prepare_desired_row, line_draw_cost): | ||
| 10 | Use int, not unsigned, where either works. | ||
| 11 | (save_current_matrix, restore_current_matrix): | ||
| 12 | Use ptrdiff_t, not size_t, where either works. | ||
| 13 | (init_display): Check for overflow more accurately, and without | ||
| 14 | relying on undefined behavior. | ||
| 15 | |||
| 3 | * editfns.c (pWIDE, pWIDElen, signed_wide, unsigned_wide): | 16 | * editfns.c (pWIDE, pWIDElen, signed_wide, unsigned_wide): |
| 4 | Remove, replacing with the new symbols in lisp.h. All uses changed. | 17 | Remove, replacing with the new symbols in lisp.h. All uses changed. |
| 5 | * fileio.c (make_temp_name): | 18 | * fileio.c (make_temp_name): |
diff --git a/src/dispnew.c b/src/dispnew.c index 8691c921853..c95404b5c52 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -103,57 +103,24 @@ struct dim | |||
| 103 | 103 | ||
| 104 | /* Function prototypes. */ | 104 | /* Function prototypes. */ |
| 105 | 105 | ||
| 106 | static struct glyph_matrix *save_current_matrix (struct frame *); | ||
| 107 | static void restore_current_matrix (struct frame *, struct glyph_matrix *); | ||
| 108 | static int showing_window_margins_p (struct window *); | ||
| 109 | static void fake_current_matrices (Lisp_Object); | ||
| 110 | static void redraw_overlapping_rows (struct window *, int); | ||
| 111 | static void redraw_overlapped_rows (struct window *, int); | ||
| 112 | static int count_blanks (struct glyph *, int); | ||
| 113 | static int count_match (struct glyph *, struct glyph *, | ||
| 114 | struct glyph *, struct glyph *); | ||
| 115 | static unsigned line_draw_cost (struct glyph_matrix *, int); | ||
| 116 | static void update_frame_line (struct frame *, int); | 106 | static void update_frame_line (struct frame *, int); |
| 117 | static struct dim allocate_matrices_for_frame_redisplay | ||
| 118 | (Lisp_Object, int, int, int, int *); | ||
| 119 | static int required_matrix_height (struct window *); | 107 | static int required_matrix_height (struct window *); |
| 120 | static int required_matrix_width (struct window *); | 108 | static int required_matrix_width (struct window *); |
| 121 | static void allocate_matrices_for_window_redisplay (struct window *); | ||
| 122 | static int realloc_glyph_pool (struct glyph_pool *, struct dim); | ||
| 123 | static void adjust_frame_glyphs (struct frame *); | 109 | static void adjust_frame_glyphs (struct frame *); |
| 124 | static struct glyph_matrix *new_glyph_matrix (struct glyph_pool *); | ||
| 125 | static void free_glyph_matrix (struct glyph_matrix *); | ||
| 126 | static void adjust_glyph_matrix (struct window *, struct glyph_matrix *, | ||
| 127 | int, int, struct dim); | ||
| 128 | static void change_frame_size_1 (struct frame *, int, int, int, int, int); | 110 | static void change_frame_size_1 (struct frame *, int, int, int, int, int); |
| 129 | static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT); | 111 | static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT); |
| 130 | static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *); | ||
| 131 | #if GLYPH_DEBUG | ||
| 132 | static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *); | ||
| 133 | #endif | ||
| 134 | static void fill_up_frame_row_with_spaces (struct glyph_row *, int); | 112 | static void fill_up_frame_row_with_spaces (struct glyph_row *, int); |
| 135 | static void build_frame_matrix_from_window_tree (struct glyph_matrix *, | 113 | static void build_frame_matrix_from_window_tree (struct glyph_matrix *, |
| 136 | struct window *); | 114 | struct window *); |
| 137 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, | 115 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, |
| 138 | struct window *); | 116 | struct window *); |
| 139 | static struct glyph_pool *new_glyph_pool (void); | ||
| 140 | static void free_glyph_pool (struct glyph_pool *); | ||
| 141 | static void adjust_frame_glyphs_initially (void); | ||
| 142 | static void adjust_frame_message_buffer (struct frame *); | 117 | static void adjust_frame_message_buffer (struct frame *); |
| 143 | static void adjust_decode_mode_spec_buffer (struct frame *); | 118 | static void adjust_decode_mode_spec_buffer (struct frame *); |
| 144 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); | 119 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); |
| 145 | static void build_frame_matrix (struct frame *); | ||
| 146 | void clear_current_matrices (struct frame *); | ||
| 147 | void scroll_glyph_matrix_range (struct glyph_matrix *, int, int, | ||
| 148 | int, int); | ||
| 149 | static void clear_window_matrices (struct window *, int); | 120 | static void clear_window_matrices (struct window *, int); |
| 150 | static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); | 121 | static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); |
| 151 | static int scrolling_window (struct window *, int); | 122 | static int scrolling_window (struct window *, int); |
| 152 | static int update_window_line (struct window *, int, int *); | 123 | static int update_window_line (struct window *, int, int *); |
| 153 | static void update_marginal_area (struct window *, int, int); | ||
| 154 | static int update_text_area (struct window *, int); | ||
| 155 | static void make_current (struct glyph_matrix *, struct glyph_matrix *, | ||
| 156 | int); | ||
| 157 | static void mirror_make_current (struct window *, int); | 124 | static void mirror_make_current (struct window *, int); |
| 158 | #if GLYPH_DEBUG | 125 | #if GLYPH_DEBUG |
| 159 | static void check_matrix_pointers (struct glyph_matrix *, | 126 | static void check_matrix_pointers (struct glyph_matrix *, |
| @@ -286,7 +253,7 @@ static int history_idx; | |||
| 286 | /* A tick that's incremented each time something is added to the | 253 | /* A tick that's incremented each time something is added to the |
| 287 | history. */ | 254 | history. */ |
| 288 | 255 | ||
| 289 | static unsigned history_tick; | 256 | static uprintmax_t history_tick; |
| 290 | 257 | ||
| 291 | static void add_frame_display_history (struct frame *, int); | 258 | static void add_frame_display_history (struct frame *, int); |
| 292 | 259 | ||
| @@ -305,7 +272,7 @@ add_window_display_history (struct window *w, const char *msg, int paused_p) | |||
| 305 | buf = redisplay_history[history_idx].trace; | 272 | buf = redisplay_history[history_idx].trace; |
| 306 | ++history_idx; | 273 | ++history_idx; |
| 307 | 274 | ||
| 308 | sprintf (buf, "%d: window %p (`%s')%s\n", | 275 | sprintf (buf, "%"pMu": window %p (`%s')%s\n", |
| 309 | history_tick++, | 276 | history_tick++, |
| 310 | w, | 277 | w, |
| 311 | ((BUFFERP (w->buffer) | 278 | ((BUFFERP (w->buffer) |
| @@ -331,7 +298,7 @@ add_frame_display_history (struct frame *f, int paused_p) | |||
| 331 | buf = redisplay_history[history_idx].trace; | 298 | buf = redisplay_history[history_idx].trace; |
| 332 | ++history_idx; | 299 | ++history_idx; |
| 333 | 300 | ||
| 334 | sprintf (buf, "%d: update frame %p%s", | 301 | sprintf (buf, "%"pMu": update frame %p%s", |
| 335 | history_tick++, | 302 | history_tick++, |
| 336 | f, paused_p ? " ***paused***" : ""); | 303 | f, paused_p ? " ***paused***" : ""); |
| 337 | } | 304 | } |
| @@ -532,7 +499,7 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 532 | /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ | 499 | /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ |
| 533 | if (matrix->rows_allocated < dim.height) | 500 | if (matrix->rows_allocated < dim.height) |
| 534 | { | 501 | { |
| 535 | int size = dim.height * sizeof (struct glyph_row); | 502 | ptrdiff_t size = dim.height * sizeof (struct glyph_row); |
| 536 | new_rows = dim.height - matrix->rows_allocated; | 503 | new_rows = dim.height - matrix->rows_allocated; |
| 537 | matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size); | 504 | matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size); |
| 538 | memset (matrix->rows + matrix->rows_allocated, 0, | 505 | memset (matrix->rows + matrix->rows_allocated, 0, |
| @@ -1199,7 +1166,7 @@ prepare_desired_row (struct glyph_row *row) | |||
| 1199 | { | 1166 | { |
| 1200 | if (!row->enabled_p) | 1167 | if (!row->enabled_p) |
| 1201 | { | 1168 | { |
| 1202 | unsigned rp = row->reversed_p; | 1169 | int rp = row->reversed_p; |
| 1203 | 1170 | ||
| 1204 | clear_glyph_row (row); | 1171 | clear_glyph_row (row); |
| 1205 | row->enabled_p = 1; | 1172 | row->enabled_p = 1; |
| @@ -1243,7 +1210,7 @@ line_hash_code (struct glyph_row *row) | |||
| 1243 | the number of characters in the line. If must_write_spaces is | 1210 | the number of characters in the line. If must_write_spaces is |
| 1244 | zero, leading and trailing spaces are ignored. */ | 1211 | zero, leading and trailing spaces are ignored. */ |
| 1245 | 1212 | ||
| 1246 | static unsigned int | 1213 | static int |
| 1247 | line_draw_cost (struct glyph_matrix *matrix, int vpos) | 1214 | line_draw_cost (struct glyph_matrix *matrix, int vpos) |
| 1248 | { | 1215 | { |
| 1249 | struct glyph_row *row = matrix->rows + vpos; | 1216 | struct glyph_row *row = matrix->rows + vpos; |
| @@ -1436,7 +1403,7 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) | |||
| 1436 | needed = matrix_dim.width * matrix_dim.height; | 1403 | needed = matrix_dim.width * matrix_dim.height; |
| 1437 | if (needed > pool->nglyphs) | 1404 | if (needed > pool->nglyphs) |
| 1438 | { | 1405 | { |
| 1439 | int size = needed * sizeof (struct glyph); | 1406 | ptrdiff_t size = needed * sizeof (struct glyph); |
| 1440 | 1407 | ||
| 1441 | if (pool->glyphs) | 1408 | if (pool->glyphs) |
| 1442 | { | 1409 | { |
| @@ -2062,7 +2029,7 @@ save_current_matrix (struct frame *f) | |||
| 2062 | { | 2029 | { |
| 2063 | struct glyph_row *from = f->current_matrix->rows + i; | 2030 | struct glyph_row *from = f->current_matrix->rows + i; |
| 2064 | struct glyph_row *to = saved->rows + i; | 2031 | struct glyph_row *to = saved->rows + i; |
| 2065 | size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); | 2032 | ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); |
| 2066 | to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes); | 2033 | to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes); |
| 2067 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); | 2034 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); |
| 2068 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | 2035 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; |
| @@ -2084,7 +2051,7 @@ restore_current_matrix (struct frame *f, struct glyph_matrix *saved) | |||
| 2084 | { | 2051 | { |
| 2085 | struct glyph_row *from = saved->rows + i; | 2052 | struct glyph_row *from = saved->rows + i; |
| 2086 | struct glyph_row *to = f->current_matrix->rows + i; | 2053 | struct glyph_row *to = f->current_matrix->rows + i; |
| 2087 | size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); | 2054 | ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); |
| 2088 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); | 2055 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); |
| 2089 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | 2056 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; |
| 2090 | xfree (from->glyphs[TEXT_AREA]); | 2057 | xfree (from->glyphs[TEXT_AREA]); |
| @@ -2272,7 +2239,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f) | |||
| 2272 | static void | 2239 | static void |
| 2273 | adjust_frame_message_buffer (struct frame *f) | 2240 | adjust_frame_message_buffer (struct frame *f) |
| 2274 | { | 2241 | { |
| 2275 | int size = FRAME_MESSAGE_BUF_SIZE (f) + 1; | 2242 | ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1; |
| 2276 | 2243 | ||
| 2277 | if (FRAME_MESSAGE_BUF (f)) | 2244 | if (FRAME_MESSAGE_BUF (f)) |
| 2278 | { | 2245 | { |
| @@ -4302,7 +4269,8 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4302 | struct glyph_matrix *current_matrix = w->current_matrix; | 4269 | struct glyph_matrix *current_matrix = w->current_matrix; |
| 4303 | int yb = window_text_bottom_y (w); | 4270 | int yb = window_text_bottom_y (w); |
| 4304 | int i, j, first_old, first_new, last_old, last_new; | 4271 | int i, j, first_old, first_new, last_old, last_new; |
| 4305 | int nruns, nbytes, n, run_idx; | 4272 | int nruns, n, run_idx; |
| 4273 | ptrdiff_t nbytes; | ||
| 4306 | struct row_entry *entry; | 4274 | struct row_entry *entry; |
| 4307 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 4275 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 4308 | 4276 | ||
| @@ -6327,11 +6295,14 @@ init_display (void) | |||
| 6327 | int width = FRAME_TOTAL_COLS (sf); | 6295 | int width = FRAME_TOTAL_COLS (sf); |
| 6328 | int height = FRAME_LINES (sf); | 6296 | int height = FRAME_LINES (sf); |
| 6329 | 6297 | ||
| 6330 | unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph); | ||
| 6331 | |||
| 6332 | /* If these sizes are so big they cause overflow, just ignore the | 6298 | /* If these sizes are so big they cause overflow, just ignore the |
| 6333 | change. It's not clear what better we could do. */ | 6299 | change. It's not clear what better we could do. The rest of |
| 6334 | if (total_glyphs / sizeof (struct glyph) / height != width + 2) | 6300 | the code assumes that (width + 2) * height * sizeof (struct glyph) |
| 6301 | does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */ | ||
| 6302 | if (INT_ADD_OVERFLOW (width, 2) | ||
| 6303 | || INT_MULTIPLY_OVERFLOW (width + 2, height) | ||
| 6304 | || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) | ||
| 6305 | < (width + 2) * height)) | ||
| 6335 | fatal ("screen size %dx%d too big", width, height); | 6306 | fatal ("screen size %dx%d too big", width, height); |
| 6336 | } | 6307 | } |
| 6337 | 6308 | ||