| 3762 | */ |
| 3763 | |
| 3764 | static int |
| 3765 | htmlParseStartTag(htmlParserCtxtPtr ctxt) { |
| 3766 | const xmlChar *name; |
| 3767 | const xmlChar *attname; |
| 3768 | xmlChar *attvalue; |
| 3769 | const xmlChar **atts; |
| 3770 | int nbatts = 0; |
| 3771 | int maxatts; |
| 3772 | int meta = 0; |
| 3773 | int i; |
| 3774 | int discardtag = 0; |
| 3775 | |
| 3776 | if ((ctxt == NULL) || (ctxt->input == NULL)) |
| 3777 | return -1; |
| 3778 | if (CUR != '<') return -1; |
| 3779 | NEXT; |
| 3780 | |
| 3781 | atts = ctxt->atts; |
| 3782 | maxatts = ctxt->maxatts; |
| 3783 | |
| 3784 | GROW; |
| 3785 | name = htmlParseHTMLName(ctxt); |
| 3786 | if (name == NULL) { |
| 3787 | htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED, |
| 3788 | "htmlParseStartTag: invalid element name\n", |
| 3789 | NULL, NULL); |
| 3790 | /* Dump the bogus tag like browsers do */ |
| 3791 | while ((CUR != 0) && (CUR != '>') && |
| 3792 | (PARSER_STOPPED(ctxt) == 0)) |
| 3793 | NEXT; |
| 3794 | return -1; |
| 3795 | } |
| 3796 | if (xmlStrEqual(name, BAD_CAST"meta")) |
| 3797 | meta = 1; |
| 3798 | |
| 3799 | /* |
| 3800 | * Check for auto-closure of HTML elements. |
| 3801 | */ |
| 3802 | htmlAutoClose(ctxt, name); |
| 3803 | |
| 3804 | /* |
| 3805 | * Check for implied HTML elements. |
| 3806 | */ |
| 3807 | htmlCheckImplied(ctxt, name); |
| 3808 | |
| 3809 | /* |
| 3810 | * Avoid html at any level > 0, head at any level != 1 |
| 3811 | * or any attempt to recurse body |
| 3812 | */ |
| 3813 | if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) { |
| 3814 | htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR, |
| 3815 | "htmlParseStartTag: misplaced <html> tag\n", |
| 3816 | name, NULL); |
| 3817 | discardtag = 1; |
| 3818 | ctxt->depth++; |
| 3819 | } |
| 3820 | if ((ctxt->nameNr != 1) && |
| 3821 | (xmlStrEqual(name, BAD_CAST"head"))) { |
no test coverage detected