diff options
author | Oleg Oshmyan <chortos@inbox.lv> | 2015-10-30 01:33:30 +0200 |
---|---|---|
committer | Oleg Oshmyan <chortos@inbox.lv> | 2015-10-30 03:50:53 +0200 |
commit | ad5988af46f5ca698115140f9252882286539f72 (patch) | |
tree | 04e5367c4faed223416ae0a2ea82b3bc9ca9142e /libass | |
parent | 7ff5f49e30b91f8ac3e707896ee1fed83dcca170 (diff) | |
download | libass-ad5988af46f5ca698115140f9252882286539f72.tar.bz2 libass-ad5988af46f5ca698115140f9252882286539f72.tar.xz |
directwrite: improve error handling
* Check malloc and calloc return values.
* Abort if a name can't be fetched, rather than supply a NULL
string to fontselect causing it to crash.
* Make sure to free all allocated memory.
* Always check FAILED(hr) before using the value of any output
argument returned by DirectWrite, because it is not clear whether
they are guaranteed to have correct values in case of error.
Diffstat (limited to 'libass')
-rw-r--r-- | libass/ass_directwrite.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c index e07b607..cb21dd4 100644 --- a/libass/ass_directwrite.c +++ b/libass/ass_directwrite.c @@ -520,22 +520,23 @@ static void add_font(IDWriteFont *font, IDWriteFontFamily *fontFamily, IDWriteLocalizedStrings *psNames; hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &psNames, &exists); - if (FAILED(hr)) { - IDWriteFont_Release(font); - return; - } + if (FAILED(hr)) + goto cleanup; if (exists) { hr = IDWriteLocalizedStrings_GetString(psNames, 0, temp_name, NAME_MAX_LENGTH); if (FAILED(hr)) { IDWriteLocalizedStrings_Release(psNames); - IDWriteFont_Release(font); - return; + goto cleanup; } temp_name[NAME_MAX_LENGTH-1] = 0; size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0, NULL, NULL); char *mbName = (char *) malloc(size_needed); + if (!mbName) { + IDWriteLocalizedStrings_Release(psNames); + goto cleanup; + } WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL); meta.postscript_name = mbName; @@ -545,25 +546,32 @@ static void add_font(IDWriteFont *font, IDWriteFontFamily *fontFamily, IDWriteLocalizedStrings *fontNames; hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_FULL_NAME, &fontNames, &exists); - if (FAILED(hr)) { - IDWriteFont_Release(font); - return; - } + if (FAILED(hr)) + goto cleanup; if (exists) { meta.n_fullname = IDWriteLocalizedStrings_GetCount(fontNames); meta.fullnames = (char **) calloc(meta.n_fullname, sizeof(char *)); + if (!meta.fullnames) { + IDWriteLocalizedStrings_Release(fontNames); + goto cleanup; + } for (int k = 0; k < meta.n_fullname; k++) { hr = IDWriteLocalizedStrings_GetString(fontNames, k, temp_name, NAME_MAX_LENGTH); if (FAILED(hr)) { - continue; + IDWriteLocalizedStrings_Release(fontNames); + goto cleanup; } temp_name[NAME_MAX_LENGTH-1] = 0; size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0, NULL, NULL); char *mbName = (char *) malloc(size_needed); + if (!mbName) { + IDWriteLocalizedStrings_Release(fontNames); + goto cleanup; + } WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL); meta.fullnames[k] = mbName; } @@ -573,26 +581,33 @@ static void add_font(IDWriteFont *font, IDWriteFontFamily *fontFamily, IDWriteLocalizedStrings *familyNames; hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &familyNames, &exists); - if (!exists) + if (FAILED(hr) || !exists) hr = IDWriteFontFamily_GetFamilyNames(fontFamily, &familyNames); - if (FAILED(hr)) { - IDWriteFont_Release(font); - return; - } + if (FAILED(hr)) + goto cleanup; meta.n_family = IDWriteLocalizedStrings_GetCount(familyNames); meta.families = (char **) calloc(meta.n_family, sizeof(char *)); + if (!meta.families) { + IDWriteLocalizedStrings_Release(familyNames); + goto cleanup; + } for (int k = 0; k < meta.n_family; k++) { hr = IDWriteLocalizedStrings_GetString(familyNames, k, temp_name, NAME_MAX_LENGTH); if (FAILED(hr)) { - continue; + IDWriteLocalizedStrings_Release(familyNames); + goto cleanup; } temp_name[NAME_MAX_LENGTH-1] = 0; size_needed = WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, NULL, 0, NULL, NULL); char *mbName = (char *) malloc(size_needed); + if (!mbName) { + IDWriteLocalizedStrings_Release(familyNames); + goto cleanup; + } WideCharToMultiByte(CP_UTF8, 0, temp_name, -1, mbName, size_needed, NULL, NULL); meta.families[k] = mbName; } @@ -601,17 +616,30 @@ static void add_font(IDWriteFont *font, IDWriteFontFamily *fontFamily, meta.is_postscript = is_postscript(font); FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv)); + if (!font_priv) + goto cleanup; font_priv->font = font; + font = NULL; ass_font_provider_add_font(provider, &meta, NULL, 0, font_priv); - for (int k = 0; k < meta.n_family; k++) - free(meta.families[k]); - for (int k = 0; k < meta.n_fullname; k++) - free(meta.fullnames[k]); - free(meta.fullnames); - free(meta.families); +cleanup: + if (meta.families) { + for (int k = 0; k < meta.n_family; k++) + free(meta.families[k]); + free(meta.families); + } + + if (meta.fullnames) { + for (int k = 0; k < meta.n_fullname; k++) + free(meta.fullnames[k]); + free(meta.fullnames); + } + free(meta.postscript_name); + + if (font) + IDWriteFont_Release(font); } /* |