]> granicus.if.org Git - libexpat/commitdiff
xmlparse.c: Deny internal entities closing the doctype
authorSebastian Pipping <sebastian@pipping.org>
Tue, 27 Aug 2019 22:24:59 +0000 (00:24 +0200)
committerSebastian Pipping <sebastian@pipping.org>
Wed, 28 Aug 2019 13:14:26 +0000 (15:14 +0200)
expat/lib/xmlparse.c

index 0553e3df8258c261e3cf27fc072d49a9851f6d9c..c29a6449db592fda99b9f9c4b1341d703d11ce2d 100644 (file)
@@ -401,7 +401,7 @@ static enum XML_Error initializeEncoding(XML_Parser parser);
 static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
                                const char *s, const char *end, int tok,
                                const char *next, const char **nextPtr,
-                               XML_Bool haveMore);
+                               XML_Bool haveMore, XML_Bool allowClosingDoctype);
 static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
                                             XML_Bool betweenDecl);
 static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
@@ -4046,7 +4046,7 @@ externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
 
   parser->m_processor = prologProcessor;
   return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-                  (XML_Bool)! parser->m_parsingStatus.finalBuffer);
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
 }
 
 static enum XML_Error PTRCALL
@@ -4090,12 +4090,13 @@ prologProcessor(XML_Parser parser, const char *s, const char *end,
   const char *next = s;
   int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
   return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-                  (XML_Bool)! parser->m_parsingStatus.finalBuffer);
+                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
 }
 
 static enum XML_Error
 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
-         int tok, const char *next, const char **nextPtr, XML_Bool haveMore) {
+         int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
+         XML_Bool allowClosingDoctype) {
 #ifdef XML_DTD
   static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
 #endif /* XML_DTD */
@@ -4271,6 +4272,11 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
       }
       break;
     case XML_ROLE_DOCTYPE_CLOSE:
+      if (allowClosingDoctype != XML_TRUE) {
+        /* Must not close doctype from within expanded parameter entities */
+        return XML_ERROR_INVALID_TOKEN;
+      }
+
       if (parser->m_doctypeName) {
         parser->m_startDoctypeDeclHandler(
             parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
@@ -5174,7 +5180,7 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
     int tok
         = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
     result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-                      tok, next, &next, XML_FALSE);
+                      tok, next, &next, XML_FALSE, XML_FALSE);
   } else
 #endif /* XML_DTD */
     result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
@@ -5217,7 +5223,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
     int tok
         = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
     result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
-                      tok, next, &next, XML_FALSE);
+                      tok, next, &next, XML_FALSE, XML_TRUE);
   } else
 #endif /* XML_DTD */
     result = doContent(parser, openEntity->startTagLevel,
@@ -5244,7 +5250,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
     parser->m_processor = prologProcessor;
     tok = XmlPrologTok(parser->m_encoding, s, end, &next);
     return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
-                    (XML_Bool)! parser->m_parsingStatus.finalBuffer);
+                    (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
   } else
 #endif /* XML_DTD */
   {