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/ftfont.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/ftfont.c')
| -rw-r--r-- | src/ftfont.c | 111 |
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 | ||
| 145 | static bool | ||
| 146 | matching_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 | |||
| 573 | ftfont_get_charset (Lisp_Object registry) | 573 | ftfont_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); |