mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-12-25 23:21:26 +03:00
fixed xmlSetProp and al. when the node passed is not an element. fixed
* tree.c: fixed xmlSetProp and al. when the node passed is not an element. * relaxng.c: fixed bugs 7.3 (though not complete) and memory leaks found 373 test schemas: 369 success 4 failures found 529 test instances: 525 success 4 failures * check-relaxng-test-suite.py: added memory debug reporting Daniel
This commit is contained in:
parent
c64b8e984c
commit
3ebc7d43f7
@ -1,3 +1,12 @@
|
||||
Mon Feb 24 18:14:16 CET 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* tree.c: fixed xmlSetProp and al. when the node passed is not an
|
||||
element.
|
||||
* relaxng.c: fixed bugs 7.3 (though not complete) and memory leaks
|
||||
found 373 test schemas: 369 success 4 failures
|
||||
found 529 test instances: 525 success 4 failures
|
||||
* check-relaxng-test-suite.py: added memory debug reporting
|
||||
|
||||
Mon Feb 24 12:41:54 CET 2003 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* uri.c parser.c: some warning removal on Igor's patch
|
||||
|
@ -7,6 +7,8 @@ import StringIO
|
||||
sys.path.append("python")
|
||||
import libxml2
|
||||
|
||||
# Memory debug specific
|
||||
libxml2.debugMemory(1)
|
||||
debug = 0
|
||||
|
||||
#
|
||||
@ -97,6 +99,7 @@ def handle_valid(node, schema):
|
||||
nb_instances_failed = nb_instances_failed + 1
|
||||
else:
|
||||
nb_instances_success = nb_instances_success + 1
|
||||
doc.freeDoc()
|
||||
|
||||
#
|
||||
# handle an invalid instance
|
||||
@ -136,6 +139,7 @@ def handle_invalid(node, schema):
|
||||
nb_instances_failed = nb_instances_failed + 1
|
||||
else:
|
||||
nb_instances_success = nb_instances_success + 1
|
||||
doc.freeDoc()
|
||||
|
||||
#
|
||||
# handle an incorrect test
|
||||
@ -364,3 +368,14 @@ print "\nTOTAL:\nfound %d test schemas: %d success %d failures" % (
|
||||
nb_schemas_tests, nb_schemas_success, nb_schemas_failed)
|
||||
print "found %d test instances: %d success %d failures" % (
|
||||
nb_instances_tests, nb_instances_success, nb_instances_failed)
|
||||
|
||||
testsuite.freeDoc()
|
||||
|
||||
# Memory debug specific
|
||||
libxml2.relaxNGCleanupTypes()
|
||||
libxml2.cleanupParser()
|
||||
if libxml2.debugMemory(1) == 0:
|
||||
print "OK"
|
||||
else:
|
||||
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
|
||||
libxml2.dumpMemory()
|
||||
|
313
relaxng.c
313
relaxng.c
@ -309,6 +309,7 @@ struct _xmlRelaxNGDocument {
|
||||
xmlRelaxNGPtr schema; /* the schema */
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Preliminary type checking interfaces *
|
||||
@ -969,7 +970,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *URL,
|
||||
*/
|
||||
doc = xmlRelaxNGCleanupDoc(ctxt, doc);
|
||||
if (doc == NULL) {
|
||||
/* xmlFreeDoc(ctxt->include); */
|
||||
ctxt->inc = NULL;
|
||||
return(NULL);
|
||||
}
|
||||
@ -988,7 +988,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *URL,
|
||||
ctxt->error(ctxt->userData,
|
||||
"xmlRelaxNG: included document is empty %s\n", URL);
|
||||
ctxt->nbErrors++;
|
||||
xmlFreeDoc(doc);
|
||||
return (NULL);
|
||||
}
|
||||
if (!IS_RELAXNG(root, "grammar")) {
|
||||
@ -997,7 +996,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *URL,
|
||||
"xmlRelaxNG: included document %s root is not a grammar\n",
|
||||
URL);
|
||||
ctxt->nbErrors++;
|
||||
xmlFreeDoc(doc);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -1248,7 +1246,6 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *URL,
|
||||
*/
|
||||
doc = xmlRelaxNGCleanupDoc(ctxt, doc);
|
||||
if (doc == NULL) {
|
||||
xmlFreeDoc(ctxt->document);
|
||||
ctxt->doc = NULL;
|
||||
return(NULL);
|
||||
}
|
||||
@ -2052,11 +2049,14 @@ xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
|
||||
return(def);
|
||||
}
|
||||
|
||||
static const xmlChar *invalidName = BAD_CAST "\1";
|
||||
|
||||
/**
|
||||
* xmlRelaxNGCompareElemDefLists:
|
||||
* @ctxt: a Relax-NG parser context
|
||||
* @defs1: the first list of element defs
|
||||
* @defs2: the second list of element defs
|
||||
* xmlRelaxNGCompareNameClasses:
|
||||
* @defs1: the first element/attribute defs
|
||||
* @defs2: the second element/attribute defs
|
||||
* @name: the restriction on the name
|
||||
* @ns: the restriction on the namespace
|
||||
*
|
||||
* Compare the 2 lists of element definitions. The comparison is
|
||||
* that if both lists do not accept the same QNames, it returns 1
|
||||
@ -2065,6 +2065,103 @@ xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
|
||||
* Returns 1 disttinct, 0 if equal
|
||||
*/
|
||||
static int
|
||||
xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
|
||||
xmlRelaxNGDefinePtr def2) {
|
||||
int ret = 1;
|
||||
xmlNode node;
|
||||
xmlNs ns;
|
||||
xmlRelaxNGValidCtxt ctxt;
|
||||
ctxt.flags = FLAGS_IGNORABLE;
|
||||
|
||||
if ((def1->type == XML_RELAXNG_ELEMENT) ||
|
||||
(def1->type == XML_RELAXNG_ATTRIBUTE)) {
|
||||
if (def2->type == XML_RELAXNG_TEXT)
|
||||
return(1);
|
||||
if (def1->name != NULL) {
|
||||
node.name = def1->name;
|
||||
} else {
|
||||
node.name = invalidName;
|
||||
}
|
||||
node.ns = &ns;
|
||||
if (def1->ns != NULL) {
|
||||
if (def1->ns[0] == 0) {
|
||||
node.ns = NULL;
|
||||
} else {
|
||||
ns.href = def1->ns;
|
||||
}
|
||||
} else {
|
||||
ns.href = invalidName;
|
||||
}
|
||||
if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
|
||||
if (def1->nameClass != NULL) {
|
||||
ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
} else if (def1->type == XML_RELAXNG_TEXT) {
|
||||
if (def2->type == XML_RELAXNG_TEXT)
|
||||
return(0);
|
||||
return(1);
|
||||
} else if (def1->type == XML_RELAXNG_EXCEPT) {
|
||||
xmlRelaxNGDefinePtr tmp = def1->content;
|
||||
TODO
|
||||
ret = 0;
|
||||
} else {
|
||||
TODO
|
||||
ret = 0;
|
||||
}
|
||||
if (ret == 0)
|
||||
return(ret);
|
||||
if ((def2->type == XML_RELAXNG_ELEMENT) ||
|
||||
(def2->type == XML_RELAXNG_ATTRIBUTE)) {
|
||||
if (def2->name != NULL) {
|
||||
node.name = def2->name;
|
||||
} else {
|
||||
node.name = invalidName;
|
||||
}
|
||||
node.ns = &ns;
|
||||
if (def2->ns != NULL) {
|
||||
if (def2->ns[0] == 0) {
|
||||
node.ns = NULL;
|
||||
} else {
|
||||
ns.href = def2->ns;
|
||||
}
|
||||
} else {
|
||||
ns.href = invalidName;
|
||||
}
|
||||
if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
|
||||
if (def2->nameClass != NULL) {
|
||||
ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
TODO
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGCompareElemDefLists:
|
||||
* @ctxt: a Relax-NG parser context
|
||||
* @defs1: the first list of element/attribute defs
|
||||
* @defs2: the second list of element/attribute defs
|
||||
*
|
||||
* Compare the 2 lists of element or attribute definitions. The comparison
|
||||
* is that if both lists do not accept the same QNames, it returns 1
|
||||
* If the 2 lists can accept the same QName the comparison returns 0
|
||||
*
|
||||
* Returns 1 disttinct, 0 if equal
|
||||
*/
|
||||
static int
|
||||
xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
|
||||
xmlRelaxNGDefinePtr *def1,
|
||||
xmlRelaxNGDefinePtr *def2) {
|
||||
@ -2076,16 +2173,8 @@ xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
|
||||
return(1);
|
||||
while (*def1 != NULL) {
|
||||
while ((*def2) != NULL) {
|
||||
if ((*def1)->name == NULL) {
|
||||
if (xmlStrEqual((*def2)->ns, (*def1)->ns))
|
||||
return(0);
|
||||
} else if ((*def2)->name == NULL) {
|
||||
if (xmlStrEqual((*def2)->ns, (*def1)->ns))
|
||||
return(0);
|
||||
} else if (xmlStrEqual((*def1)->name, (*def2)->name)) {
|
||||
if (xmlStrEqual((*def2)->ns, (*def1)->ns))
|
||||
return(0);
|
||||
}
|
||||
if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
|
||||
return(0);
|
||||
def2++;
|
||||
}
|
||||
def2 = basedef2;
|
||||
@ -4656,6 +4745,9 @@ xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt) {
|
||||
if (ctxt->documents != NULL)
|
||||
xmlHashFree(ctxt->documents, (xmlHashDeallocator)
|
||||
xmlRelaxNGFreeDocument);
|
||||
if (ctxt->includes != NULL)
|
||||
xmlHashFree(ctxt->includes, (xmlHashDeallocator)
|
||||
xmlRelaxNGFreeInclude);
|
||||
if (ctxt->docTab != NULL)
|
||||
xmlFree(ctxt->docTab);
|
||||
if (ctxt->incTab != NULL)
|
||||
@ -4912,6 +5004,8 @@ xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root) {
|
||||
delete = cur;
|
||||
goto skip_children;
|
||||
}
|
||||
if (ns != NULL)
|
||||
xmlFree(ns);
|
||||
xmlFree(URL);
|
||||
cur->_private = docu;
|
||||
} else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
|
||||
@ -5311,11 +5405,14 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
|
||||
ctxt->error(ctxt->userData, "xmlRelaxNGParse: %s is empty\n",
|
||||
ctxt->URL);
|
||||
ctxt->nbErrors++;
|
||||
xmlFreeDoc(doc);
|
||||
return (NULL);
|
||||
}
|
||||
ret = xmlRelaxNGParseDocument(ctxt, root);
|
||||
if (ret == NULL)
|
||||
if (ret == NULL) {
|
||||
xmlFreeDoc(doc);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the ref/defines links
|
||||
@ -5345,6 +5442,7 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
|
||||
ctxt->document = NULL;
|
||||
ret->documents = ctxt->documents;
|
||||
ctxt->documents = NULL;
|
||||
|
||||
ret->includes = ctxt->includes;
|
||||
ctxt->includes = NULL;
|
||||
ret->defNr = ctxt->defNr;
|
||||
@ -6221,96 +6319,6 @@ xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGValidateTryPermutation:
|
||||
* @ctxt: a Relax-NG validation context
|
||||
* @groups: the array of groups
|
||||
* @nbgroups: the number of groups in the array
|
||||
* @array: the permutation to try
|
||||
* @len: the size of the set
|
||||
*
|
||||
* Try to validate a permutation for the group of definitions.
|
||||
*
|
||||
* Returns 0 if the validation succeeded or an error code.
|
||||
*/
|
||||
static int
|
||||
xmlRelaxNGValidateTryPermutation(xmlRelaxNGValidCtxtPtr ctxt,
|
||||
xmlRelaxNGDefinePtr rule,
|
||||
xmlNodePtr *array, int len) {
|
||||
int i, ret;
|
||||
|
||||
if (len > 0) {
|
||||
/*
|
||||
* One only need the next pointer set-up to do the validation
|
||||
*/
|
||||
for (i = 0;i < (len - 1);i++)
|
||||
array[i]->next = array[i + 1];
|
||||
array[i]->next = NULL;
|
||||
|
||||
/*
|
||||
* Now try to validate the sequence
|
||||
*/
|
||||
ctxt->state->seq = array[0];
|
||||
ret = xmlRelaxNGValidateDefinition(ctxt, rule);
|
||||
} else {
|
||||
ctxt->state->seq = NULL;
|
||||
ret = xmlRelaxNGValidateDefinition(ctxt, rule);
|
||||
}
|
||||
|
||||
/*
|
||||
* the sequence must be fully consumed
|
||||
*/
|
||||
if (ctxt->state->seq != NULL)
|
||||
return(-1);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGValidateWalkPermutations:
|
||||
* @ctxt: a Relax-NG validation context
|
||||
* @groups: the array of groups
|
||||
* @nbgroups: the number of groups in the array
|
||||
* @nodes: the set of nodes
|
||||
* @array: the current state of the parmutation
|
||||
* @len: the size of the set
|
||||
* @level: a pointer to the level variable
|
||||
* @k: the index in the array to fill
|
||||
*
|
||||
* Validate a set of nodes for a groups of definitions, will try the
|
||||
* full set of permutations
|
||||
*
|
||||
* Returns 0 if the validation succeeded or an error code.
|
||||
*/
|
||||
static int
|
||||
xmlRelaxNGValidateWalkPermutations(xmlRelaxNGValidCtxtPtr ctxt,
|
||||
xmlRelaxNGDefinePtr rule, xmlNodePtr *nodes,
|
||||
xmlNodePtr *array, int len,
|
||||
int *level, int k) {
|
||||
int i, ret;
|
||||
|
||||
if ((k >= 0) && (k < len))
|
||||
array[k] = nodes[*level];
|
||||
*level = *level + 1;
|
||||
if (*level == len) {
|
||||
ret = xmlRelaxNGValidateTryPermutation(ctxt, rule, array, len);
|
||||
if (ret == 0)
|
||||
return(0);
|
||||
} else {
|
||||
for (i = 0;i < len;i++) {
|
||||
if (array[i] == NULL) {
|
||||
ret = xmlRelaxNGValidateWalkPermutations(ctxt, rule,
|
||||
nodes, array, len, level, i);
|
||||
if (ret == 0)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
*level = *level - 1;
|
||||
array[k] = NULL;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGNodeMatchesList:
|
||||
* @node: the node
|
||||
@ -6355,91 +6363,6 @@ xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr *list) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGValidatePartGroup:
|
||||
* @ctxt: a Relax-NG validation context
|
||||
* @groups: the array of groups
|
||||
* @nbgroups: the number of groups in the array
|
||||
* @nodes: the set of nodes
|
||||
* @len: the size of the set of nodes
|
||||
*
|
||||
* Validate a set of nodes for a groups of definitions
|
||||
*
|
||||
* Returns 0 if the validation succeeded or an error code.
|
||||
*/
|
||||
static int
|
||||
xmlRelaxNGValidatePartGroup(xmlRelaxNGValidCtxtPtr ctxt,
|
||||
xmlRelaxNGInterleaveGroupPtr *groups,
|
||||
int nbgroups, xmlNodePtr *nodes, int len) {
|
||||
int level, ret = -1, i, j, k, top_j, max_j;
|
||||
xmlNodePtr *array = NULL, *list, oldseq;
|
||||
xmlRelaxNGInterleaveGroupPtr group;
|
||||
|
||||
list = (xmlNodePtr *) xmlMalloc(len * sizeof(xmlNodePtr));
|
||||
if (list == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
array = (xmlNodePtr *) xmlMalloc(len * sizeof(xmlNodePtr));
|
||||
if (array == NULL) {
|
||||
xmlFree(list);
|
||||
return(-1);
|
||||
}
|
||||
memset(array, 0, len * sizeof(xmlNodePtr));
|
||||
|
||||
/*
|
||||
* Partition the elements and validate the subsets.
|
||||
*/
|
||||
oldseq = ctxt->state->seq;
|
||||
max_j = -1;
|
||||
for (i = 0;i < nbgroups;i++) {
|
||||
group = groups[i];
|
||||
if (group == NULL)
|
||||
continue;
|
||||
k = 0;
|
||||
top_j = -1;
|
||||
for (j = 0;j < len;j++) {
|
||||
if (nodes[j] == NULL)
|
||||
continue;
|
||||
if (xmlRelaxNGNodeMatchesList(nodes[j], group->defs)) {
|
||||
list[k++] = nodes[j];
|
||||
nodes[j] = NULL;
|
||||
top_j = j;
|
||||
}
|
||||
}
|
||||
if (top_j > max_j)
|
||||
max_j = top_j;
|
||||
ctxt->state->seq = oldseq;
|
||||
if (k > 1) {
|
||||
memset(array, 0, k * sizeof(xmlNodePtr));
|
||||
level = -1;
|
||||
ret = xmlRelaxNGValidateWalkPermutations(ctxt, group->rule,
|
||||
list, array, k, &level, -1);
|
||||
} else {
|
||||
ret = xmlRelaxNGValidateTryPermutation(ctxt, group->rule, list, k);
|
||||
}
|
||||
if (ret != 0) {
|
||||
ctxt->state->seq = oldseq;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0;j < max_j;j++) {
|
||||
if (nodes[j] != NULL) {
|
||||
TODO /* problem, one of the nodes didn't got a match */
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
if (max_j + 1 < len)
|
||||
ctxt->state->seq = nodes[max_j + 1];
|
||||
else
|
||||
ctxt->state->seq = NULL;
|
||||
}
|
||||
|
||||
xmlFree(list);
|
||||
xmlFree(array);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlRelaxNGValidateInterleave:
|
||||
* @ctxt: a Relax-NG validation context
|
||||
@ -6455,7 +6378,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
|
||||
int ret = 0, i, nbgroups, left;
|
||||
xmlRelaxNGPartitionPtr partitions;
|
||||
xmlRelaxNGInterleaveGroupPtr group = NULL;
|
||||
xmlNodePtr cur, start, last, lastchg = NULL, lastelem;
|
||||
xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
|
||||
xmlNodePtr *list = NULL, *lasts = NULL;
|
||||
|
||||
if (define->data != NULL) {
|
||||
|
4
tree.c
4
tree.c
@ -1402,6 +1402,8 @@ xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
|
||||
#endif
|
||||
return(NULL);
|
||||
}
|
||||
if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
|
||||
return(NULL);
|
||||
|
||||
/*
|
||||
* Allocate a new property and fill the fields.
|
||||
@ -5699,7 +5701,7 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
|
||||
xmlAttrPtr prop;
|
||||
xmlDocPtr doc;
|
||||
|
||||
if ((node == NULL) || (name == NULL))
|
||||
if ((node == NULL) || (name == NULL) || (node->type != XML_ELEMENT_NODE))
|
||||
return(NULL);
|
||||
doc = node->doc;
|
||||
prop = node->properties;
|
||||
|
Loading…
Reference in New Issue
Block a user