aboutsummaryrefslogtreecommitdiffstats
path: root/src/ftfont.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/ftfont.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/ftfont.c')
-rw-r--r--src/ftfont.c111
1 files changed, 75 insertions, 36 deletions
diff --git a/src/ftfont.c b/src/ftfont.c
index 1cad158065b..0ab3119365e 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24#include <fontconfig/fontconfig.h> 24#include <fontconfig/fontconfig.h>
25#include <fontconfig/fcfreetype.h> 25#include <fontconfig/fcfreetype.h>
26 26
27#include <c-strcase.h>
28
27#include "lisp.h" 29#include "lisp.h"
28#include "dispextern.h" 30#include "dispextern.h"
29#include "frame.h" 31#include "frame.h"
@@ -140,6 +142,12 @@ static struct
140 { NULL } 142 { NULL }
141 }; 143 };
142 144
145static bool
146matching_prefix (char const *str, ptrdiff_t len, char const *pat)
147{
148 return len == strlen (pat) && c_strncasecmp (str, pat, len) == 0;
149}
150
143/* Dirty hack for handing ADSTYLE property. 151/* Dirty hack for handing ADSTYLE property.
144 152
145 Fontconfig (actually the underlying FreeType) gives such ADSTYLE 153 Fontconfig (actually the underlying FreeType) gives such ADSTYLE
@@ -171,18 +179,10 @@ get_adstyle_property (FcPattern *p)
171 return Qnil; 179 return Qnil;
172 str = (char *) fcstr; 180 str = (char *) fcstr;
173 for (end = str; *end && *end != ' '; end++); 181 for (end = str; *end && *end != ' '; end++);
174 if (*end) 182 if (matching_prefix (str, end - str, "Regular")
175 { 183 || matching_prefix (str, end - str, "Bold")
176 char *newstr = alloca (end - str + 1); 184 || matching_prefix (str, end - str, "Oblique")
177 memcpy (newstr, str, end - str); 185 || matching_prefix (str, end - str, "Italic"))
178 newstr[end - str] = '\0';
179 end = newstr + (end - str);
180 str = newstr;
181 }
182 if (xstrcasecmp (str, "Regular") == 0
183 || xstrcasecmp (str, "Bold") == 0
184 || xstrcasecmp (str, "Oblique") == 0
185 || xstrcasecmp (str, "Italic") == 0)
186 return Qnil; 186 return Qnil;
187 adstyle = font_intern_prop (str, end - str, 1); 187 adstyle = font_intern_prop (str, end - str, 1);
188 if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0) 188 if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
@@ -573,7 +573,8 @@ static int
573ftfont_get_charset (Lisp_Object registry) 573ftfont_get_charset (Lisp_Object registry)
574{ 574{
575 char *str = SSDATA (SYMBOL_NAME (registry)); 575 char *str = SSDATA (SYMBOL_NAME (registry));
576 char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1); 576 USE_SAFE_ALLOCA;
577 char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
577 Lisp_Object regexp; 578 Lisp_Object regexp;
578 int i, j; 579 int i, j;
579 580
@@ -589,6 +590,7 @@ ftfont_get_charset (Lisp_Object registry)
589 } 590 }
590 re[j] = '\0'; 591 re[j] = '\0';
591 regexp = make_unibyte_string (re, j); 592 regexp = make_unibyte_string (re, j);
593 SAFE_FREE ();
592 for (i = 0; fc_charset_table[i].name; i++) 594 for (i = 0; fc_charset_table[i].name; i++)
593 if (fast_c_string_match_ignore_case 595 if (fast_c_string_match_ignore_case
594 (regexp, fc_charset_table[i].name, 596 (regexp, fc_charset_table[i].name,
@@ -1688,7 +1690,8 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1688 else if (! otf) 1690 else if (! otf)
1689 return 0; 1691 return 0;
1690 for (n = 1; spec->features[i][n]; n++); 1692 for (n = 1; spec->features[i][n]; n++);
1691 tags = alloca (sizeof (OTF_Tag) * n); 1693 USE_SAFE_ALLOCA;
1694 SAFE_NALLOCA (tags, 1, n);
1692 for (n = 0, negative = 0; spec->features[i][n]; n++) 1695 for (n = 0, negative = 0; spec->features[i][n]; n++)
1693 { 1696 {
1694 if (spec->features[i][n] == 0xFFFFFFFF) 1697 if (spec->features[i][n] == 0xFFFFFFFF)
@@ -1698,16 +1701,17 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1698 else 1701 else
1699 tags[n] = spec->features[i][n]; 1702 tags[n] = spec->features[i][n];
1700 } 1703 }
1701#ifdef M17N_FLT_USE_NEW_FEATURE 1704 bool passed = true;
1702 if (OTF_check_features (otf, i == 0, spec->script, spec->langsys, 1705#ifndef M17N_FLT_USE_NEW_FEATURE
1703 tags, n - negative) != 1) 1706 passed = n - negative > 0;
1704 return 0; 1707#endif
1705#else /* not M17N_FLT_USE_NEW_FEATURE */ 1708 if (passed)
1706 if (n - negative > 0 1709 passed = (OTF_check_features (otf, i == 0, spec->script,
1707 && OTF_check_features (otf, i == 0, spec->script, spec->langsys, 1710 spec->langsys, tags, n - negative)
1708 tags, n - negative) != 1) 1711 != 1);
1712 SAFE_FREE ();
1713 if (passed)
1709 return 0; 1714 return 0;
1710#endif /* not M17N_FLT_USE_NEW_FEATURE */
1711 } 1715 }
1712 return 1; 1716 return 1;
1713#undef FEATURE_NONE 1717#undef FEATURE_NONE
@@ -1799,11 +1803,15 @@ ftfont_drive_otf (MFLTFont *font,
1799 if (len == 0) 1803 if (len == 0)
1800 return from; 1804 return from;
1801 OTF_tag_name (spec->script, script); 1805 OTF_tag_name (spec->script, script);
1806
1807 char langsysbuf[5];
1802 if (spec->langsys) 1808 if (spec->langsys)
1803 { 1809 {
1804 langsys = alloca (5); 1810 langsys = langsysbuf;
1805 OTF_tag_name (spec->langsys, langsys); 1811 OTF_tag_name (spec->langsys, langsys);
1806 } 1812 }
1813
1814 USE_SAFE_ALLOCA;
1807 for (i = 0; i < 2; i++) 1815 for (i = 0; i < 2; i++)
1808 { 1816 {
1809 char *p; 1817 char *p;
@@ -1811,10 +1819,11 @@ ftfont_drive_otf (MFLTFont *font,
1811 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) 1819 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
1812 { 1820 {
1813 for (j = 0; spec->features[i][j]; j++); 1821 for (j = 0; spec->features[i][j]; j++);
1822 SAFE_NALLOCA (p, 6, j);
1814 if (i == 0) 1823 if (i == 0)
1815 p = gsub_features = alloca (6 * j); 1824 gsub_features = p;
1816 else 1825 else
1817 p = gpos_features = alloca (6 * j); 1826 gpos_features = p;
1818 for (j = 0; spec->features[i][j]; j++) 1827 for (j = 0; spec->features[i][j]; j++)
1819 { 1828 {
1820 if (spec->features[i][j] == 0xFFFFFFFF) 1829 if (spec->features[i][j] == 0xFFFFFFFF)
@@ -1846,7 +1855,10 @@ ftfont_drive_otf (MFLTFont *font,
1846 gsub_features) < 0) 1855 gsub_features) < 0)
1847 goto simple_copy; 1856 goto simple_copy;
1848 if (out->allocated < out->used + otf_gstring.used) 1857 if (out->allocated < out->used + otf_gstring.used)
1849 return -2; 1858 {
1859 SAFE_FREE ();
1860 return -2;
1861 }
1850 features = otf->gsub->FeatureList.Feature; 1862 features = otf->gsub->FeatureList.Feature;
1851 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) 1863 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
1852 { 1864 {
@@ -1935,7 +1947,10 @@ ftfont_drive_otf (MFLTFont *font,
1935 else if (out) 1947 else if (out)
1936 { 1948 {
1937 if (out->allocated < out->used + len) 1949 if (out->allocated < out->used + len)
1938 return -2; 1950 {
1951 SAFE_FREE ();
1952 return -2;
1953 }
1939 for (i = 0; i < len; i++) 1954 for (i = 0; i < len; i++)
1940 out->glyphs[out->used++] = in->glyphs[from + i]; 1955 out->glyphs[out->used++] = in->glyphs[from + i];
1941 } 1956 }
@@ -1947,7 +1962,10 @@ ftfont_drive_otf (MFLTFont *font,
1947 1962
1948 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, 1963 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
1949 gpos_features) < 0) 1964 gpos_features) < 0)
1950 return to; 1965 {
1966 SAFE_FREE ();
1967 return to;
1968 }
1951 features = otf->gpos->FeatureList.Feature; 1969 features = otf->gpos->FeatureList.Feature;
1952 x_ppem = ft_face->size->metrics.x_ppem; 1970 x_ppem = ft_face->size->metrics.x_ppem;
1953 y_ppem = ft_face->size->metrics.y_ppem; 1971 y_ppem = ft_face->size->metrics.y_ppem;
@@ -2069,7 +2087,10 @@ ftfont_drive_otf (MFLTFont *font,
2069 { 2087 {
2070 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, 2088 if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
2071 gpos_features) < 0) 2089 gpos_features) < 0)
2072 return to; 2090 {
2091 SAFE_FREE ();
2092 return to;
2093 }
2073 features = otf->gpos->FeatureList.Feature; 2094 features = otf->gpos->FeatureList.Feature;
2074 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; 2095 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used;
2075 i++, otfg++) 2096 i++, otfg++)
@@ -2089,9 +2110,11 @@ ftfont_drive_otf (MFLTFont *font,
2089 } 2110 }
2090 } 2111 }
2091 } 2112 }
2113 SAFE_FREE ();
2092 return to; 2114 return to;
2093 2115
2094 simple_copy: 2116 simple_copy:
2117 SAFE_FREE ();
2095 if (! out) 2118 if (! out)
2096 return to; 2119 return to;
2097 if (out->allocated < out->used + len) 2120 if (out->allocated < out->used + len)
@@ -2129,11 +2152,15 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2129 if (len == 0) 2152 if (len == 0)
2130 return from; 2153 return from;
2131 OTF_tag_name (spec->script, script); 2154 OTF_tag_name (spec->script, script);
2155
2156 char langsysbuf[5];
2132 if (spec->langsys) 2157 if (spec->langsys)
2133 { 2158 {
2134 langsys = alloca (5); 2159 langsys = langsysbuf;
2135 OTF_tag_name (spec->langsys, langsys); 2160 OTF_tag_name (spec->langsys, langsys);
2136 } 2161 }
2162
2163 USE_SAFE_ALLOCA;
2137 for (i = 0; i < 2; i++) 2164 for (i = 0; i < 2; i++)
2138 { 2165 {
2139 char *p; 2166 char *p;
@@ -2141,10 +2168,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2141 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) 2168 if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
2142 { 2169 {
2143 for (j = 0; spec->features[i][j]; j++); 2170 for (j = 0; spec->features[i][j]; j++);
2171 SAFE_NALLOCA (p, 6, j);
2144 if (i == 0) 2172 if (i == 0)
2145 p = gsub_features = alloca (6 * j); 2173 gsub_features = p;
2146 else 2174 else
2147 p = gpos_features = alloca (6 * j); 2175 gpos_features = p;
2148 for (j = 0; spec->features[i][j]; j++) 2176 for (j = 0; spec->features[i][j]; j++)
2149 { 2177 {
2150 if (spec->features[i][j] == 0xFFFFFFFF) 2178 if (spec->features[i][j] == 0xFFFFFFFF)
@@ -2176,7 +2204,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2176 < 0) 2204 < 0)
2177 goto simple_copy; 2205 goto simple_copy;
2178 if (out->allocated < out->used + otf_gstring.used) 2206 if (out->allocated < out->used + otf_gstring.used)
2179 return -2; 2207 {
2208 SAFE_FREE ();
2209 return -2;
2210 }
2180 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) 2211 for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
2181 { 2212 {
2182 MFLTGlyph *g; 2213 MFLTGlyph *g;
@@ -2227,7 +2258,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2227 else 2258 else
2228 { 2259 {
2229 if (out->allocated < out->used + len) 2260 if (out->allocated < out->used + len)
2230 return -2; 2261 {
2262 SAFE_FREE ();
2263 return -2;
2264 }
2231 for (i = 0; i < len; i++) 2265 for (i = 0; i < len; i++)
2232 out->glyphs[out->used++] = in->glyphs[from + i]; 2266 out->glyphs[out->used++] = in->glyphs[from + i];
2233 } 2267 }
@@ -2239,7 +2273,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2239 2273
2240 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features) 2274 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features)
2241 < 0) 2275 < 0)
2242 return to; 2276 {
2277 SAFE_FREE ();
2278 return to;
2279 }
2243 2280
2244 x_ppem = ft_face->size->metrics.x_ppem; 2281 x_ppem = ft_face->size->metrics.x_ppem;
2245 y_ppem = ft_face->size->metrics.y_ppem; 2282 y_ppem = ft_face->size->metrics.y_ppem;
@@ -2349,9 +2386,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
2349 base = g; 2386 base = g;
2350 } 2387 }
2351 } 2388 }
2389 SAFE_FREE ();
2352 return to; 2390 return to;
2353 2391
2354 simple_copy: 2392 simple_copy:
2393 SAFE_FREE ();
2355 if (out->allocated < out->used + len) 2394 if (out->allocated < out->used + len)
2356 return -2; 2395 return -2;
2357 font->get_metrics (font, in, from, to); 2396 font->get_metrics (font, in, from, to);