aboutsummaryrefslogtreecommitdiffstats
path: root/src/search.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/search.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/search.c')
-rw-r--r--src/search.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/src/search.c b/src/search.c
index ecfb2352144..9eed390244f 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1318,6 +1318,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1318 translation. Otherwise set to zero later. */ 1318 translation. Otherwise set to zero later. */
1319 int char_base = -1; 1319 int char_base = -1;
1320 bool boyer_moore_ok = 1; 1320 bool boyer_moore_ok = 1;
1321 USE_SAFE_ALLOCA;
1321 1322
1322 /* MULTIBYTE says whether the text to be searched is multibyte. 1323 /* MULTIBYTE says whether the text to be searched is multibyte.
1323 We must convert PATTERN to match that, or we will not really 1324 We must convert PATTERN to match that, or we will not really
@@ -1335,7 +1336,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1335 raw_pattern_size_byte 1336 raw_pattern_size_byte
1336 = count_size_as_multibyte (SDATA (string), 1337 = count_size_as_multibyte (SDATA (string),
1337 raw_pattern_size); 1338 raw_pattern_size);
1338 raw_pattern = alloca (raw_pattern_size_byte + 1); 1339 raw_pattern = SAFE_ALLOCA (raw_pattern_size_byte + 1);
1339 copy_text (SDATA (string), raw_pattern, 1340 copy_text (SDATA (string), raw_pattern,
1340 SCHARS (string), 0, 1); 1341 SCHARS (string), 0, 1);
1341 } 1342 }
@@ -1349,7 +1350,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1349 the chosen single-byte character set can possibly match. */ 1350 the chosen single-byte character set can possibly match. */
1350 raw_pattern_size = SCHARS (string); 1351 raw_pattern_size = SCHARS (string);
1351 raw_pattern_size_byte = SCHARS (string); 1352 raw_pattern_size_byte = SCHARS (string);
1352 raw_pattern = alloca (raw_pattern_size + 1); 1353 raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1);
1353 copy_text (SDATA (string), raw_pattern, 1354 copy_text (SDATA (string), raw_pattern,
1354 SBYTES (string), 1, 0); 1355 SBYTES (string), 1, 0);
1355 } 1356 }
@@ -1357,7 +1358,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1357 /* Copy and optionally translate the pattern. */ 1358 /* Copy and optionally translate the pattern. */
1358 len = raw_pattern_size; 1359 len = raw_pattern_size;
1359 len_byte = raw_pattern_size_byte; 1360 len_byte = raw_pattern_size_byte;
1360 patbuf = alloca (len * MAX_MULTIBYTE_LENGTH); 1361 SAFE_NALLOCA (patbuf, MAX_MULTIBYTE_LENGTH, len);
1361 pat = patbuf; 1362 pat = patbuf;
1362 base_pat = raw_pattern; 1363 base_pat = raw_pattern;
1363 if (multibyte) 1364 if (multibyte)
@@ -1497,13 +1498,15 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1497 len_byte = pat - patbuf; 1498 len_byte = pat - patbuf;
1498 pat = base_pat = patbuf; 1499 pat = base_pat = patbuf;
1499 1500
1500 if (boyer_moore_ok) 1501 EMACS_INT result
1501 return boyer_moore (n, pat, len_byte, trt, inverse_trt, 1502 = (boyer_moore_ok
1502 pos_byte, lim_byte, 1503 ? boyer_moore (n, pat, len_byte, trt, inverse_trt,
1503 char_base); 1504 pos_byte, lim_byte,
1504 else 1505 char_base)
1505 return simple_search (n, pat, raw_pattern_size, len_byte, trt, 1506 : simple_search (n, pat, raw_pattern_size, len_byte, trt,
1506 pos, pos_byte, lim, lim_byte); 1507 pos, pos_byte, lim, lim_byte));
1508 SAFE_FREE ();
1509 return result;
1507 } 1510 }
1508} 1511}
1509 1512
@@ -2809,7 +2812,8 @@ Return value is undefined if the last search failed. */)
2809 2812
2810 prev = Qnil; 2813 prev = Qnil;
2811 2814
2812 data = alloca ((2 * search_regs.num_regs + 1) * sizeof *data); 2815 USE_SAFE_ALLOCA;
2816 SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);
2813 2817
2814 len = 0; 2818 len = 0;
2815 for (i = 0; i < search_regs.num_regs; i++) 2819 for (i = 0; i < search_regs.num_regs; i++)
@@ -2852,25 +2856,28 @@ Return value is undefined if the last search failed. */)
2852 2856
2853 /* If REUSE is not usable, cons up the values and return them. */ 2857 /* If REUSE is not usable, cons up the values and return them. */
2854 if (! CONSP (reuse)) 2858 if (! CONSP (reuse))
2855 return Flist (len, data); 2859 reuse = Flist (len, data);
2856 2860 else
2857 /* If REUSE is a list, store as many value elements as will fit
2858 into the elements of REUSE. */
2859 for (i = 0, tail = reuse; CONSP (tail);
2860 i++, tail = XCDR (tail))
2861 { 2861 {
2862 /* If REUSE is a list, store as many value elements as will fit
2863 into the elements of REUSE. */
2864 for (i = 0, tail = reuse; CONSP (tail);
2865 i++, tail = XCDR (tail))
2866 {
2867 if (i < len)
2868 XSETCAR (tail, data[i]);
2869 else
2870 XSETCAR (tail, Qnil);
2871 prev = tail;
2872 }
2873
2874 /* If we couldn't fit all value elements into REUSE,
2875 cons up the rest of them and add them to the end of REUSE. */
2862 if (i < len) 2876 if (i < len)
2863 XSETCAR (tail, data[i]); 2877 XSETCDR (prev, Flist (len - i, data + i));
2864 else
2865 XSETCAR (tail, Qnil);
2866 prev = tail;
2867 } 2878 }
2868 2879
2869 /* If we couldn't fit all value elements into REUSE, 2880 SAFE_FREE ();
2870 cons up the rest of them and add them to the end of REUSE. */
2871 if (i < len)
2872 XSETCDR (prev, Flist (len - i, data + i));
2873
2874 return reuse; 2881 return reuse;
2875} 2882}
2876 2883
@@ -3075,7 +3082,8 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3075 3082
3076 CHECK_STRING (string); 3083 CHECK_STRING (string);
3077 3084
3078 temp = alloca (SBYTES (string) * 2); 3085 USE_SAFE_ALLOCA;
3086 SAFE_NALLOCA (temp, 2, SBYTES (string));
3079 3087
3080 /* Now copy the data into the new string, inserting escapes. */ 3088 /* Now copy the data into the new string, inserting escapes. */
3081 3089
@@ -3093,10 +3101,13 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3093 *out++ = *in; 3101 *out++ = *in;
3094 } 3102 }
3095 3103
3096 return make_specified_string (temp, 3104 Lisp_Object result
3097 SCHARS (string) + backslashes_added, 3105 = make_specified_string (temp,
3098 out - temp, 3106 SCHARS (string) + backslashes_added,
3099 STRING_MULTIBYTE (string)); 3107 out - temp,
3108 STRING_MULTIBYTE (string));
3109 SAFE_FREE ();
3110 return result;
3100} 3111}
3101 3112
3102/* Like find_newline, but doesn't use the cache, and only searches forward. */ 3113/* Like find_newline, but doesn't use the cache, and only searches forward. */