|
1 | | -/* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+) |
| 1 | +/* 5ab094ffadd6edfc94c3eee53af44a86951f9f1f0933ada3114bbce2bfb02c99 (2.5.0+) |
2 | 2 | __ __ _ |
3 | 3 | ___\ \/ /_ __ __ _| |_ |
4 | 4 | / _ \\ /| '_ \ / _` | __| |
|
35 | 35 | Copyright (c) 2021 Dong-hee Na <[email protected]> |
36 | 36 | Copyright (c) 2022 Samanta Navarro <[email protected]> |
37 | 37 | Copyright (c) 2022 Jeffrey Walton <[email protected]> |
| 38 | + Copyright (c) 2022 Jann Horn <[email protected]> |
38 | 39 | Licensed under the MIT license: |
39 | 40 |
|
40 | 41 | Permission is hereby granted, free of charge, to any person obtaining |
@@ -1068,6 +1069,14 @@ parserCreate(const XML_Char *encodingName, |
1068 | 1069 | parserInit(parser, encodingName); |
1069 | 1070 |
|
1070 | 1071 | if (encodingName && ! parser->m_protocolEncodingName) { |
| 1072 | + if (dtd) { |
| 1073 | + // We need to stop the upcoming call to XML_ParserFree from happily |
| 1074 | + // destroying parser->m_dtd because the DTD is shared with the parent |
| 1075 | + // parser and the only guard that keeps XML_ParserFree from destroying |
| 1076 | + // parser->m_dtd is parser->m_isParamEntity but it will be set to |
| 1077 | + // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all). |
| 1078 | + parser->m_dtd = NULL; |
| 1079 | + } |
1071 | 1080 | XML_ParserFree(parser); |
1072 | 1081 | return NULL; |
1073 | 1082 | } |
@@ -3011,16 +3020,16 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, |
3011 | 3020 | int len; |
3012 | 3021 | const char *rawName; |
3013 | 3022 | TAG *tag = parser->m_tagStack; |
3014 | | - parser->m_tagStack = tag->parent; |
3015 | | - tag->parent = parser->m_freeTagList; |
3016 | | - parser->m_freeTagList = tag; |
3017 | 3023 | rawName = s + enc->minBytesPerChar * 2; |
3018 | 3024 | len = XmlNameLength(enc, rawName); |
3019 | 3025 | if (len != tag->rawNameLength |
3020 | 3026 | || memcmp(tag->rawName, rawName, len) != 0) { |
3021 | 3027 | *eventPP = rawName; |
3022 | 3028 | return XML_ERROR_TAG_MISMATCH; |
3023 | 3029 | } |
| 3030 | + parser->m_tagStack = tag->parent; |
| 3031 | + tag->parent = parser->m_freeTagList; |
| 3032 | + parser->m_freeTagList = tag; |
3024 | 3033 | --parser->m_tagLevel; |
3025 | 3034 | if (parser->m_endElementHandler) { |
3026 | 3035 | const XML_Char *localPart; |
@@ -4975,10 +4984,10 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, |
4975 | 4984 | parser->m_handlerArg, parser->m_declElementType->name, |
4976 | 4985 | parser->m_declAttributeId->name, parser->m_declAttributeType, 0, |
4977 | 4986 | role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); |
4978 | | - poolClear(&parser->m_tempPool); |
4979 | 4987 | handleDefault = XML_FALSE; |
4980 | 4988 | } |
4981 | 4989 | } |
| 4990 | + poolClear(&parser->m_tempPool); |
4982 | 4991 | break; |
4983 | 4992 | case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: |
4984 | 4993 | case XML_ROLE_FIXED_ATTRIBUTE_VALUE: |
@@ -5386,7 +5395,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, |
5386 | 5395 | * |
5387 | 5396 | * If 'standalone' is false, the DTD must have no |
5388 | 5397 | * parameter entities or we wouldn't have passed the outer |
5389 | | - * 'if' statement. That measn the only entity in the hash |
| 5398 | + * 'if' statement. That means the only entity in the hash |
5390 | 5399 | * table is the external subset name "#" which cannot be |
5391 | 5400 | * given as a parameter entity name in XML syntax, so the |
5392 | 5401 | * lookup must have returned NULL and we don't even reach |
@@ -5798,19 +5807,27 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, |
5798 | 5807 |
|
5799 | 5808 | if (result != XML_ERROR_NONE) |
5800 | 5809 | return result; |
5801 | | - else if (textEnd != next |
5802 | | - && parser->m_parsingStatus.parsing == XML_SUSPENDED) { |
| 5810 | + |
| 5811 | + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { |
5803 | 5812 | entity->processed = (int)(next - (const char *)entity->textPtr); |
5804 | 5813 | return result; |
5805 | | - } else { |
| 5814 | + } |
| 5815 | + |
5806 | 5816 | #ifdef XML_DTD |
5807 | | - entityTrackingOnClose(parser, entity, __LINE__); |
| 5817 | + entityTrackingOnClose(parser, entity, __LINE__); |
5808 | 5818 | #endif |
5809 | | - entity->open = XML_FALSE; |
5810 | | - parser->m_openInternalEntities = openEntity->next; |
5811 | | - /* put openEntity back in list of free instances */ |
5812 | | - openEntity->next = parser->m_freeInternalEntities; |
5813 | | - parser->m_freeInternalEntities = openEntity; |
| 5819 | + entity->open = XML_FALSE; |
| 5820 | + parser->m_openInternalEntities = openEntity->next; |
| 5821 | + /* put openEntity back in list of free instances */ |
| 5822 | + openEntity->next = parser->m_freeInternalEntities; |
| 5823 | + parser->m_freeInternalEntities = openEntity; |
| 5824 | + |
| 5825 | + // If there are more open entities we want to stop right here and have the |
| 5826 | + // upcoming call to XML_ResumeParser continue with entity content, or it would |
| 5827 | + // be ignored altogether. |
| 5828 | + if (parser->m_openInternalEntities != NULL |
| 5829 | + && parser->m_parsingStatus.parsing == XML_SUSPENDED) { |
| 5830 | + return XML_ERROR_NONE; |
5814 | 5831 | } |
5815 | 5832 |
|
5816 | 5833 | #ifdef XML_DTD |
|
0 commit comments