aboutsummaryrefslogtreecommitdiffstats
path: root/src/font.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/font.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/font.c')
-rw-r--r--src/font.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/font.c b/src/font.c
index 054a68bfd94..90a5c6a2f88 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1299,6 +1299,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1299 1299
1300 val = AREF (font, FONT_SIZE_INDEX); 1300 val = AREF (font, FONT_SIZE_INDEX);
1301 eassert (NUMBERP (val) || NILP (val)); 1301 eassert (NUMBERP (val) || NILP (val));
1302 char font_size_index_buf[sizeof "-*"
1303 + MAX (INT_STRLEN_BOUND (EMACS_INT),
1304 1 + DBL_MAX_10_EXP + 1)];
1302 if (INTEGERP (val)) 1305 if (INTEGERP (val))
1303 { 1306 {
1304 EMACS_INT v = XINT (val); 1307 EMACS_INT v = XINT (val);
@@ -1306,8 +1309,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1306 v = pixel_size; 1309 v = pixel_size;
1307 if (v > 0) 1310 if (v > 0)
1308 { 1311 {
1309 f[XLFD_PIXEL_INDEX] = p = 1312 f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
1310 alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
1311 sprintf (p, "%"pI"d-*", v); 1313 sprintf (p, "%"pI"d-*", v);
1312 } 1314 }
1313 else 1315 else
@@ -1316,21 +1318,22 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1316 else if (FLOATP (val)) 1318 else if (FLOATP (val))
1317 { 1319 {
1318 double v = XFLOAT_DATA (val) * 10; 1320 double v = XFLOAT_DATA (val) * 10;
1319 f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1); 1321 f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
1320 sprintf (p, "*-%.0f", v); 1322 sprintf (p, "*-%.0f", v);
1321 } 1323 }
1322 else 1324 else
1323 f[XLFD_PIXEL_INDEX] = "*-*"; 1325 f[XLFD_PIXEL_INDEX] = "*-*";
1324 1326
1327 char dpi_index_buf[sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT)];
1325 if (INTEGERP (AREF (font, FONT_DPI_INDEX))) 1328 if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
1326 { 1329 {
1327 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX)); 1330 EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
1328 f[XLFD_RESX_INDEX] = p = 1331 f[XLFD_RESX_INDEX] = p = dpi_index_buf;
1329 alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
1330 sprintf (p, "%"pI"d-%"pI"d", v, v); 1332 sprintf (p, "%"pI"d-%"pI"d", v, v);
1331 } 1333 }
1332 else 1334 else
1333 f[XLFD_RESX_INDEX] = "*-*"; 1335 f[XLFD_RESX_INDEX] = "*-*";
1336
1334 if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) 1337 if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
1335 { 1338 {
1336 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX)); 1339 EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
@@ -1342,13 +1345,16 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
1342 } 1345 }
1343 else 1346 else
1344 f[XLFD_SPACING_INDEX] = "*"; 1347 f[XLFD_SPACING_INDEX] = "*";
1348
1349 char avgwidth_index_buf[INT_BUFSIZE_BOUND (EMACS_INT)];
1345 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) 1350 if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
1346 { 1351 {
1347 f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT)); 1352 f[XLFD_AVGWIDTH_INDEX] = p = avgwidth_index_buf;
1348 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))); 1353 sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
1349 } 1354 }
1350 else 1355 else
1351 f[XLFD_AVGWIDTH_INDEX] = "*"; 1356 f[XLFD_AVGWIDTH_INDEX] = "*";
1357
1352 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", 1358 len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
1353 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], 1359 f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
1354 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], 1360 f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
@@ -2185,13 +2191,17 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
2185static Lisp_Object 2191static Lisp_Object
2186font_vconcat_entity_vectors (Lisp_Object list) 2192font_vconcat_entity_vectors (Lisp_Object list)
2187{ 2193{
2188 int nargs = XINT (Flength (list)); 2194 EMACS_INT nargs = XFASTINT (Flength (list));
2189 Lisp_Object *args = alloca (word_size * nargs); 2195 Lisp_Object *args;
2190 int i; 2196 USE_SAFE_ALLOCA;
2197 SAFE_ALLOCA_LISP (args, nargs);
2198 ptrdiff_t i;
2191 2199
2192 for (i = 0; i < nargs; i++, list = XCDR (list)) 2200 for (i = 0; i < nargs; i++, list = XCDR (list))
2193 args[i] = XCAR (list); 2201 args[i] = XCAR (list);
2194 return Fvconcat (nargs, args); 2202 Lisp_Object result = Fvconcat (nargs, args);
2203 SAFE_FREE ();
2204 return result;
2195} 2205}
2196 2206
2197 2207
@@ -3219,9 +3229,10 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
3219 val = attrs[LFACE_FAMILY_INDEX]; 3229 val = attrs[LFACE_FAMILY_INDEX];
3220 val = font_intern_prop (SSDATA (val), SBYTES (val), 1); 3230 val = font_intern_prop (SSDATA (val), SBYTES (val), 1);
3221 } 3231 }
3232 Lisp_Object familybuf[3];
3222 if (NILP (val)) 3233 if (NILP (val))
3223 { 3234 {
3224 family = alloca ((sizeof family[0]) * 2); 3235 family = familybuf;
3225 family[0] = Qnil; 3236 family[0] = Qnil;
3226 family[1] = zero_vector; /* terminator. */ 3237 family[1] = zero_vector; /* terminator. */
3227 } 3238 }
@@ -3242,7 +3253,7 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
3242 } 3253 }
3243 else 3254 else
3244 { 3255 {
3245 family = alloca ((sizeof family[0]) * 3); 3256 family = familybuf;
3246 i = 0; 3257 i = 0;
3247 family[i++] = val; 3258 family[i++] = val;
3248 if (NILP (AREF (spec, FONT_FAMILY_INDEX))) 3259 if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
@@ -3529,8 +3540,9 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
3529 struct font_driver_list **list_table, **next; 3540 struct font_driver_list **list_table, **next;
3530 Lisp_Object tail; 3541 Lisp_Object tail;
3531 int i; 3542 int i;
3543 USE_SAFE_ALLOCA;
3532 3544
3533 list_table = alloca (sizeof list_table[0] * (num_font_drivers + 1)); 3545 SAFE_NALLOCA (list_table, 1, num_font_drivers + 1);
3534 for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail)) 3546 for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail))
3535 { 3547 {
3536 for (list = f->font_driver_list; list; list = list->next) 3548 for (list = f->font_driver_list; list; list = list->next)
@@ -3551,6 +3563,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
3551 next = &(*next)->next; 3563 next = &(*next)->next;
3552 } 3564 }
3553 *next = NULL; 3565 *next = NULL;
3566 SAFE_FREE ();
3554 3567
3555 if (! f->font_driver_list->on) 3568 if (! f->font_driver_list->on)
3556 { /* None of the drivers is enabled: enable them all. 3569 { /* None of the drivers is enabled: enable them all.