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/font.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/font.c')
| -rw-r--r-- | src/font.c | 39 |
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) | |||
| 2185 | static Lisp_Object | 2191 | static Lisp_Object |
| 2186 | font_vconcat_entity_vectors (Lisp_Object list) | 2192 | font_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. |