summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-01-21 18:54:29 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-01-21 18:54:29 -0300
commitce12353e70a468374baf90a7d09cdb71b2224add (patch)
tree2c158dcf57c372ada6be6b4a04a3bcd7df8bd4a3
parent94f2baf7660ac7b0baccbe79725a817ed877260f (diff)
Fixed charset decoding given in HTTP and META. (bugs and race condition)
-rw-r--r--src/cache.c41
-rw-r--r--src/html.cc27
-rw-r--r--src/nav.c1
3 files changed, 39 insertions, 30 deletions
diff --git a/src/cache.c b/src/cache.c
index 328d4913..5a804b21 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -497,23 +497,31 @@ const char *a_Cache_set_content_type(const DilloUrl *url, const char *ctype)
curr = Cache_current_content_type(entry);
if (entry->TypeMeta) {
- /* Type is already been set. Do nothing.
+ /* Type is already been set. Do nothing. META overrides TypeHdr.
* Multiple META elements? */
- } else if (a_Misc_content_type_cmp(curr, ctype)) {
- /* TypeMeta not set, and META gives one different from default */
- curr = entry->TypeMeta = dStrdup(ctype);
- if (entry->CharsetDecoder)
- a_Decode_free(entry->CharsetDecoder);
- a_Misc_parse_content_type(ctype, NULL, NULL, &charset);
- entry->CharsetDecoder = a_Decode_charset_init(charset);
- dFree(charset);
-
- /* Invalidate UTF8Data */
- dStr_free(entry->UTF8Data, 1);
- entry->UTF8Data = NULL;
+ } else {
+ if (!entry->TypeHdr) {
+ /* Content-Type from HTTP header */
+ entry->TypeHdr = dStrdup(ctype);
+ } else {
+ /* Content-Type from META */
+ entry->TypeMeta = dStrdup(ctype);
+ }
+ if (a_Misc_content_type_cmp(curr, ctype)) {
+ /* ctype gives one different from current */
+ if (entry->CharsetDecoder)
+ a_Decode_free(entry->CharsetDecoder);
+ a_Misc_parse_content_type(ctype, NULL, NULL, &charset);
+ 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;
+ }
}
-
return curr;
}
@@ -739,7 +747,6 @@ static void Cache_parse_header(CacheEntry_t *entry)
dStr_free(entry->Data, 1);
entry->Data = dStr_sized_new(MIN(entry->ExpectedSize, MAX_INIT_BUF));
}
- Cache_ref_data(entry);
/* Get Content-Type */
if ((Type = Cache_parse_field(header, "Content-Type")) == NULL) {
@@ -750,10 +757,12 @@ static void Cache_parse_header(CacheEntry_t *entry)
} else {
/* This HTTP Content-Type is not trusted. It's checked against real data
* in Cache_process_queue(); only then CA_GotContentType becomes true. */
- entry->TypeHdr = Type;
+ a_Cache_set_content_type(entry->Url, Type);
_MSG("TypeHdr {%s} {%s}\n", Type, URL_STR(entry->Url));
_MSG("TypeMeta {%s}\n", entry->TypeMeta);
+ dFree(Type);
}
+ Cache_ref_data(entry);
}
/*
diff --git a/src/html.cc b/src/html.cc
index d57d7300..334e50db 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -571,8 +571,8 @@ void DilloHtml::write(char *Buf, int BufSize, int Eof)
dFree(aux);
#endif
- dReturn_if_fail (dw != NULL);
- dReturn_if_fail (stop_parser == FALSE);
+ dReturn_if (dw == NULL);
+ dReturn_if (stop_parser == TRUE);
Start_Buf = Buf;
token_start = Html_write_raw(this, buf, bufsize, Eof);
@@ -2736,7 +2736,7 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
" <tr><td bgcolor='#a0a0a0' colspan='2'>The author wanted you to go\n"
" <a href='%s'>here</a>%s</td></tr></table><br>\n";
- const char *equiv, *content;
+ const char *equiv, *content, *new_content;
char delay_str[64];
Dstr *ds_msg;
int delay;
@@ -2778,15 +2778,14 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
} else if (!dStrcasecmp(equiv, "content-type") &&
(content = a_Html_get_attr(html, tag, tagsize, "content"))) {
- if (a_Misc_content_type_cmp(html->content_type, content)) {
- const char *new_content =
- a_Capi_set_content_type(html->page_url, content);
- /* Cannot ask cache whether the content type was changed, as
- * this code in another bw might have already changed it for us.
- */
- if (a_Misc_content_type_cmp(html->content_type, new_content)) {
- html->repush_after_head = true;
- }
+ _MSG("Html_tag_open_meta: content={%s}\n", content);
+ /* Cannot ask cache whether the content type was changed, as
+ * this code in another bw might have already changed it for us.
+ */
+ new_content = a_Capi_set_content_type(html->page_url, content);
+ if (a_Misc_content_type_cmp(html->content_type, new_content)) {
+ html->stop_parser = true; /* Avoid a race condition */
+ html->repush_after_head = true;
}
}
}
@@ -3303,7 +3302,7 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize)
char *start = tag + 1; /* discard the '<' */
int IsCloseTag = (*start == '/');
- dReturn_if_fail ( html->stop_parser == false );
+ dReturn_if (html->stop_parser == TRUE);
ni = a_Html_tag_index(start + IsCloseTag);
if (ni == -1) {
@@ -3586,7 +3585,7 @@ static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof)
* boundary. Iterate through tokens until end of buffer is reached. */
buf_index = 0;
token_start = buf_index;
- while ((buf_index < bufsize) && (html->stop_parser == false)) {
+ while ((buf_index < bufsize) && !html->stop_parser) {
/* invariant: buf_index == bufsize || token_start == buf_index */
if (S_TOP(html)->parse_mode ==
diff --git a/src/nav.c b/src/nav.c
index ad8eb43b..abfec30d 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -370,6 +370,7 @@ static void Nav_repush(BrowserWindow *bw)
static void Nav_repush_callback(void *data)
{
+ _MSG(">>> Nav_repush_callback <<<<\n");
Nav_repush(data);
a_Timeout_remove();
}