From ce12353e70a468374baf90a7d09cdb71b2224add Mon Sep 17 00:00:00 2001 From: Jorge Arellano Cid Date: Wed, 21 Jan 2009 18:54:29 -0300 Subject: Fixed charset decoding given in HTTP and META. (bugs and race condition) --- src/cache.c | 41 +++++++++++++++++++++++++---------------- src/html.cc | 27 +++++++++++++-------------- src/nav.c | 1 + 3 files changed, 39 insertions(+), 30 deletions(-) (limited to 'src') 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) " The author wanted you to go\n" " here%s
\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(); } -- cgit v1.2.3