aboutsummaryrefslogtreecommitdiffstats
path: root/src/frame.c
diff options
context:
space:
mode:
authorPaul Eggert2014-09-07 00:04:01 -0700
committerPaul Eggert2014-09-07 00:04:01 -0700
commitb3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d (patch)
treecf138164e4f8887394f52cb22da594d1713da316 /src/frame.c
parent930fb80f9e2815e599eb1de699668d42e305fa21 (diff)
downloademacs-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.c56
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)
4010static Lisp_Object 4008static Lisp_Object
4011xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass) 4009xrdb_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);