From aa01b5537785ce57a6359f50cb24f4552058a290 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Fri, 12 Jun 2015 21:14:53 +0200 Subject: fontselect: fix undefined behavior with calloc If allocations have the size zero, malloc/calloc implementations can return a zero-size buffer or NULL. The earlier introduced malloc checking blows up if an implementation returns NULL. Fix that by only allocating and checking when it's actually needed. Also fix a minor problem with iconv deinitialization in an error path. --- libass/ass_fontselect.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c index fc36dde..26fe579 100644 --- a/libass/ass_fontselect.c +++ b/libass/ass_fontselect.c @@ -277,10 +277,14 @@ ass_font_provider_add_font(ASS_FontProvider *provider, info->width = width; info->n_fullname = meta->n_fullname; info->n_family = meta->n_family; - info->fullnames = calloc(meta->n_fullname, sizeof(char *)); info->families = calloc(meta->n_family, sizeof(char *)); + if (meta->n_fullname) { + info->fullnames = calloc(meta->n_fullname, sizeof(char *)); + if (info->fullnames == NULL) + goto error; + } - if (info->fullnames == NULL || info->families == NULL) + if (info->families == NULL) goto error; for (i = 0; i < info->n_family; i++) { @@ -664,6 +668,7 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) } iconv_close(utf16to8); + utf16to8 = (iconv_t)-1; // check if we got a valid family - if not use whatever FreeType gives us if (num_family == 0 && face->family_name) { @@ -673,6 +678,10 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) num_family++; } + // we absolutely need a name + if (num_family == 0) + goto error; + // calculate sensible slant and weight from style attributes slant = 110 * !!(face->style_flags & FT_STYLE_FLAG_ITALIC); weight = 300 * !!(face->style_flags & FT_STYLE_FLAG_BOLD) + 400; @@ -682,13 +691,20 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) info->weight = weight; info->width = 100; // FIXME, should probably query the OS/2 table info->families = calloc(sizeof(char *), num_family); - info->fullnames = calloc(sizeof(char *), num_fullname); - if (info->families == NULL || info->fullnames == NULL) + + if (info->families == NULL) goto error; + memcpy(info->families, &families, sizeof(char *) * num_family); - memcpy(info->fullnames, &fullnames, sizeof(char *) * num_fullname); - info->n_family = num_family; - info->n_fullname = num_fullname; + info->n_family = num_family; + + if (num_fullname) { + info->fullnames = calloc(sizeof(char *), num_fullname); + if (info->fullnames == NULL) + goto error; + memcpy(info->fullnames, &fullnames, sizeof(char *) * num_fullname); + info->n_fullname = num_fullname; + } return 0; -- cgit v1.2.3