From: simon Date: Thu, 18 May 2006 08:38:41 +0000 (+0000) Subject: Missing error handling: the HTML and WinHelp back ends would both X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/commitdiff_plain/3ae196b46ee9e2850ea7fc91262b746240df84e9 Missing error handling: the HTML and WinHelp back ends would both segfault if they were unable to open their output files. git-svn-id: svn://svn.tartarus.org/sgt/halibut@6704 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/bk_html.c b/bk_html.c index 41a9f76..4311d26 100644 --- a/bk_html.c +++ b/bk_html.c @@ -763,6 +763,9 @@ void html_backend(paragraph *sourceform, keywordlist *keywords, #define itemname(lt) ( (lt)==LI ? "li" : (lt)==DT ? "dt" : "dd" ) ho.fp = fopen(f->filename, "w"); + if (!ho.fp) + error(err_cantopenw, f->filename); + ho.charset = conf.output_charset; ho.restrict_charset = conf.restrict_charset; ho.cstate = charset_init_state; @@ -773,31 +776,38 @@ void html_backend(paragraph *sourceform, keywordlist *keywords, /* . */ switch (conf.htmlver) { case HTML_3_2: - fprintf(ho.fp, "\n"); + if (ho.fp) + fprintf(ho.fp, "\n"); break; case HTML_4: - fprintf(ho.fp, "\n"); + if (ho.fp) + fprintf(ho.fp, "\n"); break; case ISO_HTML: - fprintf(ho.fp, "\n"); + if (ho.fp) + fprintf(ho.fp, "\n"); break; case XHTML_1_0_TRANSITIONAL: - fprintf(ho.fp, "\n", - charset_to_mimeenc(conf.output_charset)); - fprintf(ho.fp, "\n"); + if (ho.fp) { + fprintf(ho.fp, "\n", + charset_to_mimeenc(conf.output_charset)); + fprintf(ho.fp, "\n"); + } break; case XHTML_1_0_STRICT: - fprintf(ho.fp, "\n", - charset_to_mimeenc(conf.output_charset)); - fprintf(ho.fp, "\n"); + if (ho.fp) { + fprintf(ho.fp, "\n", + charset_to_mimeenc(conf.output_charset)); + fprintf(ho.fp, "\n"); + } break; } @@ -1811,16 +1821,18 @@ static void html_charset_cleanup(htmloutput *ho) bytes = charset_from_unicode(NULL, NULL, outbuf, lenof(outbuf), ho->charset, &ho->cstate, NULL); - if (bytes > 0) + if (ho->fp && bytes > 0) fwrite(outbuf, 1, bytes, ho->fp); } static void return_mostly_to_neutral(htmloutput *ho) { - if (ho->state == HO_IN_EMPTY_TAG && is_xhtml(ho->ver)) { - fprintf(ho->fp, " />"); - } else if (ho->state == HO_IN_EMPTY_TAG || ho->state == HO_IN_TAG) { - fprintf(ho->fp, ">"); + if (ho->fp) { + if (ho->state == HO_IN_EMPTY_TAG && is_xhtml(ho->ver)) { + fprintf(ho->fp, " />"); + } else if (ho->state == HO_IN_EMPTY_TAG || ho->state == HO_IN_TAG) { + fprintf(ho->fp, ">"); + } } ho->state = HO_NEUTRAL; @@ -1838,58 +1850,68 @@ static void return_to_neutral(htmloutput *ho) static void element_open(htmloutput *ho, char const *name) { return_to_neutral(ho); - fprintf(ho->fp, "<%s", name); + if (ho->fp) + fprintf(ho->fp, "<%s", name); ho->state = HO_IN_TAG; } static void element_close(htmloutput *ho, char const *name) { return_to_neutral(ho); - fprintf(ho->fp, "", name); + if (ho->fp) + fprintf(ho->fp, "", name); ho->state = HO_NEUTRAL; } static void element_empty(htmloutput *ho, char const *name) { return_to_neutral(ho); - fprintf(ho->fp, "<%s", name); + if (ho->fp) + fprintf(ho->fp, "<%s", name); ho->state = HO_IN_EMPTY_TAG; } static void html_nl(htmloutput *ho) { return_to_neutral(ho); - fputc('\n', ho->fp); + if (ho->fp) + fputc('\n', ho->fp); } static void html_raw(htmloutput *ho, char *text) { return_to_neutral(ho); - fputs(text, ho->fp); + if (ho->fp) + fputs(text, ho->fp); } static void html_raw_as_attr(htmloutput *ho, char *text) { assert(ho->state == HO_IN_TAG || ho->state == HO_IN_EMPTY_TAG); - fputc(' ', ho->fp); - fputs(text, ho->fp); + if (ho->fp) { + fputc(' ', ho->fp); + fputs(text, ho->fp); + } } static void element_attr(htmloutput *ho, char const *name, char const *value) { html_charset_cleanup(ho); assert(ho->state == HO_IN_TAG || ho->state == HO_IN_EMPTY_TAG); - fprintf(ho->fp, " %s=\"%s\"", name, value); + if (ho->fp) + fprintf(ho->fp, " %s=\"%s\"", name, value); } static void element_attr_w(htmloutput *ho, char const *name, wchar_t const *value) { html_charset_cleanup(ho); - fprintf(ho->fp, " %s=\"", name); + if (ho->fp) + fprintf(ho->fp, " %s=\"", name); html_text_limit_internal(ho, value, 0, TRUE, FALSE); html_charset_cleanup(ho); - fputc('"', ho->fp); + if (ho->fp) + fputc('"', ho->fp); } static void html_text(htmloutput *ho, wchar_t const *text) @@ -1934,7 +1956,7 @@ static void html_text_limit_internal(htmloutput *ho, wchar_t const *text, bytes = charset_from_unicode(&text, &lenafter, outbuf, lenof(outbuf), ho->charset, &ho->cstate, &err); textlen -= (lenbefore - lenafter); - if (bytes > 0) + if (bytes > 0 && ho->fp) fwrite(outbuf, 1, bytes, ho->fp); if (err) { /* @@ -1943,26 +1965,29 @@ static void html_text_limit_internal(htmloutput *ho, wchar_t const *text, * we use an HTML numeric entity reference. */ assert(textlen > 0); - fprintf(ho->fp, "&#%ld;", (long int)*text); + if (ho->fp) + fprintf(ho->fp, "&#%ld;", (long int)*text); text++, textlen--; } else if (lenafter == 0 && textlen > 0) { /* * We have encountered a character which is special to * HTML. */ - if (*text == L'<') - fprintf(ho->fp, "<"); - else if (*text == L'>') - fprintf(ho->fp, ">"); - else if (*text == L'&') - fprintf(ho->fp, "&"); - else if (*text == L'"') - fprintf(ho->fp, """); - else if (*text == L' ') { - assert(nbsp); - fprintf(ho->fp, " "); - } else - assert(!"Can't happen"); + if (ho->fp) { + if (*text == L'<') + fprintf(ho->fp, "<"); + else if (*text == L'>') + fprintf(ho->fp, ">"); + else if (*text == L'&') + fprintf(ho->fp, "&"); + else if (*text == L'"') + fprintf(ho->fp, """); + else if (*text == L' ') { + assert(nbsp); + fprintf(ho->fp, " "); + } else + assert(!"Can't happen"); + } text++, textlen--; } } @@ -1971,7 +1996,8 @@ static void html_text_limit_internal(htmloutput *ho, wchar_t const *text, static void cleanup(htmloutput *ho) { return_to_neutral(ho); - fclose(ho->fp); + if (ho->fp) + fclose(ho->fp); } static void html_href(htmloutput *ho, htmlfile *thisfile, diff --git a/bk_whlp.c b/bk_whlp.c index 9772021..14e6b01 100644 --- a/bk_whlp.c +++ b/bk_whlp.c @@ -212,6 +212,10 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords, } state.cntfp = fopen(cntname, "wb"); + if (!state.cntfp) { + error(err_cantopenw, cntname); + return; + } state.cnt_last_level = -1; state.cnt_workaround = 0; /*