more RelaxNG bug hunting Daniel
* relaxng.c check-relaxng-test-suite.py: more RelaxNG bug hunting
Daniel
diff --git a/relaxng.c b/relaxng.c
index d6f1f17..ac8194c 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2786,6 +2786,16 @@
def = xmlRelaxNGParseInterleave(ctxt, node);
if (def != NULL) {
xmlRelaxNGDefinePtr tmp;
+
+ if ((def->content != NULL) && (def->content->next != NULL)) {
+ tmp = xmlRelaxNGNewDefine(ctxt, node);
+ if (tmp != NULL) {
+ tmp->type = XML_RELAXNG_GROUP;
+ tmp->content = def->content;
+ def->content = tmp;
+ }
+ }
+
tmp = xmlRelaxNGNewDefine(ctxt, node);
if (tmp == NULL)
return(def);
@@ -3235,7 +3245,7 @@
static int
xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes) {
int ret = 0;
- xmlRelaxNGDefinePtr def = NULL;
+ xmlRelaxNGDefinePtr def = NULL, last;
if (nodes == NULL) {
if (ctxt->error != NULL)
@@ -3254,7 +3264,6 @@
ctxt->error(ctxt->userData, "element empty is not empty\n");
ctxt->nbErrors++;
}
- ctxt->grammar->start = def;
} else if (IS_RELAXNG(nodes, "notAllowed")) {
def = xmlRelaxNGNewDefine(ctxt, nodes);
if (def == NULL)
@@ -3266,9 +3275,15 @@
"element notAllowed is not empty\n");
ctxt->nbErrors++;
}
- ctxt->grammar->start = def;
} else {
def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
+ }
+ if (ctxt->grammar->start != NULL) {
+ last = ctxt->grammar->start;
+ while (last->next != NULL)
+ last = last->next;
+ last->next = def;
+ } else {
ctxt->grammar->start = def;
}
nodes = nodes->next;
@@ -3528,14 +3543,24 @@
xmlChar *combine;
int choiceOrInterleave = -1;
int missing = 0;
- xmlRelaxNGDefinePtr cur, last, tmp, tmp2;
+ xmlRelaxNGDefinePtr cur;
- starts = grammar->startList;
- if ((starts == NULL) || (starts->nextHash == NULL))
+ starts = grammar->start;
+ if ((starts == NULL) || (starts->next == NULL))
return;
cur = starts;
while (cur != NULL) {
- combine = xmlGetProp(cur->node, BAD_CAST "combine");
+ if ((cur->node == NULL) || (cur->node->parent == NULL) ||
+ (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
+ combine = NULL;
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Internal error: start element not found\n");
+ ctxt->nbErrors++;
+ } else {
+ combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
+ }
+
if (combine != NULL) {
if (xmlStrEqual(combine, BAD_CAST "choice")) {
if (choiceOrInterleave == -1)
@@ -3546,7 +3571,7 @@
"<start> use both 'choice' and 'interleave'\n");
ctxt->nbErrors++;
}
- } else if (xmlStrEqual(combine, BAD_CAST "choice")) {
+ } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
if (choiceOrInterleave == -1)
choiceOrInterleave = 0;
else if (choiceOrInterleave == 1) {
@@ -3573,7 +3598,7 @@
}
}
- cur = cur->nextHash;
+ cur = cur->next;
}
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,
@@ -3586,36 +3611,31 @@
if (cur == NULL)
return;
if (choiceOrInterleave == 0)
- cur->type = XML_RELAXNG_CHOICE;
- else
cur->type = XML_RELAXNG_INTERLEAVE;
- tmp = starts;
- last = NULL;
- while (tmp != NULL) {
- if (tmp->content != NULL) {
- if (tmp->content->next != NULL) {
- /*
- * we need first to create a wrapper.
- */
- tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
- if (tmp2 == NULL)
- break;
- tmp2->type = XML_RELAXNG_GROUP;
- tmp2->content = tmp->content;
- } else {
- tmp2 = tmp->content;
+ else
+ cur->type = XML_RELAXNG_CHOICE;
+ cur->content = grammar->start;
+ grammar->start = cur;
+ if (choiceOrInterleave == 0) {
+ if (ctxt->interleaves == NULL)
+ ctxt->interleaves = xmlHashCreate(10);
+ if (ctxt->interleaves == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Failed to create interleaves hash table\n");
+ ctxt->nbErrors++;
+ } else {
+ char tmpname[32];
+
+ snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
+ if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) < 0) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Failed to add %s to hash table\n", tmpname);
+ ctxt->nbErrors++;
}
- if (last == NULL) {
- cur->content = tmp2;
- } else {
- last->next = tmp2;
- }
- last = tmp2;
- tmp->content = NULL;
}
- tmp = tmp->nextHash;
}
- starts->content = cur;
}
/**
@@ -3655,6 +3675,17 @@
ctxt->grammar = ret;
xmlRelaxNGParseGrammarContent(ctxt, nodes);
ctxt->grammar = ret;
+ if (ctxt->grammar == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Failed to parse <grammar> content\n");
+ ctxt->nbErrors++;
+ } else if (ctxt->grammar->start == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Element <grammar> has no <start>\n");
+ ctxt->nbErrors++;
+ }
/*
* Apply 4.17 mergingd rules to defines and starts
@@ -3893,6 +3924,7 @@
(!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
(!xmlStrEqual(node->name, BAD_CAST "ref")) &&
(!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
+ (!xmlStrEqual(node->name, BAD_CAST "param")) &&
(!xmlStrEqual(node->name, BAD_CAST "define"))) {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,