aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-02-03 09:18:49 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-02-03 09:18:49 -0300
commitba53afebc95493fcf3a7105989e2cabb015b4b1b (patch)
treeba2d4120e27956da3c5dc2e276731d5c50db5b75 /src
parent69bcd6963fabfd547495c186e3ea570d2f33cbed (diff)
Fix a race condition with charset, and the case of charset after CSS in HEAD
Race condition example: www.blisty.cz charset after CSS ex. : http://www.daemonnews.org
Diffstat (limited to 'src')
-rw-r--r--src/cache.c5
-rw-r--r--src/html.cc55
-rw-r--r--src/html_common.hh6
3 files changed, 44 insertions, 22 deletions
diff --git a/src/cache.c b/src/cache.c
index 8d01c40e..8ab9e1a4 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -424,7 +424,8 @@ static void Cache_ref_data(CacheEntry_t *entry)
if (entry) {
entry->DataRefcount++;
_MSG("DataRefcount++: %d\n", entry->DataRefcount);
- if (entry->CharsetDecoder && entry->DataRefcount == 1) {
+ if (entry->CharsetDecoder &&
+ (!entry->UTF8Data || entry->DataRefcount == 1)) {
dStr_free(entry->UTF8Data, 1);
entry->UTF8Data = a_Decode_process(entry->CharsetDecoder,
entry->Data->str,
@@ -518,7 +519,7 @@ const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype,
entry->CharsetDecoder = a_Decode_charset_init(charset);
dFree(charset);
curr = Cache_current_content_type(entry);
-
+
/* Invalidate UTF8Data */
dStr_free(entry->UTF8Data, 1);
entry->UTF8Data = NULL;
diff --git a/src/html.cc b/src/html.cc
index 5571b8bb..93cb769b 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -110,6 +110,7 @@ static void Html_load_image(BrowserWindow *bw, DilloUrl *url,
DilloImage *image);
static void Html_callback(int Op, CacheClient_t *Client);
static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx);
+static void Html_load_stylesheet(DilloHtml *html, DilloUrl *url);
/*-----------------------------------------------------------------------------
* Local Data
@@ -416,7 +417,6 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
a_Misc_parse_content_type(content_type, NULL, NULL, &charset);
stop_parser = false;
- repush_after_head = false;
CurrTagOfs = 0;
OldTagOfs = 0;
@@ -425,6 +425,8 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
DocType = DT_NONE; /* assume Tag Soup 0.0! :-) */
DocTypeVersion = 0.0f;
+ cssUrls = new misc::SimpleVector <DilloUrl*> (1);
+
stack = new misc::SimpleVector <DilloHtmlState> (16);
stack->increase();
stack->getRef(0)->table_cell_props = NULL;
@@ -509,6 +511,11 @@ DilloHtml::~DilloHtml()
a_Url_free(page_url);
a_Url_free(base_url);
+ for (int i = 0; i < cssUrls->size(); i++)
+ if (cssUrls->get(i))
+ a_Url_free(cssUrls->get(i));
+ delete (cssUrls);
+
for (int i = 0; i < forms->size(); i++)
a_Html_form_delete (forms->get(i));
delete(forms);
@@ -613,6 +620,8 @@ void DilloHtml::finishParsing(int ClientKey)
{
int si;
+ dReturn_if (stop_parser == true);
+
/* force the close of elements left open (TODO: not for XHTML) */
while ((si = stack->size() - 1)) {
if (stack->getRef(si)->tag_idx != -1) {
@@ -672,6 +681,16 @@ void DilloHtml::loadImages (const DilloUrl *pattern)
}
}
+/*
+ * Save URL in a vector (may be loaded later).
+ */
+void DilloHtml::addCssUrl(const DilloUrl *url)
+{
+ int nu = cssUrls->size();
+ cssUrls->increase();
+ cssUrls->set(nu, a_Url_dup(url));
+}
+
bool DilloHtml::HtmlLinkReceiver::enter (Widget *widget, int link, int img,
int x, int y)
{
@@ -1552,8 +1571,7 @@ static void Html_tag_open_head(DilloHtml *html, const char *tag, int tagsize)
* Handle close HEAD element
* Note: as a side effect of Html_test_section() this function is called
* twice when the head element is closed implicitly.
- * Note2: HEAD is parsed once completely got. This asserts that a
- * linked stylesheet will always arrive after HEAD contents.
+ * Note2: HEAD is parsed once completely got.
*/
static void Html_tag_close_head(DilloHtml *html, int TagIdx)
{
@@ -1564,10 +1582,9 @@ static void Html_tag_close_head(DilloHtml *html, int TagIdx)
html->InFlags &= ~IN_HEAD;
- if (html->repush_after_head) {
- html->stop_parser = true;
- MSG(" [html->stop_parser = true]\n");
- a_UIcmd_repush(html->bw);
+ /* charset is already set, load remote stylesheets now */
+ for (int i = 0; i < html->cssUrls->size(); i++) {
+ Html_load_stylesheet(html, html->cssUrls->get(i));
}
}
}
@@ -2768,8 +2785,8 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
*/
new_content = a_Capi_set_content_type(html->page_url,content,"meta");
if (a_Misc_content_type_cmp(html->content_type, new_content)) {
- html->stop_parser = true; /* Avoid a race condition */
- html->repush_after_head = true;
+ html->stop_parser = true; /* The cache buffer is no longer valid */
+ a_UIcmd_repush(html->bw);
}
}
}
@@ -2780,7 +2797,7 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
*/
static void Html_css_load_callback(int Op, CacheClient_t *Client)
{
- _MSG("Css_callback: Op=%d\n", Op);
+ _MSG("Html_css_load_callback: Op=%d\n", Op);
if (Op) { /* EOF */
BrowserWindow *bw = ((DilloWeb *)Client->Web)->bw;
/* Repush when we've got them all */
@@ -2796,25 +2813,28 @@ static void Html_load_stylesheet(DilloHtml *html, DilloUrl *url)
{
char *data;
int len;
+
+ dReturn_if (url == NULL);
+
+ _MSG("Html_load_stylesheet: ");
if (a_Capi_get_buf(url, &data, &len)) {
- /* Haven't looked into what origin_count is */
+ _MSG("cached URL=%s len=%d", URL_STR(url), len);
if (a_Capi_get_flags(url) & CAPI_Completed)
html->styleEngine->parse(data, len, 0, CSS_ORIGIN_AUTHOR);
a_Capi_unref_buf(url);
- } else if (!html->repush_after_head) {
+ } else {
/* Fill a Web structure for the cache query */
int ClientKey;
DilloWeb *Web = a_Web_new(url);
Web->bw = html->bw;
- //Web->flags |= WEB_Stylesheet;
if ((ClientKey = a_Capi_open_url(Web, Html_css_load_callback, NULL))) {
++html->bw->NumPendingStyleSheets;
a_Bw_add_client(html->bw, ClientKey, 0);
a_Bw_add_url(html->bw, url);
- MSG("Html_load_stylesheet: NumPendingStyleSheets=%d\n",
- html->bw->NumPendingStyleSheets);
+ MSG("NumPendingStyleSheets=%d", html->bw->NumPendingStyleSheets);
}
}
+ MSG("\n");
}
/*
@@ -2861,10 +2881,9 @@ static void Html_tag_open_link(DilloHtml *html, const char *tag, int tagsize)
!(url = a_Html_url_new(html, attrbuf, NULL, 0)))
return;
- MSG(" Html_tag_open_link(): URL=%s\n", URL_STR(url));
- _MSG(" repush after HEAD=%d\n", html->repush_after_head);
+ MSG(" Html_tag_open_link(): addCssUrl %s\n", URL_STR(url));
- Html_load_stylesheet(html, url);
+ html->addCssUrl(url);
a_Url_free(url);
}
diff --git a/src/html_common.hh b/src/html_common.hh
index de87ec80..7983ea5a 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -172,14 +172,15 @@ public: //BUG: for now everything is public
char *content_type, *charset;
bool stop_parser;
- bool repush_after_head;
-
size_t CurrTagOfs;
size_t OldTagOfs, OldTagLine;
DilloHtmlDocumentType DocType; /* as given by DOCTYPE tag */
float DocTypeVersion; /* HTML or XHTML version number */
+ /* vector of remote CSS resources, as given by the LINK element */
+ lout::misc::SimpleVector<DilloUrl*> *cssUrls;
+
lout::misc::SimpleVector<DilloHtmlState> *stack;
StyleEngine *styleEngine;
@@ -233,6 +234,7 @@ public:
DilloHtmlForm *getCurrentForm ();
bool_t unloadedImages();
void loadImages (const DilloUrl *pattern);
+ void addCssUrl(const DilloUrl *url);
};
/*