diff options
author | Jorge Arellano Cid <jcid@dillo.org> | 2013-08-26 15:05:44 -0400 |
---|---|---|
committer | Jorge Arellano Cid <jcid@dillo.org> | 2013-08-26 15:05:44 -0400 |
commit | cc2b0c119f9a34330153855c4f42c490ecfc2d23 (patch) | |
tree | 0f225c763088de8649cefac4bdae79f60fbf401d /src/html.cc | |
parent | 4fbea0e16f95208a8293b0f7fa96652bdc7a33dc (diff) |
Fix handling of the HEAD element
Avoids overflow of Num_HEAD variable, its potential problems
and improves HTML bug messages.
The handling algorithm changed to not only care gracefully for
some tag soup cases, but also for malicious HTML.
Diffstat (limited to 'src/html.cc')
-rw-r--r-- | src/html.cc | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/html.cc b/src/html.cc index 6b129188..5e2c799b 100644 --- a/src/html.cc +++ b/src/html.cc @@ -1649,40 +1649,48 @@ static void Html_tag_close_html(DilloHtml *html) */ static void Html_tag_open_head(DilloHtml *html, const char *tag, int tagsize) { - if (html->InFlags & IN_BODY || html->Num_BODY > 0) { + if (html->InFlags & IN_BODY) { BUG_MSG("HEAD element must go before the BODY section\n"); html->ReqTagClose = true; return; } - if (!(html->InFlags & IN_HEAD)) - html->InFlags |= IN_HEAD; - ++html->Num_HEAD; - - if (html->Num_HEAD > 1) { + if (html->Num_HEAD < UCHAR_MAX) + ++html->Num_HEAD; + if (html->InFlags & IN_HEAD) { BUG_MSG("HEAD element was already open\n"); + html->ReqTagClose = true; + } else if (html->Num_HEAD > 1) { + BUG_MSG("HEAD section already finished -- ignoring\n"); + html->ReqTagClose = true; + } else { + html->InFlags |= IN_HEAD; } } /* * 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. + * Note: HEAD is parsed once completely got. */ static void Html_tag_close_head(DilloHtml *html) { if (html->InFlags & IN_HEAD) { - _MSG("Closing HEAD section\n"); - if (html->Num_TITLE == 0) - BUG_MSG("HEAD section lacks the TITLE element\n"); - - html->InFlags &= ~IN_HEAD; - - /* charset is already set, load remote stylesheets now */ - for (int i = 0; i < html->cssUrls->size(); i++) { - a_Html_load_stylesheet(html, html->cssUrls->get(i)); + if (html->Num_HEAD == 1) { + /* match for the well formed start of HEAD section */ + if (html->Num_TITLE == 0) + BUG_MSG("HEAD section lacks the TITLE element\n"); + + html->InFlags &= ~IN_HEAD; + + /* charset is already set, load remote stylesheets now */ + for (int i = 0; i < html->cssUrls->size(); i++) { + a_Html_load_stylesheet(html, html->cssUrls->get(i)); + } + } else if (html->Num_HEAD > 1) { + --html->Num_HEAD; } + } else { + /* not reached, see Html_tag_cleanup_at_close() */ } } |