2011-07-28 Paul Eggert <eggert@cs.ucla.edu>
+ * doc.c: Integer and memory overflow fixes.
+ (get_doc_string_buffer_size): Now ptrdiff_t, not int.
+ (get_doc_string): Check for size calculation overflow.
+ Don't update size until allocation succeeds.
+ (get_doc_string, Fsubstitute_command_keys): Use ptrdiff_t, not
+ EMACS_INT, where ptrdiff_t will do.
+ (Fsubstitute_command_keys): Check for string overflow.
+
Integer and memory overflow fixes for display code.
* dispextern.h (struct glyph_pool.nglyphs): Now ptrdiff_t, not int.
* dispnew.c (adjust_glyph_matrix, realloc_glyph_pool, scrolling_window):
extern Lisp_Object Qclosure;
/* Buffer used for reading from documentation file. */
static char *get_doc_string_buffer;
-static int get_doc_string_buffer_size;
+static ptrdiff_t get_doc_string_buffer_size;
static unsigned char *read_bytecode_pointer;
static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object,
p = get_doc_string_buffer;
while (1)
{
- EMACS_INT space_left = (get_doc_string_buffer_size
+ ptrdiff_t space_left = (get_doc_string_buffer_size
- (p - get_doc_string_buffer));
int nread;
/* Allocate or grow the buffer if we need to. */
if (space_left == 0)
{
- EMACS_INT in_buffer = p - get_doc_string_buffer;
- get_doc_string_buffer_size += 16 * 1024;
+ ptrdiff_t in_buffer = p - get_doc_string_buffer;
+ enum { incr = 16 * 1024 };
+ ptrdiff_t size;
+ if (min (PTRDIFF_MAX, SIZE_MAX) - 1 - incr
+ < get_doc_string_buffer_size)
+ memory_full (SIZE_MAX);
+ size = get_doc_string_buffer_size + incr;
get_doc_string_buffer
- = (char *) xrealloc (get_doc_string_buffer,
- get_doc_string_buffer_size + 1);
+ = (char *) xrealloc (get_doc_string_buffer, size + 1);
+ get_doc_string_buffer_size = size;
p = get_doc_string_buffer + in_buffer;
space_left = (get_doc_string_buffer_size
- (p - get_doc_string_buffer));
int changed = 0;
register unsigned char *strp;
register char *bufp;
- EMACS_INT idx;
- EMACS_INT bsize;
+ ptrdiff_t idx;
+ ptrdiff_t bsize;
Lisp_Object tem;
Lisp_Object keymap;
unsigned char *start;
- EMACS_INT length, length_byte;
+ ptrdiff_t length, length_byte;
Lisp_Object name;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int multibyte;
- EMACS_INT nchars;
+ ptrdiff_t nchars;
if (NILP (string))
return Qnil;
}
else if (strp[0] == '\\' && strp[1] == '[')
{
- EMACS_INT start_idx;
+ ptrdiff_t start_idx;
int follow_remap = 1;
changed = 1;
if (NILP (tem)) /* but not on any keys */
{
- EMACS_INT offset = bufp - buf;
+ ptrdiff_t offset = bufp - buf;
+ if (STRING_BYTES_BOUND - 4 < bsize)
+ string_overflow ();
buf = (char *) xrealloc (buf, bsize += 4);
bufp = buf + offset;
memcpy (bufp, "M-x ", 4);
else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<'))
{
struct buffer *oldbuf;
- EMACS_INT start_idx;
+ ptrdiff_t start_idx;
/* This is for computing the SHADOWS arg for describe_map_tree. */
Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil);
Lisp_Object earlier_maps;
length_byte = SBYTES (tem);
subst:
{
- EMACS_INT offset = bufp - buf;
+ ptrdiff_t offset = bufp - buf;
+ if (STRING_BYTES_BOUND - length_byte < bsize)
+ string_overflow ();
buf = (char *) xrealloc (buf, bsize += length_byte);
bufp = buf + offset;
memcpy (bufp, start, length_byte);