mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
entities: Add XML_ENT_PARSED flag
To check whether an entity was already parsed, the code previously tested whether "checked" was non-zero or "children" was non-null. The "children" check could be unreliable because an empty entity also results in an empty (NULL) node list. Use a separate flag to make this check more reliable.
This commit is contained in:
@@ -4,6 +4,14 @@
|
|||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <libxml/xmlstring.h>
|
#include <libxml/xmlstring.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entity flags
|
||||||
|
*
|
||||||
|
* XML_ENT_PARSED: The entity was parsed and `children` points to the
|
||||||
|
* content.
|
||||||
|
*/
|
||||||
|
#define XML_ENT_PARSED (1<<0)
|
||||||
|
|
||||||
XML_HIDDEN xmlChar *
|
XML_HIDDEN xmlChar *
|
||||||
xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
|
xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
|
||||||
|
|
||||||
|
|||||||
12
parser.c
12
parser.c
@@ -78,6 +78,7 @@
|
|||||||
#include "private/buf.h"
|
#include "private/buf.h"
|
||||||
#include "private/dict.h"
|
#include "private/dict.h"
|
||||||
#include "private/enc.h"
|
#include "private/enc.h"
|
||||||
|
#include "private/entities.h"
|
||||||
#include "private/error.h"
|
#include "private/error.h"
|
||||||
#include "private/globals.h"
|
#include "private/globals.h"
|
||||||
#include "private/html.h"
|
#include "private/html.h"
|
||||||
@@ -7203,7 +7204,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
|||||||
if (ent == NULL) return;
|
if (ent == NULL) return;
|
||||||
if (!ctxt->wellFormed)
|
if (!ctxt->wellFormed)
|
||||||
return;
|
return;
|
||||||
was_checked = ent->checked;
|
was_checked = ent->flags & XML_ENT_PARSED;
|
||||||
|
|
||||||
/* special case of predefined entities */
|
/* special case of predefined entities */
|
||||||
if ((ent->name == NULL) ||
|
if ((ent->name == NULL) ||
|
||||||
@@ -7229,8 +7230,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
|||||||
* far more secure as the parser will only process data coming from
|
* far more secure as the parser will only process data coming from
|
||||||
* the document entity by default.
|
* the document entity by default.
|
||||||
*/
|
*/
|
||||||
if (((ent->checked == 0) ||
|
if (((ent->flags & XML_ENT_PARSED) == 0) &&
|
||||||
((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
|
|
||||||
((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
|
((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
|
||||||
(ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
|
(ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
|
||||||
unsigned long oldnbent = ctxt->nbentities, diff;
|
unsigned long oldnbent = ctxt->nbentities, diff;
|
||||||
@@ -7270,6 +7270,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
|||||||
"invalid entity type found\n", NULL);
|
"invalid entity type found\n", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ent->flags |= XML_ENT_PARSED;
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@@ -7292,9 +7293,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((ret == XML_ERR_OK) && (list != NULL)) {
|
if ((ret == XML_ERR_OK) && (list != NULL)) {
|
||||||
if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
|
if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
|
||||||
(ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
|
(ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
|
||||||
(ent->children == NULL)) {
|
|
||||||
ent->children = list;
|
ent->children = list;
|
||||||
/*
|
/*
|
||||||
* Prune it directly in the generated document
|
* Prune it directly in the generated document
|
||||||
|
|||||||
8
tree.c
8
tree.c
@@ -1411,7 +1411,8 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
|
|||||||
if (val != NULL) xmlFree(val);
|
if (val != NULL) xmlFree(val);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else if ((ent != NULL) && (ent->children == NULL)) {
|
else if ((ent != NULL) &&
|
||||||
|
((ent->flags & XML_ENT_PARSED) == 0)) {
|
||||||
xmlNodePtr temp;
|
xmlNodePtr temp;
|
||||||
|
|
||||||
/* Set to non-NULL value to avoid recursion. */
|
/* Set to non-NULL value to avoid recursion. */
|
||||||
@@ -1419,6 +1420,7 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
|
|||||||
ent->children = xmlStringGetNodeList(doc,
|
ent->children = xmlStringGetNodeList(doc,
|
||||||
(const xmlChar*)node->content);
|
(const xmlChar*)node->content);
|
||||||
ent->owner = 1;
|
ent->owner = 1;
|
||||||
|
ent->flags |= XML_ENT_PARSED;
|
||||||
temp = ent->children;
|
temp = ent->children;
|
||||||
while (temp) {
|
while (temp) {
|
||||||
temp->parent = (xmlNodePtr)ent;
|
temp->parent = (xmlNodePtr)ent;
|
||||||
@@ -1607,7 +1609,8 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
|||||||
node = xmlNewReference(doc, val);
|
node = xmlNewReference(doc, val);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
if ((ent != NULL) && (ent->children == NULL)) {
|
if ((ent != NULL) &&
|
||||||
|
((ent->flags & XML_ENT_PARSED) == 0)) {
|
||||||
xmlNodePtr temp;
|
xmlNodePtr temp;
|
||||||
|
|
||||||
/* Set to non-NULL value to avoid recursion. */
|
/* Set to non-NULL value to avoid recursion. */
|
||||||
@@ -1615,6 +1618,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
|||||||
ent->children = xmlStringGetNodeList(doc,
|
ent->children = xmlStringGetNodeList(doc,
|
||||||
(const xmlChar*)node->content);
|
(const xmlChar*)node->content);
|
||||||
ent->owner = 1;
|
ent->owner = 1;
|
||||||
|
ent->flags |= XML_ENT_PARSED;
|
||||||
temp = ent->children;
|
temp = ent->children;
|
||||||
while (temp) {
|
while (temp) {
|
||||||
temp->parent = (xmlNodePtr)ent;
|
temp->parent = (xmlNodePtr)ent;
|
||||||
|
|||||||
Reference in New Issue
Block a user