diff options
| author | Paul Eggert | 2011-07-28 14:34:39 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 14:34:39 -0700 |
| commit | 3d0c92a26bb73fdc542e4d9e467b31fd0ad02417 (patch) | |
| tree | 30754be8833646ed36d98fe37695b5a8630806b5 /src/doc.c | |
| parent | ca9ce8f2cb9d3d70c4e7d9dc9299ea4d5d71dfbc (diff) | |
| download | emacs-3d0c92a26bb73fdc542e4d9e467b31fd0ad02417.tar.gz emacs-3d0c92a26bb73fdc542e4d9e467b31fd0ad02417.zip | |
* 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.
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 37 |
1 files changed, 23 insertions, 14 deletions
| @@ -39,7 +39,7 @@ Lisp_Object Qfunction_documentation; | |||
| 39 | extern Lisp_Object Qclosure; | 39 | extern Lisp_Object Qclosure; |
| 40 | /* Buffer used for reading from documentation file. */ | 40 | /* Buffer used for reading from documentation file. */ |
| 41 | static char *get_doc_string_buffer; | 41 | static char *get_doc_string_buffer; |
| 42 | static int get_doc_string_buffer_size; | 42 | static ptrdiff_t get_doc_string_buffer_size; |
| 43 | 43 | ||
| 44 | static unsigned char *read_bytecode_pointer; | 44 | static unsigned char *read_bytecode_pointer; |
| 45 | static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, | 45 | static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, |
| @@ -166,18 +166,23 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 166 | p = get_doc_string_buffer; | 166 | p = get_doc_string_buffer; |
| 167 | while (1) | 167 | while (1) |
| 168 | { | 168 | { |
| 169 | EMACS_INT space_left = (get_doc_string_buffer_size | 169 | ptrdiff_t space_left = (get_doc_string_buffer_size |
| 170 | - (p - get_doc_string_buffer)); | 170 | - (p - get_doc_string_buffer)); |
| 171 | int nread; | 171 | int nread; |
| 172 | 172 | ||
| 173 | /* Allocate or grow the buffer if we need to. */ | 173 | /* Allocate or grow the buffer if we need to. */ |
| 174 | if (space_left == 0) | 174 | if (space_left == 0) |
| 175 | { | 175 | { |
| 176 | EMACS_INT in_buffer = p - get_doc_string_buffer; | 176 | ptrdiff_t in_buffer = p - get_doc_string_buffer; |
| 177 | get_doc_string_buffer_size += 16 * 1024; | 177 | enum { incr = 16 * 1024 }; |
| 178 | ptrdiff_t size; | ||
| 179 | if (min (PTRDIFF_MAX, SIZE_MAX) - 1 - incr | ||
| 180 | < get_doc_string_buffer_size) | ||
| 181 | memory_full (SIZE_MAX); | ||
| 182 | size = get_doc_string_buffer_size + incr; | ||
| 178 | get_doc_string_buffer | 183 | get_doc_string_buffer |
| 179 | = (char *) xrealloc (get_doc_string_buffer, | 184 | = (char *) xrealloc (get_doc_string_buffer, size + 1); |
| 180 | get_doc_string_buffer_size + 1); | 185 | get_doc_string_buffer_size = size; |
| 181 | p = get_doc_string_buffer + in_buffer; | 186 | p = get_doc_string_buffer + in_buffer; |
| 182 | space_left = (get_doc_string_buffer_size | 187 | space_left = (get_doc_string_buffer_size |
| 183 | - (p - get_doc_string_buffer)); | 188 | - (p - get_doc_string_buffer)); |
| @@ -713,16 +718,16 @@ a new string, without any text properties, is returned. */) | |||
| 713 | int changed = 0; | 718 | int changed = 0; |
| 714 | register unsigned char *strp; | 719 | register unsigned char *strp; |
| 715 | register char *bufp; | 720 | register char *bufp; |
| 716 | EMACS_INT idx; | 721 | ptrdiff_t idx; |
| 717 | EMACS_INT bsize; | 722 | ptrdiff_t bsize; |
| 718 | Lisp_Object tem; | 723 | Lisp_Object tem; |
| 719 | Lisp_Object keymap; | 724 | Lisp_Object keymap; |
| 720 | unsigned char *start; | 725 | unsigned char *start; |
| 721 | EMACS_INT length, length_byte; | 726 | ptrdiff_t length, length_byte; |
| 722 | Lisp_Object name; | 727 | Lisp_Object name; |
| 723 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 728 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 724 | int multibyte; | 729 | int multibyte; |
| 725 | EMACS_INT nchars; | 730 | ptrdiff_t nchars; |
| 726 | 731 | ||
| 727 | if (NILP (string)) | 732 | if (NILP (string)) |
| 728 | return Qnil; | 733 | return Qnil; |
| @@ -774,7 +779,7 @@ a new string, without any text properties, is returned. */) | |||
| 774 | } | 779 | } |
| 775 | else if (strp[0] == '\\' && strp[1] == '[') | 780 | else if (strp[0] == '\\' && strp[1] == '[') |
| 776 | { | 781 | { |
| 777 | EMACS_INT start_idx; | 782 | ptrdiff_t start_idx; |
| 778 | int follow_remap = 1; | 783 | int follow_remap = 1; |
| 779 | 784 | ||
| 780 | changed = 1; | 785 | changed = 1; |
| @@ -813,7 +818,9 @@ a new string, without any text properties, is returned. */) | |||
| 813 | 818 | ||
| 814 | if (NILP (tem)) /* but not on any keys */ | 819 | if (NILP (tem)) /* but not on any keys */ |
| 815 | { | 820 | { |
| 816 | EMACS_INT offset = bufp - buf; | 821 | ptrdiff_t offset = bufp - buf; |
| 822 | if (STRING_BYTES_BOUND - 4 < bsize) | ||
| 823 | string_overflow (); | ||
| 817 | buf = (char *) xrealloc (buf, bsize += 4); | 824 | buf = (char *) xrealloc (buf, bsize += 4); |
| 818 | bufp = buf + offset; | 825 | bufp = buf + offset; |
| 819 | memcpy (bufp, "M-x ", 4); | 826 | memcpy (bufp, "M-x ", 4); |
| @@ -836,7 +843,7 @@ a new string, without any text properties, is returned. */) | |||
| 836 | else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<')) | 843 | else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<')) |
| 837 | { | 844 | { |
| 838 | struct buffer *oldbuf; | 845 | struct buffer *oldbuf; |
| 839 | EMACS_INT start_idx; | 846 | ptrdiff_t start_idx; |
| 840 | /* This is for computing the SHADOWS arg for describe_map_tree. */ | 847 | /* This is for computing the SHADOWS arg for describe_map_tree. */ |
| 841 | Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil); | 848 | Lisp_Object active_maps = Fcurrent_active_maps (Qnil, Qnil); |
| 842 | Lisp_Object earlier_maps; | 849 | Lisp_Object earlier_maps; |
| @@ -907,7 +914,9 @@ a new string, without any text properties, is returned. */) | |||
| 907 | length_byte = SBYTES (tem); | 914 | length_byte = SBYTES (tem); |
| 908 | subst: | 915 | subst: |
| 909 | { | 916 | { |
| 910 | EMACS_INT offset = bufp - buf; | 917 | ptrdiff_t offset = bufp - buf; |
| 918 | if (STRING_BYTES_BOUND - length_byte < bsize) | ||
| 919 | string_overflow (); | ||
| 911 | buf = (char *) xrealloc (buf, bsize += length_byte); | 920 | buf = (char *) xrealloc (buf, bsize += length_byte); |
| 912 | bufp = buf + offset; | 921 | bufp = buf + offset; |
| 913 | memcpy (bufp, start, length_byte); | 922 | memcpy (bufp, start, length_byte); |