diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 42de3c675c2e5a..00d9f647ccfdf3 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -15,6 +15,8 @@ #include "Python.h" #include "structmember.h" // PyMemberDef +#include "expat.h" +#include "pyexpat.h" /* -------------------------------------------------------------------- */ /* configuration */ @@ -90,6 +92,8 @@ typedef struct { PyTypeObject *ElementIter_Type; PyTypeObject *TreeBuilder_Type; PyTypeObject *XMLParser_Type; + + struct PyExpat_CAPI *expat_capi; } elementtreestate; static struct PyModuleDef elementtreemodule; @@ -146,6 +150,8 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->ElementIter_Type); Py_CLEAR(st->TreeBuilder_Type); Py_CLEAR(st->XMLParser_Type); + + st->expat_capi = NULL; return 0; } @@ -3031,14 +3037,7 @@ _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, /* ==================================================================== */ /* the expat interface */ -#include "expat.h" -#include "pyexpat.h" - -/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be - * cached globally without being in per-module state. - */ -static struct PyExpat_CAPI *expat_capi; -#define EXPAT(func) (expat_capi->func) +#define EXPAT(st, func) ((st)->expat_capi->func) static XML_Memory_Handling_Suite ExpatMemoryHandler = { PyObject_Malloc, PyObject_Realloc, PyObject_Free}; @@ -3147,7 +3146,7 @@ expat_set_error(elementtreestate *st, enum XML_Error error_code, PyObject *errmsg, *error, *position, *code; errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", - message ? message : EXPAT(ErrorString)(error_code), + message ? message : EXPAT(st, ErrorString)(error_code), line, column); if (errmsg == NULL) return; @@ -3227,8 +3226,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, expat_set_error( st, XML_ERROR_UNDEFINED_ENTITY, - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), + EXPAT(st, GetErrorLineNumber)(self->parser), + EXPAT(st, GetErrorColumnNumber)(self->parser), message ); } @@ -3648,8 +3647,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, Py_CLEAR(self->entity); return -1; } - - self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); + elementtreestate *st = self->state; + self->parser = EXPAT(st, ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); if (!self->parser) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3657,15 +3656,14 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, return -1; } /* expat < 2.1.0 has no XML_SetHashSalt() */ - if (EXPAT(SetHashSalt) != NULL) { - EXPAT(SetHashSalt)(self->parser, + if (EXPAT(st, SetHashSalt) != NULL) { + EXPAT(st, SetHashSalt)(self->parser, (unsigned long)_Py_HashSecret.expat.hashsalt); } if (target != Py_None) { Py_INCREF(target); } else { - elementtreestate *st = self->state; target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self->entity); @@ -3713,43 +3711,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, } /* configure parser */ - EXPAT(SetUserData)(self->parser, self); + EXPAT(st, SetUserData)(self->parser, self); if (self->handle_start_ns || self->handle_end_ns) - EXPAT(SetNamespaceDeclHandler)( + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); - EXPAT(SetElementHandler)( + EXPAT(st, SetElementHandler)( self->parser, (XML_StartElementHandler) expat_start_handler, (XML_EndElementHandler) expat_end_handler ); - EXPAT(SetDefaultHandlerExpand)( + EXPAT(st, SetDefaultHandlerExpand)( self->parser, (XML_DefaultHandler) expat_default_handler ); - EXPAT(SetCharacterDataHandler)( + EXPAT(st, SetCharacterDataHandler)( self->parser, (XML_CharacterDataHandler) expat_data_handler ); if (self->handle_comment) - EXPAT(SetCommentHandler)( + EXPAT(st, SetCommentHandler)( self->parser, (XML_CommentHandler) expat_comment_handler ); if (self->handle_pi) - EXPAT(SetProcessingInstructionHandler)( + EXPAT(st, SetProcessingInstructionHandler)( self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); - EXPAT(SetStartDoctypeDeclHandler)( + EXPAT(st, SetStartDoctypeDeclHandler)( self->parser, (XML_StartDoctypeDeclHandler) expat_start_doctype_handler ); - EXPAT(SetUnknownEncodingHandler)( + EXPAT(st, SetUnknownEncodingHandler)( self->parser, - EXPAT(DefaultUnknownEncodingHandler), NULL + EXPAT(st, DefaultUnknownEncodingHandler), NULL ); return 0; @@ -3779,10 +3777,11 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) static int xmlparser_gc_clear(XMLParserObject *self) { + elementtreestate *st = self->state; if (self->parser != NULL) { XML_Parser parser = self->parser; self->parser = NULL; - EXPAT(ParserFree)(parser); + EXPAT(st, ParserFree)(parser); } Py_CLEAR(self->handle_close); @@ -3830,7 +3829,7 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data, int ok; assert(!PyErr_Occurred()); - ok = EXPAT(Parse)(self->parser, data, data_len, final); + ok = EXPAT(st, Parse)(self->parser, data, data_len, final); if (PyErr_Occurred()) return NULL; @@ -3838,9 +3837,9 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data, if (!ok) { expat_set_error( st, - EXPAT(GetErrorCode)(self->parser), - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), + EXPAT(st, GetErrorCode)(self->parser), + EXPAT(st, GetErrorLineNumber)(self->parser), + EXPAT(st, GetErrorColumnNumber)(self->parser), NULL ); return NULL; @@ -3911,7 +3910,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) return NULL; } /* Explicitly set UTF-8 encoding. Return code ignored. */ - (void)EXPAT(SetEncoding)(self->parser, "utf-8"); + (void)EXPAT(st, SetEncoding)(self->parser, "utf-8"); return expat_parse(st, self, data_ptr, (int)data_len, 0); } @@ -4099,27 +4098,27 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj)); } else if (strcmp(event_name, "start-ns") == 0) { Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj)); - EXPAT(SetNamespaceDeclHandler)( + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "end-ns") == 0) { Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj)); - EXPAT(SetNamespaceDeclHandler)( + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "comment") == 0) { Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj)); - EXPAT(SetCommentHandler)( + EXPAT(st, SetCommentHandler)( self->parser, (XML_CommentHandler) expat_comment_handler ); } else if (strcmp(event_name, "pi") == 0) { Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj)); - EXPAT(SetProcessingInstructionHandler)( + EXPAT(st, SetProcessingInstructionHandler)( self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); @@ -4344,14 +4343,14 @@ module_exec(PyObject *m) goto error; /* link against pyexpat */ - expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); - if (expat_capi) { + st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); + if (st->expat_capi) { /* check that it's usable */ - if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || - (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || - expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || - expat_capi->MINOR_VERSION != XML_MINOR_VERSION || - expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { + if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || + (size_t)st->expat_capi->size < sizeof(struct PyExpat_CAPI) || + st->expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || + st->expat_capi->MINOR_VERSION != XML_MINOR_VERSION || + st->expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); goto error;
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: