1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-24 21:33:51 +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>
* configure.in: detect when struct sockaddr_storage
has the __ss_family member instead of ss_family and
behave accordingly. We know can use ipv6 on aix.
has the __ss_family member instead of ss_family and
behave accordingly. We now can use ipv6 on aix.
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. */
#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. */
#undef HAVE_CLASS
@ -279,5 +282,8 @@
/* Win32 Std C name mangling work-around */
#undef snprintf
/* ss_family is not defined here, use __ss_family instead */
#undef ss_family
/* Win32 Std C name mangling work-around */
#undef vsnprintf

View File

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

View File

@ -1554,7 +1554,7 @@ libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
xmlParserCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
#endif
ctxt = (xmlParserCtxtPtr)ctx;
@ -1723,6 +1723,141 @@ libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
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 *
@ -3482,6 +3617,7 @@ static PyMethodDef libxmlMethods[] = {
{(char *) "type", libxml_type, METH_VARARGS, NULL},
{(char *) "doc", libxml_doc, METH_VARARGS, NULL},
{(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
{(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
#ifdef LIBXML_OUTPUT_ENABLED
{(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
{(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},

View File

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

View File

@ -73,6 +73,14 @@ typedef struct {
xmlParserCtxtPtr obj;
} 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 : \
(((Pycatalog_Object *)(v))->obj))
@ -213,6 +221,7 @@ PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
PyObject * libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt);
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
PyObject * libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid);
PyObject * libxml_xmlCatalogPtrWrap(xmlCatalogPtr obj);
PyObject * libxml_xmlURIPtrWrap(xmlURIPtr uri);
PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);

View File

@ -36,12 +36,14 @@ PYTESTS= \
thread2.py \
sync.py \
tstLastError.py \
indexes.py
indexes.py \
dtdvalid.py
XMLS= \
tst.xml \
valid.xml \
invalid.xml
invalid.xml \
test.dtd
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);
}
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 *
libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
{