Commit cff2546f authored by Daniel Veillard's avatar Daniel Veillard

Cache presence of '<' in entities content

slightly modify how ent->checked is used, and use the lowest bit to
keep the information
parent a3f1e3e5
...@@ -605,7 +605,9 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name) ...@@ -605,7 +605,9 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
} }
ret->owner = 1; ret->owner = 1;
if (ret->checked == 0) { if (ret->checked == 0) {
ret->checked = ctxt->nbentities - oldnbent + 1; ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
ret->checked |= 1;
} }
} }
return(ret); return(ret);
......
...@@ -58,7 +58,8 @@ struct _xmlEntity { ...@@ -58,7 +58,8 @@ struct _xmlEntity {
int owner; /* does the entity own the childrens */ int owner; /* does the entity own the childrens */
int checked; /* was the entity content checked */ int checked; /* was the entity content checked */
/* this is also used to count entites /* this is also used to count entites
* references done from that entity */ * references done from that entity
* and if it contains '<' */
}; };
/* /*
......
...@@ -170,7 +170,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, ...@@ -170,7 +170,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
/* /*
* use the number of parsed entities in the replacement * use the number of parsed entities in the replacement
*/ */
size = ent->checked; size = ent->checked / 2;
/* /*
* The amount of data parsed counting entities size only once * The amount of data parsed counting entities size only once
...@@ -2736,7 +2736,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, ...@@ -2736,7 +2736,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
(ctxt->lastError.code == XML_ERR_INTERNAL_ERROR)) (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
goto int_error; goto int_error;
if (ent != NULL) if (ent != NULL)
ctxt->nbentities += ent->checked; ctxt->nbentities += ent->checked / 2;
if ((ent != NULL) && if ((ent != NULL) &&
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
if (ent->content != NULL) { if (ent->content != NULL) {
...@@ -2787,7 +2787,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, ...@@ -2787,7 +2787,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP) if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
goto int_error; goto int_error;
if (ent != NULL) if (ent != NULL)
ctxt->nbentities += ent->checked; ctxt->nbentities += ent->checked / 2;
if (ent != NULL) { if (ent != NULL) {
if (ent->content == NULL) { if (ent->content == NULL) {
xmlLoadEntityContent(ctxt, ent); xmlLoadEntityContent(ctxt, ent);
...@@ -4050,8 +4050,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { ...@@ -4050,8 +4050,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
rep = xmlStringDecodeEntities(ctxt, ent->content, rep = xmlStringDecodeEntities(ctxt, ent->content,
XML_SUBSTITUTE_REF, 0, 0, 0); XML_SUBSTITUTE_REF, 0, 0, 0);
ent->checked = ctxt->nbentities - oldnbent + 1; ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
if (rep != NULL) { if (rep != NULL) {
if (xmlStrchr(rep, '<'))
ent->checked |= 1;
xmlFree(rep); xmlFree(rep);
rep = NULL; rep = NULL;
} }
...@@ -7217,7 +7219,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ...@@ -7217,7 +7219,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
* Store the number of entities needing parsing for this entity * Store the number of entities needing parsing for this entity
* content and do checkings * content and do checkings
*/ */
ent->checked = ctxt->nbentities - oldnbent + 1; ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
ent->checked |= 1;
if (ret == XML_ERR_ENTITY_LOOP) { if (ret == XML_ERR_ENTITY_LOOP) {
xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
xmlFreeNodeList(list); xmlFreeNodeList(list);
...@@ -7282,9 +7286,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ...@@ -7282,9 +7286,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
list = NULL; list = NULL;
} }
if (ent->checked == 0) if (ent->checked == 0)
ent->checked = 1; ent->checked = 2;
} else if (ent->checked != 1) { } else if (ent->checked != 1) {
ctxt->nbentities += ent->checked; ctxt->nbentities += ent->checked / 2;
} }
/* /*
...@@ -7645,11 +7649,13 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) { ...@@ -7645,11 +7649,13 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
* not contain a <. * not contain a <.
*/ */
else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) && else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
(ent != NULL) && (ent->content != NULL) && (ent != NULL) &&
(ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
(xmlStrchr(ent->content, '<'))) { if ((ent->checked & 1) || ((ent->checked == 0) &&
xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
"'<' in entity '%s' is not allowed in attributes values\n", name); xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
"'<' in entity '%s' is not allowed in attributes values\n", name);
}
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment