/* Enlarge MATRIX->rows if necessary. New rows are cleared. */
if (matrix->rows_allocated < dim.height)
{
- ptrdiff_t size = dim.height * sizeof (struct glyph_row);
+ ptrdiff_t size;
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph_row) < dim.height)
+ memory_full (SIZE_MAX);
+ size = dim.height * sizeof (struct glyph_row);
new_rows = dim.height - matrix->rows_allocated;
matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
memset (matrix->rows + matrix->rows_allocated, 0,
struct glyph_row *row = matrix->rows;
struct glyph_row *end = row + matrix->rows_allocated;
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < dim.width)
+ memory_full (SIZE_MAX);
+
while (row < end)
{
row->glyphs[LEFT_MARGIN_AREA]
struct glyph *end = beg + row->used[TEXT_AREA];
int len;
Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
- int glyph_table_len = GLYPH_TABLE_LENGTH;
+ ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */
static int
realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
{
- int needed;
+ ptrdiff_t needed;
int changed_p;
changed_p = (pool->glyphs == 0
|| matrix_dim.height != pool->nrows
|| matrix_dim.width != pool->ncolumns);
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) / matrix_dim.width
+ < matrix_dim.height)
+ memory_full (SIZE_MAX);
+
/* Enlarge the glyph pool. */
- needed = matrix_dim.width * matrix_dim.height;
+ needed = matrix_dim.width;
+ needed *= matrix_dim.height;
if (needed > pool->nglyphs)
{
ptrdiff_t size = needed * sizeof (struct glyph);
-
- if (pool->glyphs)
- {
- pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
- memset (pool->glyphs + pool->nglyphs, 0,
- size - pool->nglyphs * sizeof (struct glyph));
- }
- else
- {
- pool->glyphs = (struct glyph *) xmalloc (size);
- memset (pool->glyphs, 0, size);
- }
-
+ pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
+ memset (pool->glyphs + pool->nglyphs, 0,
+ size - pool->nglyphs * sizeof (struct glyph));
pool->nglyphs = needed;
}
int new_line_number;
/* Bucket index of this row_entry in the hash table row_table. */
- int bucket;
+ ptrdiff_t bucket;
/* The row described by this entry. */
struct glyph_row *row;
that we need a larger one. */
static struct row_entry *row_entry_pool;
-static int row_entry_pool_size;
+static ptrdiff_t row_entry_pool_size;
/* Index of next free entry in row_entry_pool. */
-static int row_entry_idx;
+static ptrdiff_t row_entry_idx;
/* The hash table used during scrolling, and the table's size. This
table is used to quickly identify equal rows in the desired and
current matrix. */
static struct row_entry **row_table;
-static int row_table_size;
+static ptrdiff_t row_table_size;
/* Vectors of pointers to row_entry structures belonging to the
current and desired matrix, and the size of the vectors. */
add_row_entry (struct glyph_row *row)
{
struct row_entry *entry;
- int i = row->hash % row_table_size;
+ ptrdiff_t i = row->hash % row_table_size;
entry = row_table[i];
while (entry && !row_equal_p (entry->row, row, 1))
struct glyph_matrix *desired_matrix = w->desired_matrix;
struct glyph_matrix *current_matrix = w->current_matrix;
int yb = window_text_bottom_y (w);
- int i, j, first_old, first_new, last_old, last_new;
- int nruns, n, run_idx;
- ptrdiff_t nbytes;
+ ptrdiff_t i;
+ int j, first_old, first_new, last_old, last_new;
+ int nruns, run_idx;
+ ptrdiff_t n, nbytes;
struct row_entry *entry;
struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
if (last_new == first_new)
return 0;
+ /* Check for integer overflow in xrealloc size calculation.
+
+ If next_almost_prime checks (N) for divisibility by 2..10, then
+ it can return at most N + 10, e.g., next_almost_prime (1) == 11.
+ So, set next_almost_prime_increment_max to 10.
+
+ It's just a coincidence that next_almost_prime_increment_max ==
+ NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were
+ 13, then next_almost_prime_increment_max would be 14, e.g.,
+ because next_almost_prime (113) would be 127. */
+ {
+ verify (NEXT_ALMOST_PRIME_LIMIT == 11);
+ enum { next_almost_prime_increment_max = 10 };
+ ptrdiff_t alloc_max = min (PTRDIFF_MAX, SIZE_MAX);
+ ptrdiff_t row_table_max =
+ ((alloc_max - next_almost_prime_increment_max)
+ / (3 * sizeof *row_table));
+ ptrdiff_t row_entry_pool_max = alloc_max / sizeof *row_entry_pool;
+ int n_max = min (INT_MAX, min (row_table_max, row_entry_pool_max));
+ ptrdiff_t old_lines_max = alloc_max / sizeof *old_lines;
+ int current_nrows_max = min (n_max - desired_matrix->nrows, old_lines_max);
+ int desired_nrows_max =
+ min (INT_MAX,
+ alloc_max / max (sizeof *new_lines,
+ max (sizeof *runs, sizeof *run_pool)));
+ if (current_nrows_max < current_matrix->nrows
+ || desired_nrows_max < desired_matrix->nrows)
+ memory_full (SIZE_MAX);
+ }
+
/* Reallocate vectors, tables etc. if necessary. */
if (current_matrix->nrows > old_lines_size)
{
- old_lines_size = current_matrix->nrows;
- nbytes = old_lines_size * sizeof *old_lines;
+ nbytes = current_matrix->nrows * sizeof *old_lines;
old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
+ old_lines_size = current_matrix->nrows;
}
if (desired_matrix->nrows > new_lines_size)
{
- new_lines_size = desired_matrix->nrows;
- nbytes = new_lines_size * sizeof *new_lines;
+ nbytes = desired_matrix->nrows * sizeof *new_lines;
new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
+ new_lines_size = desired_matrix->nrows;
}
- n = desired_matrix->nrows + current_matrix->nrows;
- if (3 * n > row_table_size)
+ n = desired_matrix->nrows;
+ n += current_matrix->nrows;
+ if (row_table_size / 3 < n)
{
- row_table_size = next_almost_prime (3 * n);
- nbytes = row_table_size * sizeof *row_table;
+ ptrdiff_t size = next_almost_prime (3 * n);
+ nbytes = size * sizeof *row_table;
row_table = (struct row_entry **) xrealloc (row_table, nbytes);
+ row_table_size = size;
memset (row_table, 0, nbytes);
}
if (n > row_entry_pool_size)
{
- row_entry_pool_size = n;
- nbytes = row_entry_pool_size * sizeof *row_entry_pool;
+ nbytes = n * sizeof *row_entry_pool;
row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
+ row_entry_pool_size = n;
}
if (desired_matrix->nrows > runs_size)
{
- runs_size = desired_matrix->nrows;
- nbytes = runs_size * sizeof *runs;
+ nbytes = desired_matrix->nrows * sizeof *runs;
runs = (struct run **) xrealloc (runs, nbytes);
- nbytes = runs_size * sizeof *run_pool;
+ nbytes = desired_matrix->nrows * sizeof *run_pool;
run_pool = (struct run *) xrealloc (run_pool, nbytes);
+ runs_size = desired_matrix->nrows;
}
nruns = run_idx = 0;