1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

Applied patch from Brent Hendricks adding support for late DTD validation.

* python/generator.py python/libxml.c python/libxml2class.txt
  python/libxml_wrap.h python/types.c: Applied patch from Brent
  Hendricks adding support for late DTD validation.
* python/tests/Makefile.am python/tests/dtdvalid.py
  python/tests/test.dtd: integrated the provided regression test
Daniel
This commit is contained in:
Daniel Veillard
2004-11-10 11:55:47 +00:00
parent 8eba3f3fa4
commit 850ce9b658
10 changed files with 272 additions and 16 deletions

View File

@ -1,8 +1,16 @@
Wed Nov 10 12:55:18 CET 2004 Daniel Veillard <daniel@veillard.com>
* python/generator.py python/libxml.c python/libxml2class.txt
python/libxml_wrap.h python/types.c: Applied patch from Brent
Hendricks adding support for late DTD validation.
* python/tests/Makefile.am python/tests/dtdvalid.py
python/tests/test.dtd: integrated the provided regression test
Tue nov 9 19:24:31 CET 2004 Dodji Seketeli <dodji@seketeli.org> Tue nov 9 19:24:31 CET 2004 Dodji Seketeli <dodji@seketeli.org>
* configure.in: detect when struct sockaddr_storage * configure.in: detect when struct sockaddr_storage
has the __ss_family member instead of ss_family and has the __ss_family member instead of ss_family and
behave accordingly. We know can use ipv6 on aix. behave accordingly. We now can use ipv6 on aix.
Tue Nov 9 17:15:46 CET 2004 Daniel Veillard <daniel@veillard.com> Tue Nov 9 17:15:46 CET 2004 Daniel Veillard <daniel@veillard.com>

View File

@ -25,6 +25,9 @@
/* Define to 1 if you have the <arpa/nameser.h> header file. */ /* Define to 1 if you have the <arpa/nameser.h> header file. */
#undef HAVE_ARPA_NAMESER_H #undef HAVE_ARPA_NAMESER_H
/* Whether struct sockaddr::__ss_family exists */
#undef HAVE_BROKEN_SS_FAMILY
/* Define to 1 if you have the `class' function. */ /* Define to 1 if you have the `class' function. */
#undef HAVE_CLASS #undef HAVE_CLASS
@ -279,5 +282,8 @@
/* Win32 Std C name mangling work-around */ /* Win32 Std C name mangling work-around */
#undef snprintf #undef snprintf
/* ss_family is not defined here, use __ss_family instead */
#undef ss_family
/* Win32 Std C name mangling work-around */ /* Win32 Std C name mangling work-around */
#undef vsnprintf #undef vsnprintf

View File

