1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-28 00:21:53 +03:00

removed an unprotedted debug message Aleksi Suhonen put a guard against

* python/libxml.c: removed an unprotedted debug message Aleksi Suhonen
* parser.c: put a guard against infinite document depth, basically
  trying to avoid another kind of DoS attack.
* relaxng.c: some code w.r.t. nameClasses
Daniel
This commit is contained in:
Daniel Veillard
2003-02-03 08:52:58 +00:00
parent fc1a4503fb
commit 3b2e4e1c14
4 changed files with 176 additions and 52 deletions

View File

@ -1,3 +1,10 @@
Mon Feb 3 09:50:26 CET 2003 Daniel Veillard <daniel@veillard.com>
* python/libxml.c: removed an unprotedted debug message Aleksi Suhonen
* parser.c: put a guard against infinite document depth, basically
trying to avoid another kind of DoS attack.
* relaxng.c: some code w.r.t. nameClasses
Sun Feb 2 17:01:43 CET 2003 Daniel Veillard <daniel@veillard.com> Sun Feb 2 17:01:43 CET 2003 Daniel Veillard <daniel@veillard.com>
* test/relaxng/* result/relaxng/*: check all the namespace support * test/relaxng/* result/relaxng/*: check all the namespace support

View File

@ -76,6 +76,14 @@
#include <zlib.h> #include <zlib.h>
#endif #endif
/**
* MAX_DEPTH:
*
* arbitrary depth limit for the XML documents that we allow to
* process. This is not a limitation of the parser but a safety
* boundary feature.
*/
#define MAX_DEPTH 1024
#define XML_PARSER_BIG_BUFFER_SIZE 300 #define XML_PARSER_BIG_BUFFER_SIZE 300
#define XML_PARSER_BUFFER_SIZE 100 #define XML_PARSER_BUFFER_SIZE 100
@ -191,6 +199,18 @@ nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
return (0); return (0);
} }
} }
#ifdef MAX_DEPTH
if (ctxt->nodeNr > MAX_DEPTH) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Excessive depth in document: change MAX_DEPTH = %d\n",
MAX_DEPTH);
ctxt->wellFormed = 0;
ctxt->instate = XML_PARSER_EOF;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
return(0);
}
#endif
ctxt->nodeTab[ctxt->nodeNr] = value; ctxt->nodeTab[ctxt->nodeNr] = value;
ctxt->node = value; ctxt->node = value;
return (ctxt->nodeNr++); return (ctxt->nodeNr++);

View File

