summaryrefslogtreecommitdiff
path: root/relaxng.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2003-08-27 14:15:15 +0000
committerDaniel Veillard <veillard@src.gnome.org>2003-08-27 14:15:15 +0000
commit1ac24d36b12487995b659a8fc23a02b9460edb36 (patch)
tree689cf6ea7d49cf54e180d9e66dade478b0687398 /relaxng.c
parentaa3cfbd0809378d88bc907742a9ddd27cc49b335 (diff)
downloadlibxml2-1ac24d36b12487995b659a8fc23a02b9460edb36.tar.gz
fixed an error reporting bug in Relax-NG when we end up with multiple
* relaxng.c: fixed an error reporting bug in Relax-NG when we end up with multiple states, select the "best" one. Fix #120682 * result/relaxng/tutor11_2_3.err: small change resulting * xmlschemastypes.c: applied base64 support patch from Anthony Carrico
Diffstat (limited to 'relaxng.c')
-rw-r--r--relaxng.c150
1 files changed, 126 insertions, 24 deletions
diff --git a/relaxng.c b/relaxng.c
index 28d1a606..9c788c2a 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -7786,7 +7786,8 @@ xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
************************************************************************/
static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr defines);
-static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt);
+static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int log);
+static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
/**
* xmlRelaxNGElemPush:
@@ -7944,7 +7945,7 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
}
if (ctxt->state != NULL) {
ctxt->state->seq = NULL;
- ret = xmlRelaxNGValidateElementEnd(ctxt);
+ ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
if (ret != 0) {
ctxt->pstate = -1;
}
@@ -7953,16 +7954,27 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
int tmp = -1, i;
oldflags = ctxt->flags;
- ctxt->flags |= FLAGS_IGNORABLE;
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
ctxt->state->seq = NULL;
- if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
+ if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
- xmlRelaxNGFreeValidState(ctxt, state);
+ break;
+ }
+ }
+ if (tmp != 0) {
+ /*
+ * validation error, log the message for the "best" one
+ */
+ ctxt->flags |= FLAGS_IGNORABLE;
+ xmlRelaxNGLogBestError(ctxt);
+ }
+ for (i = 0; i < ctxt->states->nbState; i++) {
+ xmlRelaxNGFreeValidState(ctxt,
+ ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->states = NULL;
@@ -9302,8 +9314,74 @@ xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
}
/**
+ * xmlRelaxNGBestState:
+ * @ctxt: a Relax-NG validation context
+ *
+ * Find the "best" state in the ctxt->states list of states to report
+ * errors about. I.e. a state with no element left in the child list
+ * or the one with the less attributes left.
+ * This is called only if a falidation error was detected
+ *
+ * Returns the index of the "best" state or -1 in case of error
+ */
+static int
+xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt) {
+ xmlRelaxNGValidStatePtr state;
+ int i, tmp;
+ int best = -1;
+ int value = 1000000;
+
+ if ((ctxt == NULL) || (ctxt->states == NULL) ||
+ (ctxt->states->nbState <= 0))
+ return(-1);
+
+ for (i = 0;i < ctxt->states->nbState;i++) {
+ state = ctxt->states->tabState[i];
+ if (state == NULL)
+ continue;
+ if (state->seq != NULL) {
+ if ((best == -1) || (value > 100000)) {
+ value = 100000;
+ best = i;
+ }
+ } else {
+ tmp = state->nbAttrLeft;
+ if ((best == -1) || (value > tmp)) {
+ value = tmp;
+ best = i;
+ }
+ }
+ }
+ return(best);
+}
+
+/**
+ * xmlRelaxNGLogBestError:
+ * @ctxt: a Relax-NG validation context
+ *
+ * Find the "best" state in the ctxt->states list of states to report
+ * errors about and log it.
+ */
+static void
+xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt) {
+ int best;
+
+ if ((ctxt == NULL) || (ctxt->states == NULL) ||
+ (ctxt->states->nbState <= 0))
+ return;
+
+ best = xmlRelaxNGBestState(ctxt);
+ if ((best >= 0) && (best < ctxt->states->nbState)) {
+ ctxt->state = ctxt->states->tabState[best];
+
+ xmlRelaxNGValidateElementEnd(ctxt, 1);
+ }
+}
+
+/**
* xmlRelaxNGValidateElementEnd:
* @ctxt: a Relax-NG validation context
+ * @log: indicate that error logging should be done
*
* Validate the end of the element, implements check that
* there is nothing left not consumed in the element content
@@ -9312,27 +9390,31 @@ xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
* Returns 0 if the validation succeeded or an error code.
*/
static int
-xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt) {
- int ret = 0, i;
+xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int log) {
+ int i;
xmlRelaxNGValidStatePtr state;
state = ctxt->state;
if (state->seq != NULL) {
state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
if (state->seq != NULL) {
- VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
- state->node->name, state->seq->name);
- ret = -1;
+ if (log) {
+ VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
+ state->node->name, state->seq->name);
+ }
+ return(-1);
}
}
for (i = 0;i < state->nbAttrs;i++) {
if (state->attrs[i] != NULL) {
- VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
- state->attrs[i]->name, state->node->name);
- ret = -1;
+ if (log) {
+ VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
+ state->attrs[i]->name, state->node->name);
+ }
+ return(-1 -i);
}
}
- return(ret);
+ return(0);
}
/**
@@ -9503,16 +9585,26 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (ctxt->states != NULL) {
tmp = -1;
- ctxt->flags |= FLAGS_IGNORABLE;
-
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
ctxt->state->seq = nseq;
- if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
+ if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
- xmlRelaxNGFreeValidState(ctxt, state);
+ break;
+ }
+ }
+ if (tmp != 0) {
+ /*
+ * validation error, log the message for the "best" one
+ */
+ ctxt->flags |= FLAGS_IGNORABLE;
+ xmlRelaxNGLogBestError(ctxt);
+ }
+ for (i = 0; i < ctxt->states->nbState; i++) {
+ xmlRelaxNGFreeValidState(ctxt,
+ ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@@ -9523,7 +9615,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
state = ctxt->state;
ctxt->state->seq = nseq;
if (ret == 0)
- ret = xmlRelaxNGValidateElementEnd(ctxt);
+ ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
xmlRelaxNGFreeValidState(ctxt, state);
}
} else {
@@ -9547,15 +9639,25 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (ctxt->states != NULL) {
tmp = -1;
- ctxt->flags |= FLAGS_IGNORABLE;
-
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
- if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
+ if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
- xmlRelaxNGFreeValidState(ctxt, state);
+ break;
+ }
+ }
+ if (tmp != 0) {
+ /*
+ * validation error, log the message for the "best" one
+ */
+ ctxt->flags |= FLAGS_IGNORABLE;
+ xmlRelaxNGLogBestError(ctxt);
+ }
+ for (i = 0; i < ctxt->states->nbState; i++) {
+ xmlRelaxNGFreeValidState(ctxt,
+ ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@@ -9565,7 +9667,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else {
state = ctxt->state;
if (ret == 0)
- ret = xmlRelaxNGValidateElementEnd(ctxt);
+ ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
xmlRelaxNGFreeValidState(ctxt, state);
}
}