Escape &<> when they appear in href text.
[sgt/halibut] / bk_html.c
index fad891c..e3202a5 100644 (file)
--- a/bk_html.c
+++ b/bk_html.c
@@ -884,7 +884,10 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
 #define listname(lt) ( (lt)==UL ? "ul" : (lt)==OL ? "ol" : "dl" )
 #define itemname(lt) ( (lt)==LI ? "li" : (lt)==DT ? "dt" : "dd" )
 
-           ho.fp = fopen(f->filename, "w");
+           if (!strcmp(f->filename, "-"))
+               ho.fp = stdout;
+           else
+               ho.fp = fopen(f->filename, "w");
            if (!ho.fp)
                error(err_cantopenw, f->filename);
 
@@ -2173,7 +2176,7 @@ static void html_words(htmloutput *ho, word *words, int flags,
                       htmlfile *file, keywordlist *keywords, htmlconfig *cfg)
 {
     word *w;
-    char *c;
+    char *c, *c2, *p, *q;
     int style, type;
 
     for (w = words; w; w = w->next) switch (w->type) {
@@ -2181,7 +2184,20 @@ static void html_words(htmloutput *ho, word *words, int flags,
        if (flags & LINKS) {
            element_open(ho, "a");
            c = utoa_dup(w->text, CS_ASCII);
-           element_attr(ho, "href", c);
+           c2 = snewn(1 + 10*strlen(c), char);
+           for (p = c, q = c2; *p; p++) {
+               if (*p == '&')
+                   q += sprintf(q, "&amp;");
+               else if (*p == '<')
+                   q += sprintf(q, "&lt;");
+               else if (*p == '>')
+                   q += sprintf(q, "&gt;");
+               else
+                   *q++ = *p;
+           }
+           *q = '\0';
+           element_attr(ho, "href", c2);
+           sfree(c2);
            sfree(c);
        }
        break;
@@ -2507,7 +2523,7 @@ static void html_text_limit_internal(htmloutput *ho, wchar_t const *text,
 static void cleanup(htmloutput *ho)
 {
     return_to_neutral(ho);
-    if (ho->fp)
+    if (ho->fp && ho->fp != stdout)
        fclose(ho->fp);
 }