From c0699c8693c47f14a2e57dec7292e862ac7adf9c Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Wed, 27 Apr 2022 12:35:39 +0200 Subject: [PATCH] Fix undefined behavior when passing null to strdup --- ChangeLog | 1 + src/opf.c | 30 ++++++++++++++++++------------ src/util.c | 2 +- tools/common.c | 2 +- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index b431347..8f48750 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +2022-04-27: Fix undefined behavior when passing null to strdup 2022-04-27: Fix wrong boundary checks in inflections parser resulting in stack buffer over-read with corrupt input 2022-04-26: Fix text formatting 2022-04-26: Fix array boundary check when parsing inflections which could result in buffer over-read with corrupt input diff --git a/src/opf.c b/src/opf.c index eb36750..02e984b 100644 --- a/src/opf.c +++ b/src/opf.c @@ -1152,24 +1152,30 @@ MOBI_RET mobi_build_opf_metadata(OPF *opf, const MOBIData *m, const MOBIRawml * if (mobi_is_dictionary(m)) { if (opf->metadata->x_meta->dictionary_in_lang == NULL) { if (m->mh && m->mh->dict_input_lang) { - opf->metadata->x_meta->dictionary_in_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*)); - if (opf->metadata->x_meta->dictionary_in_lang == NULL) { - debug_print("%s\n", "Memory allocation failed"); - return MOBI_MALLOC_FAILED; - } uint32_t dict_lang_in = *m->mh->dict_input_lang; - opf->metadata->x_meta->dictionary_in_lang[0] = strdup(mobi_get_locale_string(dict_lang_in)); + const char *lang = mobi_get_locale_string(dict_lang_in); + if (lang) { + opf->metadata->x_meta->dictionary_in_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*)); + if (opf->metadata->x_meta->dictionary_in_lang == NULL) { + debug_print("%s\n", "Memory allocation failed"); + return MOBI_MALLOC_FAILED; + } + opf->metadata->x_meta->dictionary_in_lang[0] = strdup(lang); + } } } if (opf->metadata->x_meta->dictionary_out_lang == NULL) { if (m->mh && m->mh->dict_output_lang) { - opf->metadata->x_meta->dictionary_out_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*)); - if (opf->metadata->x_meta->dictionary_out_lang == NULL) { - debug_print("%s\n", "Memory allocation failed"); - return MOBI_MALLOC_FAILED; + uint32_t dict_lang_out = *m->mh->dict_output_lang; + const char *lang = mobi_get_locale_string(dict_lang_out); + if (lang) { + opf->metadata->x_meta->dictionary_out_lang = calloc(OPF_META_MAX_TAGS, sizeof(char*)); + if (opf->metadata->x_meta->dictionary_out_lang == NULL) { + debug_print("%s\n", "Memory allocation failed"); + return MOBI_MALLOC_FAILED; + } + opf->metadata->x_meta->dictionary_out_lang[0] = strdup(lang); } - uint32_t dict_lang_in = *m->mh->dict_output_lang; - opf->metadata->x_meta->dictionary_out_lang[0] = strdup(mobi_get_locale_string(dict_lang_in)); } } if (rawml->orth->orth_index_name) { diff --git a/src/util.c b/src/util.c index d0d57dd..a9260d4 100644 --- a/src/util.c +++ b/src/util.c @@ -641,7 +641,7 @@ static const char *mobi_locale[MOBI_LANG_MAX][MOBI_REGION_MAX] = { See mobi_locale array. @param[in] locale_number Mobipocket locale number (as stored in MOBI header) - @return Pointer to locale string in mobi_locale array + @return Pointer to locale string in mobi_locale array or NULL on error */ const char * mobi_get_locale_string(const uint32_t locale_number) { uint8_t lang_code = locale_number & 0xffU; diff --git a/tools/common.c b/tools/common.c index 6c7cbfe..d26f37c 100644 --- a/tools/common.c +++ b/tools/common.c @@ -330,7 +330,7 @@ void print_summary(const MOBIData *m) { *m->mh->dict_input_lang && *m->mh->dict_output_lang) { const char *locale_in = mobi_get_locale_string(*m->mh->dict_input_lang); const char *locale_out = mobi_get_locale_string(*m->mh->dict_output_lang); - printf(": %s => %s", locale_in, locale_out); + printf(": %s => %s", locale_in ? locale_in : "unknown", locale_out ? locale_out : "unknown"); } printf("\n"); }