mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 23:40:19 +01:00
[cairo-scaled-fonts-subsets] Memleak and error reporting.
Fix leaks of strings and hash table from _cairo_scaled_font_subset_create_glyph_names(). Whilst we are in the vicinity, review the error handling.
This commit is contained in:
parent
51f37995c9
commit
e89cc8fa15
5 changed files with 68 additions and 54 deletions
|
|
@ -2133,7 +2133,7 @@ _cairo_ft_load_truetype_table (void *abstract_font,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_int_status_t
|
||||
_cairo_ft_map_glyphs_to_unicode (void *abstract_font,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
|
|
@ -2147,7 +2147,7 @@ _cairo_ft_map_glyphs_to_unicode (void *abstract_font,
|
|||
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (!face)
|
||||
return;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
count = font_subset->num_glyphs;
|
||||
charcode = FT_Get_First_Char( face, &glyph);
|
||||
|
|
@ -2160,9 +2160,11 @@ _cairo_ft_map_glyphs_to_unicode (void *abstract_font,
|
|||
break;
|
||||
}
|
||||
}
|
||||
charcode = FT_Get_Next_Char(face, charcode, &glyph);
|
||||
charcode = FT_Get_Next_Char (face, charcode, &glyph);
|
||||
}
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
|
||||
|
|
|
|||
|
|
@ -2983,17 +2983,25 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface,
|
|||
{
|
||||
const cairo_scaled_font_backend_t *backend;
|
||||
unsigned int i, num_bfchar;
|
||||
cairo_int_status_t status;
|
||||
|
||||
stream->id = 0;
|
||||
if (font_subset->to_unicode == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (_cairo_truetype_create_glyph_to_unicode_map (font_subset) != CAIRO_STATUS_SUCCESS) {
|
||||
status = _cairo_truetype_create_glyph_to_unicode_map (font_subset);
|
||||
if (status) {
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
backend = font_subset->scaled_font->backend;
|
||||
if (backend->map_glyphs_to_unicode == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
backend->map_glyphs_to_unicode (font_subset->scaled_font, font_subset);
|
||||
status = backend->map_glyphs_to_unicode (font_subset->scaled_font,
|
||||
font_subset);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
*stream = _cairo_pdf_surface_open_stream (surface,
|
||||
|
|
|
|||
|
|
@ -493,6 +493,7 @@ _cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets)
|
|||
|
||||
_cairo_hash_table_foreach (subsets->unscaled_sub_fonts, _cairo_sub_font_pluck, subsets->unscaled_sub_fonts);
|
||||
_cairo_hash_table_destroy (subsets->unscaled_sub_fonts);
|
||||
|
||||
free (subsets);
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +548,9 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (status == 0 && subsets->type != CAIRO_SUBSETS_SCALED) {
|
||||
if (status == CAIRO_STATUS_SUCCESS &&
|
||||
subsets->type != CAIRO_SUBSETS_SCALED)
|
||||
{
|
||||
/* Path available. Add to unscaled subset. */
|
||||
key.is_scaled = FALSE;
|
||||
_cairo_sub_font_init_key (&key, scaled_font);
|
||||
|
|
@ -722,20 +725,16 @@ _cairo_string_init_key (cairo_string_entry_t *key, char *s)
|
|||
key->string = s;
|
||||
}
|
||||
|
||||
static cairo_string_entry_t *
|
||||
create_string_entry (char *s)
|
||||
static cairo_status_t
|
||||
create_string_entry (char *s, cairo_string_entry_t **entry)
|
||||
{
|
||||
cairo_string_entry_t *entry;
|
||||
*entry = malloc (sizeof (cairo_string_entry_t));
|
||||
if (*entry == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
entry = malloc (sizeof (cairo_string_entry_t));
|
||||
if (entry == NULL) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
_cairo_string_init_key (*entry, s);
|
||||
|
||||
_cairo_string_init_key (entry, s);
|
||||
|
||||
return entry;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
|
|
@ -748,37 +747,42 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
cairo_string_entry_t key, *entry;
|
||||
char buf[30];
|
||||
|
||||
if (subset->to_unicode == NULL) {
|
||||
if (subset->to_unicode == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (_cairo_truetype_create_glyph_to_unicode_map (subset) != CAIRO_STATUS_SUCCESS) {
|
||||
status = _cairo_truetype_create_glyph_to_unicode_map (subset);
|
||||
if (status) {
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
backend = subset->scaled_font->backend;
|
||||
if (backend->map_glyphs_to_unicode == NULL) {
|
||||
if (backend->map_glyphs_to_unicode == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
backend->map_glyphs_to_unicode (subset->scaled_font, subset);
|
||||
}
|
||||
|
||||
subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *));
|
||||
status = backend->map_glyphs_to_unicode (subset->scaled_font, subset);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
names = _cairo_hash_table_create (_cairo_string_equal);
|
||||
if (names == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL1;
|
||||
if (names == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *));
|
||||
if (subset->glyph_names == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
subset->glyph_names[0] = strdup (".notdef");
|
||||
if (subset->glyph_names[0] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL1;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
entry = create_string_entry (subset->glyph_names[0]);
|
||||
if (entry == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL2;
|
||||
}
|
||||
status = create_string_entry (subset->glyph_names[0], &entry);
|
||||
if (status)
|
||||
goto CLEANUP_HASH;
|
||||
|
||||
status = _cairo_hash_table_insert (names, &entry->base);
|
||||
if (status) {
|
||||
|
|
@ -786,7 +790,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
for (i = 0; i < subset->num_glyphs; i++) {
|
||||
for (i = 1; i < subset->num_glyphs; i++) {
|
||||
if (subset->to_unicode[i] <= 0xffff) {
|
||||
snprintf (buf, sizeof(buf), "uni%04X", (unsigned int)(subset->to_unicode[i]));
|
||||
_cairo_string_init_key (&key, buf);
|
||||
|
|
@ -800,15 +804,13 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
|
||||
subset->glyph_names[i] = strdup (buf);
|
||||
if (subset->glyph_names[i] == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
entry = create_string_entry (subset->glyph_names[i]);
|
||||
if (entry == NULL) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
status = create_string_entry (subset->glyph_names[i], &entry);
|
||||
if (status)
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (names, &entry->base);
|
||||
if (status) {
|
||||
|
|
@ -816,30 +818,30 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
goto CLEANUP_HASH;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
CLEANUP_HASH:
|
||||
while (1) {
|
||||
entry = _cairo_hash_table_random_entry (names, NULL);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
|
||||
_cairo_hash_table_remove (names, (cairo_hash_entry_t *) entry);
|
||||
free (entry);
|
||||
}
|
||||
_cairo_hash_table_destroy (names);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FAIL2:
|
||||
for (i = 0; i < subset->num_glyphs; i++) {
|
||||
if (subset->glyph_names[i] != NULL)
|
||||
free (subset->glyph_names[i]);
|
||||
if (subset->glyph_names != NULL) {
|
||||
for (i = 0; i < subset->num_glyphs; i++) {
|
||||
if (subset->glyph_names[i] != NULL)
|
||||
free (subset->glyph_names[i]);
|
||||
}
|
||||
|
||||
free (subset->glyph_names);
|
||||
subset->glyph_names = NULL;
|
||||
}
|
||||
|
||||
FAIL1:
|
||||
free (subset->glyph_names);
|
||||
subset->glyph_names = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1328,7 +1328,7 @@ _cairo_win32_scaled_font_load_truetype_table (void *abstract_font,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_int_status_t
|
||||
_cairo_win32_scaled_font_map_glyphs_to_unicode (void *abstract_font,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
{
|
||||
|
|
@ -1336,10 +1336,12 @@ _cairo_win32_scaled_font_map_glyphs_to_unicode (void *abstract_font,
|
|||
unsigned int i;
|
||||
|
||||
if (scaled_font->glyph_indexing)
|
||||
return;
|
||||
return CAIRO_STATUS_SUCCESS; /* XXX ? */
|
||||
|
||||
for (i = 0; i < font_subset->num_glyphs; i++)
|
||||
font_subset->to_unicode[i] = font_subset->glyphs[i];
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ struct _cairo_scaled_font_backend {
|
|||
unsigned char *buffer,
|
||||
unsigned long *length);
|
||||
|
||||
void
|
||||
cairo_warn cairo_int_status_t
|
||||
(*map_glyphs_to_unicode)(void *scaled_font,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue