mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-10-26 12:25:09 +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:
parent
f34f184f8e
commit
481d79d44c
@ -4,6 +4,14 @@
|
||||
#include <libxml/tree.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 *
|
||||
xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
|
||||
|
||||
|
12
parser.c
12
parser.c
@ -78,6 +78,7 @@
|
||||
#include "private/buf.h"
|
||||
#include "private/dict.h"
|
||||
#include "private/enc.h"
|
||||
#include "private/entities.h"
|
||||
#include "private/error.h"
|
||||
#include "private/globals.h"
|
||||
#include "private/html.h"
|
||||
@ -7203,7 +7204,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
||||
if (ent == NULL) return;
|
||||
if (!ctxt->wellFormed)
|
||||
return;
|
||||
was_checked = ent->checked;
|
||||
was_checked = ent->flags & XML_ENT_PARSED;
|
||||
|
||||
/* special case of predefined entities */
|
||||
if ((ent->name == NULL) ||
|
||||
@ -7229,8 +7230,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
||||
* far more secure as the parser will only process data coming from
|
||||
* the document entity by default.
|
||||
*/
|
||||
if (((ent->checked == 0) ||
|
||||
((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
|
||||
if (((ent->flags & XML_ENT_PARSED) == 0) &&
|
||||
((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
|
||||
(ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
|
||||
unsigned long oldnbent = ctxt->nbentities, diff;
|
||||
@ -7270,6 +7270,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
||||
"invalid entity type found\n", NULL);
|
||||
}
|
||||
|
||||
ent->flags |= XML_ENT_PARSED;
|
||||
/*
|
||||
* Store the number of entities needing parsing for this entity
|
||||
* content and do checkings
|
||||
@ -7292,9 +7293,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
||||
}
|
||||
|
||||
if ((ret == XML_ERR_OK) && (list != NULL)) {
|
||||
if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
|
||||
(ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
|
||||
(ent->children == NULL)) {
|
||||
if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
|
||||
(ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
|
||||
ent->children = list;
|
||||
/*
|
||||
* 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);
|
||||
goto out;
|
||||
}
|
||||
else if ((ent != NULL) && (ent->children == NULL)) {
|
||||
else if ((ent != NULL) &&
|
||||
((ent->flags & XML_ENT_PARSED) == 0)) {
|
||||
xmlNodePtr temp;
|
||||
|
||||
/* 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,
|
||||
(const xmlChar*)node->content);
|
||||
ent->owner = 1;
|
||||
ent->flags |= XML_ENT_PARSED;
|
||||
temp = ent->children;
|
||||
while (temp) {
|
||||
temp->parent = (xmlNodePtr)ent;
|
||||
@ -1607,7 +1609,8 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
||||
node = xmlNewReference(doc, val);
|
||||
if (node == NULL)
|
||||
goto out;
|
||||
if ((ent != NULL) && (ent->children == NULL)) {
|
||||
if ((ent != NULL) &&
|
||||
((ent->flags & XML_ENT_PARSED) == 0)) {
|
||||
xmlNodePtr temp;
|
||||
|
||||
/* Set to non-NULL value to avoid recursion. */
|
||||
@ -1615,6 +1618,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
||||
ent->children = xmlStringGetNodeList(doc,
|
||||
(const xmlChar*)node->content);
|
||||
ent->owner = 1;
|
||||
ent->flags |= XML_ENT_PARSED;
|
||||
temp = ent->children;
|
||||
while (temp) {
|
||||
temp->parent = (xmlNodePtr)ent;
|
||||
|
Loading…
Reference in New Issue
Block a user