fix bug 3236, 'sc_html_parse_tag() does not recognize '<br/>' as line break'
[claws.git] / src / html.c
index 08b39f3067816379962a40f2a5c643d073a3d550..ff5a61eb3beebca9ef60f9f56947e21712df9a3e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -331,8 +331,8 @@ SC_HTMLParser *sc_html_parser_new(FILE *fp, CodeConverter *conv)
 {
        SC_HTMLParser *parser;
 
-       g_return_val_if_fail(fp != NULL, NULL);
-       g_return_val_if_fail(conv != NULL, NULL);
+       cm_return_val_if_fail(fp != NULL, NULL);
+       cm_return_val_if_fail(conv != NULL, NULL);
 
        parser = g_new0(SC_HTMLParser, 1);
        parser->fp = fp;
@@ -440,14 +440,17 @@ static SC_HTMLState sc_html_read_line(SC_HTMLParser *parser)
        gchar buf[SC_HTMLBUFSIZE];
        gchar buf2[SC_HTMLBUFSIZE];
        gint index;
+       gint n;
 
        if (parser->fp == NULL)
                return SC_HTML_EOF;
 
-       if (fgets(buf, sizeof(buf), parser->fp) == NULL) {
+       n = fread(buf, 1, sizeof(buf) - 1, parser->fp);
+       if (n == 0) {
                parser->state = SC_HTML_EOF;
                return SC_HTML_EOF;
-       }
+       } else
+               buf[n] = '\0';
 
        if (conv_convert(parser->conv, buf2, sizeof(buf2), buf) < 0) {
                index = parser->bufp - parser->buf->str;
@@ -522,7 +525,7 @@ static SC_HTMLTag *sc_html_get_tag(const gchar *str)
        gchar *tmp;
        guchar *tmpp;
 
-       g_return_val_if_fail(str != NULL, NULL);
+       cm_return_val_if_fail(str != NULL, NULL);
 
        if (*str == '\0' || *str == '!') return NULL;
 
@@ -640,7 +643,7 @@ static SC_HTMLState sc_html_parse_tag(SC_HTMLParser *parser)
        parser->state = SC_HTML_UNKNOWN;
        if (!tag) return SC_HTML_UNKNOWN;
 
-       if (!strcmp(tag->name, "br")) {
+       if (!strcmp(tag->name, "br") || !strcmp(tag->name, "br/")) {
                parser->space = FALSE;
                sc_html_append_char(parser, '\n');
                parser->state = SC_HTML_BR;
@@ -721,7 +724,7 @@ static void sc_html_parse_special(SC_HTMLParser *parser)
        const gchar *val;
 
        parser->state = SC_HTML_UNKNOWN;
-       g_return_if_fail(*parser->bufp == '&');
+       cm_return_if_fail(*parser->bufp == '&');
 
        /* &foo; */
        for (n = 0; parser->bufp[n] != '\0' && parser->bufp[n] != ';'; n++)
@@ -745,12 +748,28 @@ static void sc_html_parse_special(SC_HTMLParser *parser)
        sc_html_append_str(parser, symbol_name, -1);
 }
 
+static gchar *sc_html_find_tag(SC_HTMLParser *parser, const gchar *tag)
+{
+       gchar *cur = parser->bufp;
+       gint len = strlen(tag);
+
+       if (cur == NULL)
+               return NULL;
+
+       while ((cur = strstr(cur, "<")) != NULL) {
+               if (!g_ascii_strncasecmp(cur, tag, len))
+                       return cur;
+               cur += 2;
+       }
+       return NULL;
+}
+
 static void sc_html_get_parenthesis(SC_HTMLParser *parser, gchar *buf, gint len)
 {
        gchar *p;
 
        buf[0] = '\0';
-       g_return_if_fail(*parser->bufp == '<');
+       cm_return_if_fail(*parser->bufp == '<');
 
        /* ignore comment / CSS / script stuff */
        if (!strncmp(parser->bufp, "<!--", 4)) {
@@ -762,14 +781,14 @@ static void sc_html_get_parenthesis(SC_HTMLParser *parser, gchar *buf, gint len)
        }
        if (!g_ascii_strncasecmp(parser->bufp, "<style", 6)) {
                parser->bufp += 6;
-               while ((p = strcasestr(parser->bufp, "</style>")) == NULL)
+               while ((p = sc_html_find_tag(parser, "</style>")) == NULL)
                        if (sc_html_read_line(parser) == SC_HTML_EOF) return;
                parser->bufp = p + 8;
                return;
        }
        if (!g_ascii_strncasecmp(parser->bufp, "<script", 7)) {
                parser->bufp += 7;
-               while ((p = strcasestr(parser->bufp, "</script>")) == NULL)
+               while ((p = sc_html_find_tag(parser, "</script>")) == NULL)
                        if (sc_html_read_line(parser) == SC_HTML_EOF) return;
                parser->bufp = p + 9;
                return;