| OLD | NEW |
| (Empty) | |
| 1 diff --git a/third_party/libxml/src/entities.c b/third_party/libxml/src/entities
.c |
| 2 index 64808ff64d6a..2851e2d43113 100644 |
| 3 --- a/entities.c |
| 4 +++ b/entities.c |
| 5 @@ -159,6 +159,7 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int ty
pe, |
| 6 memset(ret, 0, sizeof(xmlEntity)); |
| 7 ret->type = XML_ENTITY_DECL; |
| 8 ret->checked = 0; |
| 9 + ret->guard = XML_ENTITY_NOT_BEING_CHECKED; |
| 10 |
| 11 /* |
| 12 * fill the structure. |
| 13 @@ -931,6 +932,7 @@ xmlCopyEntity(xmlEntityPtr ent) { |
| 14 cur->orig = xmlStrdup(ent->orig); |
| 15 if (ent->URI != NULL) |
| 16 cur->URI = xmlStrdup(ent->URI); |
| 17 + cur->guard = 0; |
| 18 return(cur); |
| 19 } |
| 20 |
| 21 diff --git a/third_party/libxml/src/include/libxml/entities.h b/third_party/libx
ml/src/include/libxml/entities.h |
| 22 index 47b4573eba65..012efab294cb 100644 |
| 23 --- a/include/libxml/entities.h |
| 24 +++ b/include/libxml/entities.h |
| 25 @@ -35,8 +35,13 @@ typedef enum { |
| 26 * and the linkind data needed for the linking in the hash table. |
| 27 */ |
| 28 |
| 29 +typedef enum { |
| 30 + XML_ENTITY_NOT_BEING_CHECKED, |
| 31 + XML_ENTITY_BEING_CHECKED /* entity check is in progress */ |
| 32 +} xmlEntityRecursionGuard; |
| 33 + |
| 34 struct _xmlEntity { |
| 35 - void *_private; /* application data */ |
| 36 + void *_private; /* application data */ |
| 37 xmlElementType type; /* XML_ENTITY_DECL, must be second ! */ |
| 38 const xmlChar *name; /* Entity name */ |
| 39 struct _xmlNode *children; /* First child link */ |
| 40 @@ -56,10 +61,11 @@ struct _xmlEntity { |
| 41 struct _xmlEntity *nexte; /* unused */ |
| 42 const xmlChar *URI; /* the full URI as computed */ |
| 43 int owner; /* does the entity own the childrens */ |
| 44 - int checked; /* was the entity content checke
d */ |
| 45 - /* this is also used to count entities |
| 46 - * references done from that entity |
| 47 - * and if it contains '<' */ |
| 48 + int checked; /* was the entity content checked and */ |
| 49 + /* l.o. bit: replacement contains '<' */ |
| 50 + /* remaining bits: one plus count of */ |
| 51 + /* entity references from this entity *
/ |
| 52 + xmlEntityRecursionGuard guard; |
| 53 }; |
| 54 |
| 55 /* |
| 56 diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c |
| 57 index 53a6b7f0c961..e3136123dca6 100644 |
| 58 --- a/parser.c |
| 59 +++ b/parser.c |
| 60 @@ -137,18 +137,24 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, |
| 61 * This may look absurd but is needed to detect |
| 62 * entities problems |
| 63 */ |
| 64 + if ((ent != NULL) && (ent->guard == XML_ENTITY_BEING_CHECKED)) { |
| 65 + xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); |
| 66 + return (1); |
| 67 + } |
| 68 if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && |
| 69 (ent->content != NULL) && (ent->checked == 0) && |
| 70 (ctxt->errNo != XML_ERR_ENTITY_LOOP)) { |
| 71 unsigned long oldnbent = ctxt->nbentities; |
| 72 xmlChar *rep; |
| 73 |
| 74 + ent->guard = XML_ENTITY_BEING_CHECKED; |
| 75 ent->checked = 1; |
| 76 |
| 77 ++ctxt->depth; |
| 78 rep = xmlStringDecodeEntities(ctxt, ent->content, |
| 79 XML_SUBSTITUTE_REF, 0, 0, 0); |
| 80 --ctxt->depth; |
| 81 + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; |
| 82 if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { |
| 83 ent->content[0] = 0; |
| 84 } |
| 85 @@ -7329,23 +7335,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { |
| 86 * if its replacement text matches the production labeled |
| 87 * content. |
| 88 */ |
| 89 - if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { |
| 90 - ctxt->depth++; |
| 91 - ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content, |
| 92 - user_data, &list); |
| 93 - ctxt->depth--; |
| 94 - |
| 95 - } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { |
| 96 - ctxt->depth++; |
| 97 - ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax, |
| 98 - user_data, ctxt->depth, ent->URI, |
| 99 - ent->ExternalID, &list); |
| 100 - ctxt->depth--; |
| 101 - } else { |
| 102 - ret = XML_ERR_ENTITY_PE_INTERNAL; |
| 103 - xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, |
| 104 - "invalid entity type found\n", NULL); |
| 105 - } |
| 106 + if (ent->guard == XML_ENTITY_BEING_CHECKED) { |
| 107 + ret = XML_ERR_ENTITY_LOOP; |
| 108 + } else { |
| 109 + ent->guard = XML_ENTITY_BEING_CHECKED; |
| 110 + if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { |
| 111 + ctxt->depth++; |
| 112 + ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content, |
| 113 + user_data, &list); |
| 114 + ctxt->depth--; |
| 115 + } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) { |
| 116 + ctxt->depth++; |
| 117 + ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sa
x, |
| 118 + user_data, ctxt->depth, ent->URI
, |
| 119 + ent->ExternalID, &list); |
| 120 + ctxt->depth--; |
| 121 + } else { |
| 122 + ret = XML_ERR_ENTITY_PE_INTERNAL; |
| 123 + xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, |
| 124 + "invalid entity type found\n", NULL); |
| 125 + } |
| 126 + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; |
| 127 + } |
| 128 |
| 129 /* |
| 130 * Store the number of entities needing parsing for this entity |
| 131 @@ -7448,23 +7459,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { |
| 132 else |
| 133 user_data = ctxt->userData; |
| 134 |
| 135 - if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { |
| 136 - ctxt->depth++; |
| 137 - ret = xmlParseBalancedChunkMemoryInternal(ctxt, |
| 138 - ent->content, user_data, NULL); |
| 139 - ctxt->depth--; |
| 140 - } else if (ent->etype == |
| 141 - XML_EXTERNAL_GENERAL_PARSED_ENTITY) { |
| 142 - ctxt->depth++; |
| 143 - ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, |
| 144 - ctxt->sax, user_data, ctxt->depth, |
| 145 - ent->URI, ent->ExternalID, NULL); |
| 146 - ctxt->depth--; |
| 147 - } else { |
| 148 - ret = XML_ERR_ENTITY_PE_INTERNAL; |
| 149 - xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, |
| 150 - "invalid entity type found\n", NULL); |
| 151 - } |
| 152 + if (ent->guard == XML_ENTITY_BEING_CHECKED) { |
| 153 + ret = XML_ERR_ENTITY_LOOP; |
| 154 + } else { |
| 155 + ent->guard = XML_ENTITY_BEING_CHECKED; |
| 156 + if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) { |
| 157 + ctxt->depth++; |
| 158 + ret = xmlParseBalancedChunkMemoryInternal(ctxt, |
| 159 + ent->content, user_data, NULL); |
| 160 + ctxt->depth--; |
| 161 + } else if (ent->etype == |
| 162 + XML_EXTERNAL_GENERAL_PARSED_ENTITY) { |
| 163 + ctxt->depth++; |
| 164 + ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, |
| 165 + ctxt->sax, user_data, ctxt->depth, |
| 166 + ent->URI, ent->ExternalID, NULL); |
| 167 + ctxt->depth--; |
| 168 + } else { |
| 169 + ret = XML_ERR_ENTITY_PE_INTERNAL; |
| 170 + xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR, |
| 171 + "invalid entity type found\n", NULL); |
| 172 + } |
| 173 + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; |
| 174 + } |
| 175 if (ret == XML_ERR_ENTITY_LOOP) { |
| 176 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); |
| 177 return; |
| 178 -- |
| 179 2.12.2.715.g7642488e1d-goog |
| 180 |
| OLD | NEW |