@ -2527,7 +2527,9 @@ libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name)) if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
return (NULL); return (NULL);
node = (xmlNodePtr) xmlNewNode(NULL, name); node = (xmlNodePtr) xmlNewNode(NULL, name);
#ifdef DEBUG
printf("NewNode: %s : %p\n", name, (void *) node); printf("NewNode: %s : %p\n", name, (void *) node);
#endif
if (node == NULL) { if (node == NULL) {
Py_INCREF(Py_None); Py_INCREF(Py_None);

199
relaxng.c
View File

@ -123,6 +123,7 @@ struct _xmlRelaxNGDefine {
xmlRelaxNGDefinePtr parent; /* the parent definition, if any */ xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
xmlRelaxNGDefinePtr next; /* list within grouping sequences */ xmlRelaxNGDefinePtr next; /* list within grouping sequences */
xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */ xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */
xmlRelaxNGDefinePtr nameClass;/* the nameClass definition if any */
xmlRelaxNGDefinePtr nextHash;/* next define in defs/refs hash tables */ xmlRelaxNGDefinePtr nextHash;/* next define in defs/refs hash tables */
}; };
@ -1562,6 +1563,9 @@ static xmlRelaxNGPtr xmlRelaxNGParseDocument(
xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node); xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node);
static int xmlRelaxNGParseGrammarContent( static int xmlRelaxNGParseGrammarContent(
xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes); xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes);
static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(
xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
xmlRelaxNGDefinePtr def);
#define IS_BLANK_NODE(n) \ #define IS_BLANK_NODE(n) \
@ -2420,7 +2424,6 @@ static xmlRelaxNGDefinePtr
xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
xmlRelaxNGDefinePtr ret, cur, last; xmlRelaxNGDefinePtr ret, cur, last;
xmlNodePtr child; xmlNodePtr child;
xmlChar *val;
int old_flags; int old_flags;
ret = xmlRelaxNGNewDefine(ctxt, node); ret = xmlRelaxNGNewDefine(ctxt, node);
@ -2438,27 +2441,10 @@ xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
} }
old_flags = ctxt->flags; old_flags = ctxt->flags;
ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE; ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
if (IS_RELAXNG(child, "name")) { cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
val = xmlNodeGetContent(child); if (cur != NULL)
ret->name = val; child = child->next;
val = xmlGetProp(child, BAD_CAST "ns");
ret->ns = val;
} else if (IS_RELAXNG(child, "anyName")) {
TODO
} else if (IS_RELAXNG(child, "nsName")) {
TODO
} else if (IS_RELAXNG(child, "choice")) {
TODO
} else {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
"element: expecting name, anyName, nsName or choice : got %s\n",
child->name);
ctxt->nbErrors++;
ctxt->flags = old_flags;
return(ret);
}
child = child->next;
last = NULL; last = NULL;
while (child != NULL) { while (child != NULL) {
cur = xmlRelaxNGParsePattern(ctxt, child); cur = xmlRelaxNGParsePattern(ctxt, child);
@ -2514,6 +2500,75 @@ xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
return(ret); return(ret);
} }
/**
* xmlRelaxNGParseExceptNameClass:
* @ctxt: a Relax-NG parser context
* @node: the except node
*
* parse the content of a RelaxNG nameClass node.
*
* Returns the definition pointer or NULL in case of error.
*/
static xmlRelaxNGDefinePtr
xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
TODO
return(NULL);
}
/**
* xmlRelaxNGParseNameClass:
* @ctxt: a Relax-NG parser context
* @node: the nameClass node
* @def: the current definition
*
* parse the content of a RelaxNG nameClass node.
*
* Returns the definition pointer or NULL in case of error.
*/
static xmlRelaxNGDefinePtr
xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
xmlRelaxNGDefinePtr def) {
xmlRelaxNGDefinePtr ret = def;
xmlChar *val;
if (IS_RELAXNG(node, "name")) {
val = xmlNodeGetContent(node);
ret->name = val;
val = xmlGetProp(node, BAD_CAST "ns");
ret->ns = val;
} else if (IS_RELAXNG(node, "anyName")) {
ret->name = NULL;
ret->ns = NULL;
if (node->children != NULL) {
ret->nameClass =
xmlRelaxNGParseExceptNameClass(ctxt, node->children);
}
} else if (IS_RELAXNG(node, "nsName")) {
ret->name = NULL;
ret->ns = xmlGetProp(node, BAD_CAST "ns");
if (ret->ns == NULL) {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
"nsName has no ns attribute\n");
ctxt->nbErrors++;
}
if (node->children != NULL) {
ret->nameClass =
xmlRelaxNGParseExceptNameClass(ctxt, node->children);
}
} else if (IS_RELAXNG(node, "choice")) {
TODO
} else {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
"expecting name, anyName, nsName or choice : got %s\n",
node->name);
ctxt->nbErrors++;
return(NULL);
}
return(ret);
}
/** /**
* xmlRelaxNGParseElement: * xmlRelaxNGParseElement:
* @ctxt: a Relax-NG parser context * @ctxt: a Relax-NG parser context
@ -2527,7 +2582,6 @@ static xmlRelaxNGDefinePtr
xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
xmlRelaxNGDefinePtr ret, cur, last; xmlRelaxNGDefinePtr ret, cur, last;
xmlNodePtr child; xmlNodePtr child;
xmlChar *val;
const xmlChar *olddefine; const xmlChar *olddefine;
ret = xmlRelaxNGNewDefine(ctxt, node); ret = xmlRelaxNGNewDefine(ctxt, node);
@ -2543,26 +2597,10 @@ xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
ctxt->nbErrors++; ctxt->nbErrors++;
return(ret); return(ret);
} }
if (IS_RELAXNG(child, "name")) { cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
val = xmlNodeGetContent(child); if (cur != NULL)
ret->name = val; child = child->next;
val = xmlGetProp(child, BAD_CAST "ns");
ret->ns = val;
} else if (IS_RELAXNG(child, "anyName")) {
TODO
} else if (IS_RELAXNG(child, "nsName")) {
TODO
} else if (IS_RELAXNG(child, "choice")) {
TODO
} else {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
"element: expecting name, anyName, nsName or choice : got %s\n",
child->name);
ctxt->nbErrors++;
return(ret);
}
child = child->next;
if (child == NULL) { if (child == NULL) {
if (ctxt->error != NULL) if (ctxt->error != NULL)
ctxt->error(ctxt->userData, ctxt->error(ctxt->userData,
@ -3405,12 +3443,7 @@ xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc) {
text = text->next; text = text->next;
} }
} }
if (text == NULL) { if (text != NULL) {
if (ctxt->error != NULL)
ctxt->error(ctxt->userData,
"xmlRelaxNGParse: attribute without name\n");
ctxt->nbErrors++;
} else {
xmlSetProp(text, BAD_CAST "ns", BAD_CAST ""); xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
} }
} }
@ -4293,9 +4326,71 @@ xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
#ifdef DEBUG #ifdef DEBUG
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"xmlRelaxNGValidateAttribute(%s): %d\n", define->name, ret); "xmlRelaxNGValidateAttribute(%s): %d\n", define->name, ret);
#endif
} else if (define->ns != NULL) {
for (i = 0;i < ctxt->state->nbAttrs;i++) {
tmp = ctxt->state->attrs[i];
if ((tmp != NULL) && (tmp->ns != NULL) &&
(xmlStrEqual(define->ns, tmp->ns->href))) {
prop = tmp;
break;
}
}
if (prop != NULL) {
value = xmlNodeListGetString(prop->doc, prop->children, 1);
oldvalue = ctxt->state->value;
ctxt->state->value = value;
ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
value = ctxt->state->value;
ctxt->state->value = oldvalue;
if (value != NULL)
xmlFree(value);
if (ret == 0) {
/*
* flag the attribute as processed
*/
ctxt->state->attrs[i] = NULL;
}
} else {
ret = -1;
}
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,
"xmlRelaxNGValidateAttribute(nsName ns = %s): %d\n",
define->ns, ret);
#endif #endif
} else { } else {
TODO for (i = 0;i < ctxt->state->nbAttrs;i++) {
tmp = ctxt->state->attrs[i];
if (tmp != NULL) {
prop = tmp;
break;
}
}
if (prop != NULL) {
value = xmlNodeListGetString(prop->doc, prop->children, 1);
oldvalue = ctxt->state->value;
ctxt->state->value = value;
ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
value = ctxt->state->value;
ctxt->state->value = oldvalue;
if (value != NULL)
xmlFree(value);
if (ret == 0) {
/*
* flag the attribute as processed
*/
ctxt->state->attrs[i] = NULL;
}
} else {
ret = -1;
}
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,
"xmlRelaxNGValidateAttribute(anyName): %d\n",
ret);
#endif
} }
return(ret); return(ret);
@ -4748,11 +4843,11 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
node->name, define->ns); node->name, define->ns);
return(-1); return(-1);
} }
} else { } else if (define->name != NULL) {
if (node->ns != NULL) { if (node->ns != NULL) {
VALID_CTXT(); VALID_CTXT();
VALID_ERROR("Expecting no namespace for element %s\n", VALID_ERROR("Expecting no namespace for element %s\n",
node->name); define->name);
return(-1); return(-1);
} }
} }