From 3d0c92a26bb73fdc542e4d9e467b31fd0ad02417 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 28 Jul 2011 14:34:39 -0700 Subject: [PATCH] * 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. --- src/ChangeLog | 8 ++++++++ src/doc.c | 37 +++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index d7d32e90089..6cf9a1f8622 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,13 @@ 2011-07-28 Paul Eggert + * 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): diff --git a/src/doc.c b/src/doc.c index 69646f5af51..bd1831dde0e 100644 --- a/src/doc.c +++ b/src/doc.c @@ -39,7 +39,7 @@ Lisp_Object Qfunction_documentation; 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, @@ -166,18 +166,23 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) 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)); @@ -713,16 +718,16 @@ a new string, without any text properties, is returned. */) 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; @@ -774,7 +779,7 @@ a new string, without any text properties, is returned. */) } else if (strp[0] == '\\' && strp[1] == '[') { - EMACS_INT start_idx; + ptrdiff_t start_idx; int follow_remap = 1; changed = 1; @@ -813,7 +818,9 @@ a new string, without any text properties, is returned. */) 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); @@ -836,7 +843,7 @@ a new string, without any text properties, is returned. */) 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; @@ -907,7 +914,9 @@ a new string, without any text properties, is returned. */) 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); -- 2.11.4.GIT