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:
parent
8eba3f3fa4
commit
850ce9b658
12
ChangeLog
12
ChangeLog
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
138
python/libxml.c
138
python/libxml.c
@ -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},
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
32
python/tests/dtdvalid.py
Executable 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
1
python/tests/test.dtd
Normal file
@ -0,0 +1 @@
|
||||
<!ELEMENT foo EMPTY>
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user