@ -270,6 +270,7 @@ py_types = {
'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"), 'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"), 'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"), 'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
'xmlValidCtxtPtr': ('O', "ValidCtxt", "xmlValidCtxtPtr", "xmlValidCtxtPtr"),
'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"), 'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
'FILE *': ('O', "File", "FILEPtr", "FILE *"), 'FILE *': ('O', "File", "FILEPtr", "FILE *"),
'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"), 'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
@ -345,6 +346,14 @@ def skip_function(name):
return 1 return 1
if name == "xmlErrMemory": if name == "xmlErrMemory":
return 1 return 1
if name == "xmlValidBuildContentModel":
return 1
if name == "xmlValidateElementDecl":
return 1
if name == "xmlValidateAttributeDecl":
return 1
return 0 return 0
def print_function_wrapper(name, output, export, include): def print_function_wrapper(name, output, export, include):
@ -668,6 +677,7 @@ classes_type = {
"xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"), "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
"htmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"), "htmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
"htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"), "htmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
"xmlValidCtxtPtr": ("._o", "ValidCtxt(_obj=%s)", "ValidCtxt"),
"xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"), "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
"xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"), "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
"xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"), "xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
@ -718,6 +728,7 @@ classes_destructors = {
"Schema": "xmlSchemaFree", "Schema": "xmlSchemaFree",
"SchemaParserCtxt": "xmlSchemaFreeParserCtxt", "SchemaParserCtxt": "xmlSchemaFreeParserCtxt",
"SchemaValidCtxt": "xmlSchemaFreeValidCtxt", "SchemaValidCtxt": "xmlSchemaFreeValidCtxt",
"ValidCtxt": "xmlFreeValidCtxt",
} }
functions_noexcept = { functions_noexcept = {

View File

@ -1554,7 +1554,7 @@ libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
xmlParserCtxtPyCtxtPtr pyCtxt; xmlParserCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR #ifdef DEBUG_ERROR
printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg); printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
#endif #endif
ctxt = (xmlParserCtxtPtr)ctx; ctxt = (xmlParserCtxtPtr)ctx;
@ -1723,6 +1723,141 @@ libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
return(Py_None); return(Py_None);
} }
/***
* xmlValidCtxt stuff
*/
typedef struct
{
PyObject *warn;
PyObject *error;
PyObject *arg;
} xmlValidCtxtPyCtxt;
typedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr;
static void
libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
{
PyObject *list;
PyObject *result;
xmlValidCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
printf("libxml_xmlValidCtxtGenericErrorFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
#endif
pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
list = PyTuple_New(2);
PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
PyTuple_SetItem(list, 1, pyCtxt->arg);
Py_XINCREF(pyCtxt->arg);
result = PyEval_CallObject(pyCtxt->error, list);
if (result == NULL)
{
/* TODO: manage for the exception to be propagated... */
PyErr_Print();
}
Py_XDECREF(list);
Py_XDECREF(result);
}
static void
libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, int severity, char *str)
{
PyObject *list;
PyObject *result;
xmlValidCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
printf("libxml_xmlValidCtxtGenericWarningFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
#endif
pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
list = PyTuple_New(2);
PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
PyTuple_SetItem(list, 1, pyCtxt->arg);
Py_XINCREF(pyCtxt->arg);
result = PyEval_CallObject(pyCtxt->warn, list);
if (result == NULL)
{
/* TODO: manage for the exception to be propagated... */
PyErr_Print();
}
Py_XDECREF(list);
Py_XDECREF(result);
}
static void
libxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
va_end(ap);
}
static void
libxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
va_end(ap);
}
static PyObject *
libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
{
PyObject *py_retval;
PyObject *pyobj_error;
PyObject *pyobj_warn;
PyObject *pyobj_ctx;
PyObject *pyobj_arg = Py_None;
xmlValidCtxtPtr ctxt;
xmlValidCtxtPyCtxtPtr pyCtxt;
if (!PyArg_ParseTuple
(args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
return (NULL);
#ifdef DEBUG_ERROR
printf("libxml_xmlSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
#endif
ctxt = PyValidCtxt_Get(pyobj_ctx);
pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
if (pyCtxt == NULL) {
py_retval = libxml_intWrap(-1);
return(py_retval);
}
memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt));
/* TODO: check warn and error is a function ! */
Py_XDECREF(pyCtxt->error);
Py_XINCREF(pyobj_error);
pyCtxt->error = pyobj_error;
Py_XDECREF(pyCtxt->warn);
Py_XINCREF(pyobj_warn);
pyCtxt->warn = pyobj_warn;
Py_XDECREF(pyCtxt->arg);
Py_XINCREF(pyobj_arg);
pyCtxt->arg = pyobj_arg;
ctxt->error = libxml_xmlValidCtxtErrorFuncHandler;
ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler;
ctxt->userData = pyCtxt;
py_retval = libxml_intWrap(1);
return (py_retval);
}
/************************************************************************ /************************************************************************
* * * *
* Per xmlTextReader error handler * * Per xmlTextReader error handler *
@ -3482,6 +3617,7 @@ static PyMethodDef libxmlMethods[] = {
{(char *) "type", libxml_type, METH_VARARGS, NULL}, {(char *) "type", libxml_type, METH_VARARGS, NULL},
{(char *) "doc", libxml_doc, METH_VARARGS, NULL}, {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
{(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL}, {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
{(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
#ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_OUTPUT_ENABLED
{(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL}, {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
{(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL}, {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},

View File

@ -187,6 +187,7 @@ normalizeURIPath()
parseURI() parseURI()
# functions from module valid # functions from module valid
newValidCtxt()
validateNameValue() validateNameValue()
validateNamesValue() validateNamesValue()
validateNmtokenValue() validateNmtokenValue()
@ -632,7 +633,20 @@ Class xmlDoc(xmlNode)
isRef() isRef()
removeID() removeID()
removeRef() removeRef()
validCtxtNormalizeAttributeValue()
validNormalizeAttributeValue() validNormalizeAttributeValue()
validateDocument()
validateDocumentFinal()
validateDtd()
validateDtdFinal()
validateElement()
validateNotationUse()
validateOneAttribute()
validateOneElement()
validateOneNamespace()
validatePopElement()
validatePushElement()
validateRoot()
# functions from module xinclude # functions from module xinclude
xincludeProcess() xincludeProcess()
@ -687,18 +701,23 @@ Class xpathContext()
Class xmlAttribute(xmlNode) Class xmlAttribute(xmlNode)
Class catalog() Class ValidCtxt()
# functions from module catalog # functions from module valid
add() validCtxtNormalizeAttributeValue()
catalogIsEmpty() validateDocument()
convertSGMLCatalog() validateDocumentFinal()
dump() validateDtd()
remove() validateDtdFinal()
resolve() validateElement()
resolvePublic() validateNotationUse()
resolveSystem() validateOneAttribute()
resolveURI() validateOneElement()
validateOneNamespace()
validatePopElement()
validatePushCData()
validatePushElement()
validateRoot()
Class xmlElement(xmlNode) Class xmlElement(xmlNode)
@ -786,6 +805,18 @@ Class xmlReg()
regexpExec() regexpExec()
regexpIsDeterminist() regexpIsDeterminist()
regexpPrint() regexpPrint()
Class catalog()
# functions from module catalog
add()
catalogIsEmpty()
convertSGMLCatalog()
dump()
remove()
resolve()
resolvePublic()
resolveSystem()
resolveURI()
Class xmlEntity(xmlNode) Class xmlEntity(xmlNode)

View File

@ -73,6 +73,14 @@ typedef struct {
xmlParserCtxtPtr obj; xmlParserCtxtPtr obj;
} PyparserCtxt_Object; } PyparserCtxt_Object;
#define PyValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
(((PyValidCtxt_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlValidCtxtPtr obj;
} PyValidCtxt_Object;
#define Pycatalog_Get(v) (((v) == Py_None) ? NULL : \ #define Pycatalog_Get(v) (((v) == Py_None) ? NULL : \
(((Pycatalog_Object *)(v))->obj)) (((Pycatalog_Object *)(v))->obj))
@ -213,6 +221,7 @@ PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt); PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt); PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj); PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid);
PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj); PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri); PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer); PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);

View File

@ -36,12 +36,14 @@ PYTESTS= \
thread2.py \ thread2.py \
sync.py \ sync.py \
tstLastError.py \ tstLastError.py \
indexes.py indexes.py \
dtdvalid.py
XMLS= \ XMLS= \
tst.xml \ tst.xml \
valid.xml \ valid.xml \
invalid.xml invalid.xml \
test.dtd
EXTRA_DIST = $(PYTESTS) $(XMLS) EXTRA_DIST = $(PYTESTS) $(XMLS)

32
python/tests/dtdvalid.py Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/python -u
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
dtd="""<!ELEMENT foo EMPTY>"""
instance="""<?xml version="1.0"?>
<foo></foo>"""
dtd = libxml2.parseDTD(None, 'test.dtd')
ctxt = libxml2.newValidCtxt()
doc = libxml2.parseDoc(instance)
ret = doc.validateDtd(ctxt, dtd)
if ret != 1:
print "error doing DTD validation"
sys.exit(1)
doc.freeDoc()
dtd.freeDtd()
del dtd
del ctxt
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print "OK"
else:
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
libxml2.dumpMemory()

1
python/tests/test.dtd Normal file
View File

@ -0,0 +1 @@
<!ELEMENT foo EMPTY>

View File

@ -477,6 +477,26 @@ libxml_xmlXPathObjectPtrConvert(PyObject * obj)
return (ret); return (ret);
} }
PyObject *
libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
{
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid);
#endif
if (valid == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
ret =
PyCObject_FromVoidPtrAndDesc((void *) valid,
(char *) "xmlValidCtxtPtr", NULL);
return (ret);
}
PyObject * PyObject *
libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal) libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
{ {