Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Unified Diff: third_party/libxml/relaxng.c

Issue 2951008: Update libxml to 2.7.7. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/libxml/relaxng.c
diff --git a/third_party/libxml/relaxng.c b/third_party/libxml/relaxng.c
index 60fdbab9256dcd9dbe5d101c31713fed163ecffa..6dbc499fccbcd59c46020c0cbabeee652747a8ae 100644
--- a/third_party/libxml/relaxng.c
+++ b/third_party/libxml/relaxng.c
@@ -149,6 +149,7 @@ typedef enum {
#define IS_PROCESSED (1 << 5)
#define IS_COMPILABLE (1 << 6)
#define IS_NOT_COMPILABLE (1 << 7)
+#define IS_EXTERNAL_REF (1 << 8)
struct _xmlRelaxNGDefine {
xmlRelaxNGType type; /* the type of definition */
@@ -414,6 +415,7 @@ struct _xmlRelaxNGDocument {
xmlDocPtr doc; /* the associated XML document */
xmlRelaxNGDefinePtr content; /* the definitions */
xmlRelaxNGPtr schema; /* the schema */
+ int externalRef; /* 1 if an external ref */
};
@@ -1006,7 +1008,7 @@ xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
xmlRelaxNGStatesPtr ret;
if ((ctxt != NULL) &&
- (ctxt->freeState != NULL) && (ctxt->freeStatesNr > 0)) {
+ (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
ctxt->freeStatesNr--;
ret = ctxt->freeStates[ctxt->freeStatesNr];
ret->nbState = 0;
@@ -1970,6 +1972,7 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
ret->doc = doc;
ret->href = xmlStrdup(URL);
ret->next = ctxt->documents;
+ ret->externalRef = 1;
ctxt->documents = ret;
/*
@@ -2372,6 +2375,9 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
} else {
node = seq = NULL;
}
+ if ((node == NULL) && (seq == NULL)) {
+ node = ctxt->pnode;
+ }
xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
}
/*
@@ -2849,6 +2855,10 @@ xmlRelaxNGCleanupTypes(void)
* *
************************************************************************/
+/* from automata.c but not exported */
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
+
static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
xmlRelaxNGDefinePtr def);
@@ -3032,6 +3042,17 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+
+ /*
+ * assume identical strings but not same pointer are different
+ * atoms, needed for non-determinism detection
+ * That way if 2 elements with the same name are in a choice
+ * branch the automata is found non-deterministic and
+ * we fallback to the normal validation which does the right
+ * thing of exploring both choices.
+ */
+ xmlAutomataSetFlags(ctxt->am, 1);
+
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
@@ -3063,6 +3084,7 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+ xmlAutomataSetFlags(ctxt->am, 1);
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
@@ -3071,6 +3093,11 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
def->contModel = xmlAutomataCompile(ctxt->am);
if (!xmlRegexpIsDeterminist(def->contModel)) {
+#ifdef DEBUG_COMPILE
+ xmlGenericError(xmlGenericErrorContext,
+ "Content model not determinist %s\n",
+ def->name);
+#endif
/*
* we can only use the automata if it is determinist
*/
@@ -3098,7 +3125,11 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
case XML_RELAXNG_OPTIONAL:{
xmlAutomataStatePtr oldstate = ctxt->state;
- xmlRelaxNGCompile(ctxt, def->content);
+ list = def->content;
+ while (list != NULL) {
+ xmlRelaxNGCompile(ctxt, list);
+ list = list->next;
+ }
xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
break;
}
@@ -3440,6 +3471,9 @@ xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
{
xmlChar *ret, *escape;
+ if (node == NULL)
+ return(NULL);
+
if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
if (ret != NULL) {
@@ -4616,6 +4650,72 @@ xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
}
/**
+ * xmlRelaxNGParseImportRef:
+ * @payload: the parser context
+ * @data: the current grammar
+ * @name: the reference name
+ *
+ * Import import one references into the current grammar
+ */
+static void
+xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) {
+ xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
+ xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
+ int tmp;
+
+ def->dflags |= IS_EXTERNAL_REF;
+
+ tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
+ if (tmp < 0) {
+ xmlRelaxNGDefinePtr prev;
+
+ prev = (xmlRelaxNGDefinePtr)
+ xmlHashLookup(ctxt->grammar->refs, def->name);
+ if (prev == NULL) {
+ if (def->name != NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions '%s'\n",
+ def->name, NULL);
+ } else {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions\n",
+ NULL, NULL);
+ }
+ } else {
+ def->nextHash = prev->nextHash;
+ prev->nextHash = def;
+ }
+ }
+}
+
+/**
+ * xmlRelaxNGParseImportRefs:
+ * @ctxt: the parser context
+ * @grammar: the sub grammar
+ *
+ * Import references from the subgrammar into the current grammar
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
+ xmlRelaxNGGrammarPtr grammar) {
+ if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
+ return(-1);
+ if (grammar->refs == NULL)
+ return(0);
+ if (ctxt->grammar->refs == NULL)
+ ctxt->grammar->refs = xmlHashCreate(10);
+ if (ctxt->grammar->refs == NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Could not create references hash\n", NULL, NULL);
+ return(-1);
+ }
+ xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
+ return(0);
+}
+
+/**
* xmlRelaxNGProcessExternalRef:
* @ctxt: the parser context
* @node: the externlRef node
@@ -4683,6 +4783,8 @@ xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
if ((docu->schema != NULL) &&
(docu->schema->topgrammar != NULL)) {
docu->content = docu->schema->topgrammar->start;
+ if (docu->schema->topgrammar->refs)
+ xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
}
/*
@@ -5267,7 +5369,8 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
} else {
xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
"expecting name, anyName, nsName or choice : got %s\n",
- node->name, NULL);
+ (node == NULL ? (const xmlChar *) "nothing" : node->name),
+ NULL);
return (NULL);
}
if (ret != def) {
@@ -5569,6 +5672,12 @@ xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref,
xmlRelaxNGGrammarPtr grammar;
xmlRelaxNGDefinePtr def, cur;
+ /*
+ * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
+ */
+ if (ref->dflags & IS_EXTERNAL_REF)
+ return;
+
grammar = ctxt->grammar;
if (grammar == NULL) {
xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
@@ -6133,7 +6242,7 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
xmlRelaxNGDefinePtr cur, int flags,
xmlRelaxNGType ptype)
{
- int nflags = flags;
+ int nflags;
xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
while (cur != NULL) {
@@ -6157,6 +6266,16 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
"Found forbidden pattern data/except//ref\n",
NULL, NULL);
}
+ if (cur->content == NULL) {
+ if (cur->type == XML_RELAXNG_PARENTREF)
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for parent refs\n",
+ NULL, NULL);
+ else
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for ref %s\n",
+ (cur->name ? cur->name: BAD_CAST "null"), NULL);
+ }
if (cur->depth > -4) {
cur->depth = -4;
ret = xmlRelaxNGCheckRules(ctxt, cur->content,
@@ -6408,6 +6527,10 @@ xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
if (ptype == XML_RELAXNG_GROUP) {
val = xmlRelaxNGGroupContentType(val, ret);
} else if (ptype == XML_RELAXNG_INTERLEAVE) {
+ /*
+ * TODO: scan complain that tmp is never used, seems on purpose
+ * need double-checking
+ */
tmp = xmlRelaxNGGroupContentType(val, ret);
if (tmp != XML_RELAXNG_CONTENT_ERROR)
tmp = xmlRelaxNGMaxContentType(val, ret);
@@ -6495,6 +6618,9 @@ xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
ctxt);
}
+
+ /* @@@@ */
+
ctxt->grammar = old;
return (ret);
}
@@ -8343,7 +8469,7 @@ xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
ret = -1;
else
ret = 1;
- xmlRelaxNGFreeValidState(ctxt, state);
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
#ifdef DEBUG_PROGRESSIVE
if (ret < 0)
@@ -8812,7 +8938,12 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
}
case XML_RELAXNG_REF:
case XML_RELAXNG_PARENTREF:
- ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ if (define->content == NULL) {
+ VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+ ret = -1;
+ } else {
+ ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ }
break;
default:
TODO ret = -1;
@@ -9319,6 +9450,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
oldstate =
ctxt->states->tabState[ctxt->states->nbState - 1];
ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
+ ctxt->states->nbState--;
}
}
for (j = 0; j < ctxt->states->nbState ; j++) {
@@ -9327,7 +9459,12 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->states = NULL;
if (found == 0) {
- VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ if (cur == NULL) {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
+ (const xmlChar *) "noname");
+ } else {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ }
ret = -1;
ctxt->state = oldstate;
goto done;
@@ -9874,8 +10011,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
- ctxt->states->
- tabState[i]);
+ ctxt->states->tabState[i]);
+ ctxt->states->tabState[i] = NULL;
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@@ -9997,11 +10134,8 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else {
for (j = 0; j < ctxt->states->nbState; j++) {
xmlRelaxNGAddStates(ctxt, res,
- xmlRelaxNGCopyValidState(ctxt,
- ctxt->
- states->
- tabState
- [j]));
+ xmlRelaxNGCopyValidState(ctxt,
+ ctxt->states->tabState[j]));
}
}
oldflags = ctxt->flags;
@@ -10030,10 +10164,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
j++) {
tmp =
xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState
- [j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10067,9 +10198,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else if (ctxt->states != NULL) {
for (j = 0; j < ctxt->states->nbState; j++) {
tmp = xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState[j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10107,8 +10236,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
for (i = base; i < res->nbState; i++)
xmlRelaxNGAddStates(ctxt, states,
xmlRelaxNGCopyValidState
- (ctxt,
- res->tabState[i]));
+ (ctxt, res->tabState[i]));
ctxt->states = states;
}
}
@@ -10630,6 +10758,60 @@ xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
return (ret);
}
+/**
+ * xmlRelaxNGCleanPSVI:
+ * @node: an input element or document
+ *
+ * Call this routine to speed up XPath computation on static documents.
+ * This stamps all the element nodes with the document order
+ * Like for line information, the order is kept in the element->content
+ * field, the value stored is actually - the node number (starting at -1)
+ * to be able to differentiate from line numbers.
+ *
+ * Returns the number of elements found in the document or -1 in case
+ * of error.
+ */
+static void
+xmlRelaxNGCleanPSVI(xmlNodePtr node) {
+ xmlNodePtr cur;
+
+ if ((node == NULL) ||
+ ((node->type != XML_ELEMENT_NODE) &&
+ (node->type != XML_DOCUMENT_NODE) &&
+ (node->type != XML_HTML_DOCUMENT_NODE)))
+ return;
+ if (node->type == XML_ELEMENT_NODE)
+ node->psvi = NULL;
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ cur->psvi = NULL;
+ if (cur->children != NULL) {
+ cur = cur->children;
+ continue;
+ }
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ continue;
+ }
+ do {
+ cur = cur->parent;
+ if (cur == NULL)
+ break;
+ if (cur == node) {
+ cur = NULL;
+ break;
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ break;
+ }
+ } while (cur != NULL);
+ }
+ return;
+}
/************************************************************************
* *
* Validation interfaces *
@@ -10804,6 +10986,11 @@ xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
ret = xmlRelaxNGValidateDocument(ctxt, doc);
/*
+ * Remove all left PSVI
+ */
+ xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
+
+ /*
* TODO: build error codes
*/
if (ret == -1)

Powered by Google App Engine
This is Rietveld 408576698