commit 27015b41e71261b25f99f9c0b151a239700feb1e Author: Olli Pottonen Date: Tue Jul 7 22:23:04 2015 +1000 Fix detecting whether encoding declaration is present. Incorrect mechanisms were used to detect whether an encoding declaration is present or not. This caused some bugs. Firstly, missing whitespace, a fatal error, is not detected, e.g. . Also, if XML_PARSE_IGNORE_ENC option is specified, we get a missing encoding declaration error in an external entity even if an encoding declaration is present. diff --git a/parser.c b/parser.c index d7457fc..93f8d35 100644 --- a/parser.c +++ b/parser.c @@ -6991,7 +6991,6 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) { void xmlParseTextDecl(xmlParserCtxtPtr ctxt) { xmlChar *version; - const xmlChar *encoding; /* * We know that 'input->version = version; /* - * We must have the encoding declaration + * We must have the encoding declaration. + * Unfortunately xmlParseEncodingDecl() has no reliable, backwards + * compatible way of telling us whether there is one. Hack around that. */ - encoding = xmlParseEncodingDecl(ctxt); + const xmlChar *preEncodingCur = ctxt->input->cur; + SKIP_BLANKS; + xmlParseEncodingDecl(ctxt); if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { /* * The XML REC instructs us to stop parsing right here */ return; } - if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) { + int hasEncodingDecl = (ctxt->input->cur != preEncodingCur); + + if (!hasEncodingDecl) { xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING, "Missing encoding in text declaration\n"); } @@ -10639,6 +10644,8 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) { } xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n"); } + SKIP_BLANKS; + const xmlChar * preEncodingCur = ctxt->input->cur; xmlParseEncodingDecl(ctxt); if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { /* @@ -10650,7 +10657,8 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) { /* * We may have the standalone status. */ - if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) { + int hasEncodingDecl = (ctxt->input->cur != preEncodingCur); + if (hasEncodingDecl && (!IS_BLANK_CH(RAW))) { if ((RAW == '?') && (NXT(1) == '>')) { SKIP(2); return;