diff options
| author | Paul Eggert | 2014-09-07 00:04:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-09-07 00:04:01 -0700 |
| commit | b3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d (patch) | |
| tree | cf138164e4f8887394f52cb22da594d1713da316 /src/frame.c | |
| parent | 930fb80f9e2815e599eb1de699668d42e305fa21 (diff) | |
| download | emacs-b3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d.tar.gz emacs-b3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d.zip | |
Use SAFE_ALLOCA etc. to avoid unbounded stack allocation.
This follows up on the recent thread in emacs-devel on alloca; see:
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00042.html
This patch also cleans up alloca-related glitches noted while
examining the code looking for unbounded alloca.
* alloc.c (listn):
* callproc.c (init_callproc):
Rewrite to avoid need for alloca.
* buffer.c (mouse_face_overlay_overlaps)
(report_overlay_modification):
* buffer.h (GET_OVERLAYS_AT):
* coding.c (make_subsidiaries):
* doc.c (Fsnarf_documentation):
* editfns.c (Fuser_full_name):
* fileio.c (Ffile_name_directory, Fexpand_file_name)
(search_embedded_absfilename, Fsubstitute_in_file_name):
* fns.c (Fmake_hash_table):
* font.c (font_vconcat_entity_vectors, font_update_drivers):
* fontset.c (fontset_pattern_regexp, Ffontset_info):
* frame.c (Fmake_terminal_frame, x_set_frame_parameters)
(xrdb_get_resource, x_get_resource_string):
* ftfont.c (ftfont_get_charset, ftfont_check_otf, ftfont_drive_otf):
* ftxfont.c (ftxfont_draw):
* image.c (xbm_load, xpm_load, jpeg_load_body):
* keyboard.c (echo_add_key, menu_bar_items, tool_bar_items):
* keymap.c (Fdescribe_buffer_bindings, describe_map):
* lread.c (openp):
* menu.c (digest_single_submenu, find_and_call_menu_selection)
(find_and_return_menu_selection):
* print.c (PRINTFINISH):
* process.c (Fformat_network_address):
* scroll.c (do_scrolling, do_direct_scrolling, scrolling_1):
* search.c (search_buffer, Fmatch_data, Fregexp_quote):
* sound.c (wav_play, au_play):
* syntax.c (skip_chars):
* term.c (tty_menu_activate, tty_menu_show):
* textprop.c (get_char_property_and_overlay):
* window.c (Fset_window_configuration):
* xdisp.c (safe__call, next_overlay_change, vmessage)
(compute_overhangs_and_x, draw_glyphs, note_mouse_highlight):
* xfaces.c (face_at_buffer_position):
* xmenu.c (x_menu_show):
Use SAFE_ALLOCA etc. instead of plain alloca, since the
allocation size isn't bounded.
* callint.c (Fcall_interactively): Redo memory_full check
so that it can be done at compile-time on some platforms.
* coding.c (MAX_LOOKUP_MAX): New constant.
(get_translation_table): Use it.
* callproc.c (call_process): Use SAFE_NALLOCA instead of
SAFE_ALLOCA, to catch integer overflows on size calculation.
(exec_failed) [!DOS_NT]: New function.
(child_setup) [!DOS_NT]: Use it.
* editfns.c (Ftranspose_regions):
Hoist USE_SAFE_ALLOC + SAFE_FREE out of 'if'.
* editfns.c (check_translation):
Allocate larger buffers on the heap.
* eval.c (internal_lisp_condition_case):
Check for MAX_ALLOCA overflow.
* fns.c (sort_vector): Use SAFE_ALLOCA_LISP rather than Fmake_vector.
(Fbase64_encode_region, Fbase64_decode_region):
Avoid unnecessary calls to SAFE_FREE before 'error'.
* buffer.c (mouse_face_overlay_overlaps):
* editfns.c (Fget_pos_property, check_translation):
* eval.c (Ffuncall):
* font.c (font_unparse_xlfd, font_find_for_lface):
* ftfont.c (ftfont_drive_otf):
* keyboard.c (echo_add_key, read_decoded_event_from_main_queue)
(menu_bar_items, tool_bar_items):
* sound.c (Fplay_sound_internal):
* xdisp.c (load_overlay_strings, dump_glyph_row):
Use an ordinary auto buffer rather than alloca, since the
allocation size is fixed and small.
* ftfont.c: Include <c-strcase.h>.
(matching_prefix): New function.
(get_adstyle_property): Use it, to avoid need for alloca.
* keyboard.c (echo_add_key):
* keymap.c (describe_map): Use ptrdiff_t, not int.
* keyboard.c (echo_add_key): Prefer sizeof to strlen.
* keymap.c (Fdescribe_buffer_bindings): Use SBYTES, not SCHARS,
when counting bytes.
* lisp.h (xlispstrdupa): Remove, replacing with ...
(SAFE_ALLOCA_STRING): ... new macro with different API.
This fixes a portability problem, namely, alloca result
passed to another function. All uses changed.
(SAFE_ALLOCA, SAFE_ALLOCA_LISP): Check for MAX_ALLOCA,
not MAX_ALLOCA - 1.
* regex.c (REGEX_USE_SAFE_ALLOCA, REGEX_SAFE_FREE)
(REGEX_ALLOCATE): New macros.
(REGEX_REALLOCATE, REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK)
(REGEX_FREE_STACK, FREE_VARIABLES, re_match_2_internal):
Use them.
* xdisp.c (message3): Use SAFE_ALLOCA_STRING rather than doing it
by hand.
(decode_mode_spec_coding): Store directly into buf rather than
into an alloca temporary and copying the temporary to the buf.
Fixes: debbugs:18410
Diffstat (limited to 'src/frame.c')
| -rw-r--r-- | src/frame.c | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/src/frame.c b/src/frame.c index 96617976ecd..7077d42dd1b 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -994,22 +994,24 @@ affects all frames on the same terminal device. */) | |||
| 994 | { | 994 | { |
| 995 | char *name = 0, *type = 0; | 995 | char *name = 0, *type = 0; |
| 996 | Lisp_Object tty, tty_type; | 996 | Lisp_Object tty, tty_type; |
| 997 | USE_SAFE_ALLOCA; | ||
| 997 | 998 | ||
| 998 | tty = get_future_frame_param | 999 | tty = get_future_frame_param |
| 999 | (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) | 1000 | (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) |
| 1000 | ? FRAME_TTY (XFRAME (selected_frame))->name | 1001 | ? FRAME_TTY (XFRAME (selected_frame))->name |
| 1001 | : NULL)); | 1002 | : NULL)); |
| 1002 | if (!NILP (tty)) | 1003 | if (!NILP (tty)) |
| 1003 | name = xlispstrdupa (tty); | 1004 | SAFE_ALLOCA_STRING (name, tty); |
| 1004 | 1005 | ||
| 1005 | tty_type = get_future_frame_param | 1006 | tty_type = get_future_frame_param |
| 1006 | (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) | 1007 | (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame)) |
| 1007 | ? FRAME_TTY (XFRAME (selected_frame))->type | 1008 | ? FRAME_TTY (XFRAME (selected_frame))->type |
| 1008 | : NULL)); | 1009 | : NULL)); |
| 1009 | if (!NILP (tty_type)) | 1010 | if (!NILP (tty_type)) |
| 1010 | type = xlispstrdupa (tty_type); | 1011 | SAFE_ALLOCA_STRING (type, tty_type); |
| 1011 | 1012 | ||
| 1012 | t = init_tty (name, type, 0); /* Errors are not fatal. */ | 1013 | t = init_tty (name, type, 0); /* Errors are not fatal. */ |
| 1014 | SAFE_FREE (); | ||
| 1013 | } | 1015 | } |
| 1014 | 1016 | ||
| 1015 | f = make_terminal_frame (t); | 1017 | f = make_terminal_frame (t); |
| @@ -3017,14 +3019,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3017 | #ifdef HAVE_X_WINDOWS | 3019 | #ifdef HAVE_X_WINDOWS |
| 3018 | bool icon_left_no_change = 0, icon_top_no_change = 0; | 3020 | bool icon_left_no_change = 0, icon_top_no_change = 0; |
| 3019 | #endif | 3021 | #endif |
| 3020 | struct gcpro gcpro1, gcpro2; | ||
| 3021 | 3022 | ||
| 3022 | i = 0; | 3023 | i = 0; |
| 3023 | for (tail = alist; CONSP (tail); tail = XCDR (tail)) | 3024 | for (tail = alist; CONSP (tail); tail = XCDR (tail)) |
| 3024 | i++; | 3025 | i++; |
| 3025 | 3026 | ||
| 3026 | parms = alloca (i * sizeof *parms); | 3027 | USE_SAFE_ALLOCA; |
| 3027 | values = alloca (i * sizeof *values); | 3028 | SAFE_ALLOCA_LISP (parms, 2 * i); |
| 3029 | values = parms + i; | ||
| 3028 | 3030 | ||
| 3029 | /* Extract parm names and values into those vectors. */ | 3031 | /* Extract parm names and values into those vectors. */ |
| 3030 | 3032 | ||
| @@ -3041,10 +3043,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3041 | /* TAIL and ALIST are not used again below here. */ | 3043 | /* TAIL and ALIST are not used again below here. */ |
| 3042 | alist = tail = Qnil; | 3044 | alist = tail = Qnil; |
| 3043 | 3045 | ||
| 3044 | GCPRO2 (*parms, *values); | ||
| 3045 | gcpro1.nvars = i; | ||
| 3046 | gcpro2.nvars = i; | ||
| 3047 | |||
| 3048 | /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, | 3046 | /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, |
| 3049 | because their values appear in VALUES and strings are not valid. */ | 3047 | because their values appear in VALUES and strings are not valid. */ |
| 3050 | top = left = Qunbound; | 3048 | top = left = Qunbound; |
| @@ -3273,7 +3271,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist) | |||
| 3273 | #endif /* HAVE_X_WINDOWS */ | 3271 | #endif /* HAVE_X_WINDOWS */ |
| 3274 | } | 3272 | } |
| 3275 | 3273 | ||
| 3276 | UNGCPRO; | 3274 | SAFE_FREE (); |
| 3277 | } | 3275 | } |
| 3278 | 3276 | ||
| 3279 | 3277 | ||
| @@ -4010,10 +4008,6 @@ validate_x_resource_name (void) | |||
| 4010 | static Lisp_Object | 4008 | static Lisp_Object |
| 4011 | xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) | 4009 | xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) |
| 4012 | { | 4010 | { |
| 4013 | register char *value; | ||
| 4014 | char *name_key; | ||
| 4015 | char *class_key; | ||
| 4016 | |||
| 4017 | CHECK_STRING (attribute); | 4011 | CHECK_STRING (attribute); |
| 4018 | CHECK_STRING (class); | 4012 | CHECK_STRING (class); |
| 4019 | 4013 | ||
| @@ -4028,17 +4022,20 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li | |||
| 4028 | 4022 | ||
| 4029 | /* Allocate space for the components, the dots which separate them, | 4023 | /* Allocate space for the components, the dots which separate them, |
| 4030 | and the final '\0'. Make them big enough for the worst case. */ | 4024 | and the final '\0'. Make them big enough for the worst case. */ |
| 4031 | name_key = alloca (SBYTES (Vx_resource_name) | 4025 | ptrdiff_t name_keysize = (SBYTES (Vx_resource_name) |
| 4032 | + (STRINGP (component) | 4026 | + (STRINGP (component) |
| 4033 | ? SBYTES (component) : 0) | 4027 | ? SBYTES (component) : 0) |
| 4034 | + SBYTES (attribute) | 4028 | + SBYTES (attribute) |
| 4035 | + 3); | 4029 | + 3); |
| 4036 | 4030 | ||
| 4037 | class_key = alloca (SBYTES (Vx_resource_class) | 4031 | ptrdiff_t class_keysize = (SBYTES (Vx_resource_class) |
| 4038 | + SBYTES (class) | 4032 | + SBYTES (class) |
| 4039 | + (STRINGP (subclass) | 4033 | + (STRINGP (subclass) |
| 4040 | ? SBYTES (subclass) : 0) | 4034 | ? SBYTES (subclass) : 0) |
| 4041 | + 3); | 4035 | + 3); |
| 4036 | USE_SAFE_ALLOCA; | ||
| 4037 | char *name_key = SAFE_ALLOCA (name_keysize + class_keysize); | ||
| 4038 | char *class_key = name_key + name_keysize; | ||
| 4042 | 4039 | ||
| 4043 | /* Start with emacs.FRAMENAME for the name (the specific one) | 4040 | /* Start with emacs.FRAMENAME for the name (the specific one) |
| 4044 | and with `Emacs' for the class key (the general one). */ | 4041 | and with `Emacs' for the class key (the general one). */ |
| @@ -4060,7 +4057,8 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li | |||
| 4060 | strcat (name_key, "."); | 4057 | strcat (name_key, "."); |
| 4061 | strcat (name_key, SSDATA (attribute)); | 4058 | strcat (name_key, SSDATA (attribute)); |
| 4062 | 4059 | ||
| 4063 | value = x_get_string_resource (rdb, name_key, class_key); | 4060 | char *value = x_get_string_resource (rdb, name_key, class_key); |
| 4061 | SAFE_FREE(); | ||
| 4064 | 4062 | ||
| 4065 | if (value && *value) | 4063 | if (value && *value) |
| 4066 | return build_string (value); | 4064 | return build_string (value); |
| @@ -4112,8 +4110,10 @@ x_get_resource_string (const char *attribute, const char *class) | |||
| 4112 | 4110 | ||
| 4113 | /* Allocate space for the components, the dots which separate them, | 4111 | /* Allocate space for the components, the dots which separate them, |
| 4114 | and the final '\0'. */ | 4112 | and the final '\0'. */ |
| 4115 | char *name_key = SAFE_ALLOCA (invocation_namelen + strlen (attribute) + 2); | 4113 | ptrdiff_t name_keysize = invocation_namelen + strlen (attribute) + 2; |
| 4116 | char *class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); | 4114 | ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2; |
| 4115 | char *name_key = SAFE_ALLOCA (name_keysize + class_keysize); | ||
| 4116 | char *class_key = name_key + name_keysize; | ||
| 4117 | 4117 | ||
| 4118 | esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); | 4118 | esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); |
| 4119 | sprintf (class_key, "%s.%s", EMACS_CLASS, class); | 4119 | sprintf (class_key, "%s.%s", EMACS_CLASS, class); |