LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - pyexpat.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 889 0.0 %
Date: 2012-12-17 Functions: 0 65 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "Python.h"
       2             : #include <ctype.h>
       3             : 
       4             : #include "frameobject.h"
       5             : #include "expat.h"
       6             : 
       7             : #include "pyexpat.h"
       8             : 
       9             : #define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
      10             : 
      11             : #define FIX_TRACE
      12             : 
      13             : enum HandlerTypes {
      14             :     StartElement,
      15             :     EndElement,
      16             :     ProcessingInstruction,
      17             :     CharacterData,
      18             :     UnparsedEntityDecl,
      19             :     NotationDecl,
      20             :     StartNamespaceDecl,
      21             :     EndNamespaceDecl,
      22             :     Comment,
      23             :     StartCdataSection,
      24             :     EndCdataSection,
      25             :     Default,
      26             :     DefaultHandlerExpand,
      27             :     NotStandalone,
      28             :     ExternalEntityRef,
      29             :     StartDoctypeDecl,
      30             :     EndDoctypeDecl,
      31             :     EntityDecl,
      32             :     XmlDecl,
      33             :     ElementDecl,
      34             :     AttlistDecl,
      35             : #if XML_COMBINED_VERSION >= 19504
      36             :     SkippedEntity,
      37             : #endif
      38             :     _DummyDecl
      39             : };
      40             : 
      41             : static PyObject *ErrorObject;
      42             : 
      43             : /* ----------------------------------------------------- */
      44             : 
      45             : /* Declarations for objects of type xmlparser */
      46             : 
      47             : typedef struct {
      48             :     PyObject_HEAD
      49             : 
      50             :     XML_Parser itself;
      51             :     int ordered_attributes;     /* Return attributes as a list. */
      52             :     int specified_attributes;   /* Report only specified attributes. */
      53             :     int in_callback;            /* Is a callback active? */
      54             :     int ns_prefixes;            /* Namespace-triplets mode? */
      55             :     XML_Char *buffer;           /* Buffer used when accumulating characters */
      56             :                                 /* NULL if not enabled */
      57             :     int buffer_size;            /* Size of buffer, in XML_Char units */
      58             :     int buffer_used;            /* Buffer units in use */
      59             :     PyObject *intern;           /* Dictionary to intern strings */
      60             :     PyObject **handlers;
      61             : } xmlparseobject;
      62             : 
      63             : #define CHARACTER_DATA_BUFFER_SIZE 8192
      64             : 
      65             : static PyTypeObject Xmlparsetype;
      66             : 
      67             : typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
      68             : typedef void* xmlhandler;
      69             : 
      70             : struct HandlerInfo {
      71             :     const char *name;
      72             :     xmlhandlersetter setter;
      73             :     xmlhandler handler;
      74             :     PyCodeObject *tb_code;
      75             :     PyObject *nameobj;
      76             : };
      77             : 
      78             : static struct HandlerInfo handler_info[64];
      79             : 
      80             : /* Set an integer attribute on the error object; return true on success,
      81             :  * false on an exception.
      82             :  */
      83             : static int
      84           0 : set_error_attr(PyObject *err, char *name, int value)
      85             : {
      86           0 :     PyObject *v = PyLong_FromLong(value);
      87             : 
      88           0 :     if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
      89           0 :         Py_XDECREF(v);
      90           0 :         return 0;
      91             :     }
      92           0 :     Py_DECREF(v);
      93           0 :     return 1;
      94             : }
      95             : 
      96             : /* Build and set an Expat exception, including positioning
      97             :  * information.  Always returns NULL.
      98             :  */
      99             : static PyObject *
     100           0 : set_error(xmlparseobject *self, enum XML_Error code)
     101             : {
     102             :     PyObject *err;
     103             :     PyObject *buffer;
     104           0 :     XML_Parser parser = self->itself;
     105           0 :     int lineno = XML_GetErrorLineNumber(parser);
     106           0 :     int column = XML_GetErrorColumnNumber(parser);
     107             : 
     108           0 :     buffer = PyUnicode_FromFormat("%s: line %i, column %i",
     109             :                                   XML_ErrorString(code), lineno, column);
     110           0 :     if (buffer == NULL)
     111           0 :         return NULL;
     112           0 :     err = PyObject_CallFunction(ErrorObject, "O", buffer);
     113           0 :     Py_DECREF(buffer);
     114           0 :     if (  err != NULL
     115           0 :           && set_error_attr(err, "code", code)
     116           0 :           && set_error_attr(err, "offset", column)
     117           0 :           && set_error_attr(err, "lineno", lineno)) {
     118           0 :         PyErr_SetObject(ErrorObject, err);
     119             :     }
     120           0 :     Py_XDECREF(err);
     121           0 :     return NULL;
     122             : }
     123             : 
     124             : static int
     125           0 : have_handler(xmlparseobject *self, int type)
     126             : {
     127           0 :     PyObject *handler = self->handlers[type];
     128           0 :     return handler != NULL;
     129             : }
     130             : 
     131             : static PyObject *
     132           0 : get_handler_name(struct HandlerInfo *hinfo)
     133             : {
     134           0 :     PyObject *name = hinfo->nameobj;
     135           0 :     if (name == NULL) {
     136           0 :         name = PyUnicode_FromString(hinfo->name);
     137           0 :         hinfo->nameobj = name;
     138             :     }
     139           0 :     Py_XINCREF(name);
     140           0 :     return name;
     141             : }
     142             : 
     143             : 
     144             : /* Convert a string of XML_Chars into a Unicode string.
     145             :    Returns None if str is a null pointer. */
     146             : 
     147             : static PyObject *
     148           0 : conv_string_to_unicode(const XML_Char *str)
     149             : {
     150             :     /* XXX currently this code assumes that XML_Char is 8-bit,
     151             :        and hence in UTF-8.  */
     152             :     /* UTF-8 from Expat, Unicode desired */
     153           0 :     if (str == NULL) {
     154           0 :         Py_INCREF(Py_None);
     155           0 :         return Py_None;
     156             :     }
     157           0 :     return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
     158             : }
     159             : 
     160             : static PyObject *
     161           0 : conv_string_len_to_unicode(const XML_Char *str, int len)
     162             : {
     163             :     /* XXX currently this code assumes that XML_Char is 8-bit,
     164             :        and hence in UTF-8.  */
     165             :     /* UTF-8 from Expat, Unicode desired */
     166           0 :     if (str == NULL) {
     167           0 :         Py_INCREF(Py_None);
     168           0 :         return Py_None;
     169             :     }
     170           0 :     return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
     171             : }
     172             : 
     173             : /* Callback routines */
     174             : 
     175             : static void clear_handlers(xmlparseobject *self, int initial);
     176             : 
     177             : /* This handler is used when an error has been detected, in the hope
     178             :    that actual parsing can be terminated early.  This will only help
     179             :    if an external entity reference is encountered. */
     180             : static int
     181           0 : error_external_entity_ref_handler(XML_Parser parser,
     182             :                                   const XML_Char *context,
     183             :                                   const XML_Char *base,
     184             :                                   const XML_Char *systemId,
     185             :                                   const XML_Char *publicId)
     186             : {
     187           0 :     return 0;
     188             : }
     189             : 
     190             : /* Dummy character data handler used when an error (exception) has
     191             :    been detected, and the actual parsing can be terminated early.
     192             :    This is needed since character data handler can't be safely removed
     193             :    from within the character data handler, but can be replaced.  It is
     194             :    used only from the character data handler trampoline, and must be
     195             :    used right after `flag_error()` is called. */
     196             : static void
     197           0 : noop_character_data_handler(void *userData, const XML_Char *data, int len)
     198             : {
     199             :     /* Do nothing. */
     200           0 : }
     201             : 
     202             : static void
     203           0 : flag_error(xmlparseobject *self)
     204             : {
     205           0 :     clear_handlers(self, 0);
     206           0 :     XML_SetExternalEntityRefHandler(self->itself,
     207             :                                     error_external_entity_ref_handler);
     208           0 : }
     209             : 
     210             : static PyCodeObject*
     211           0 : getcode(enum HandlerTypes slot, char* func_name, int lineno)
     212             : {
     213           0 :     if (handler_info[slot].tb_code == NULL) {
     214           0 :         handler_info[slot].tb_code =
     215           0 :             PyCode_NewEmpty(__FILE__, func_name, lineno);
     216             :     }
     217           0 :     return handler_info[slot].tb_code;
     218             : }
     219             : 
     220             : #ifdef FIX_TRACE
     221             : static int
     222           0 : trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
     223             : {
     224           0 :     int result = 0;
     225           0 :     if (!tstate->use_tracing || tstate->tracing)
     226           0 :         return 0;
     227           0 :     if (tstate->c_profilefunc != NULL) {
     228           0 :         tstate->tracing++;
     229           0 :         result = tstate->c_profilefunc(tstate->c_profileobj,
     230             :                                        f, code , val);
     231           0 :         tstate->use_tracing = ((tstate->c_tracefunc != NULL)
     232           0 :                                || (tstate->c_profilefunc != NULL));
     233           0 :         tstate->tracing--;
     234           0 :         if (result)
     235           0 :             return result;
     236             :     }
     237           0 :     if (tstate->c_tracefunc != NULL) {
     238           0 :         tstate->tracing++;
     239           0 :         result = tstate->c_tracefunc(tstate->c_traceobj,
     240             :                                      f, code , val);
     241           0 :         tstate->use_tracing = ((tstate->c_tracefunc != NULL)
     242           0 :                                || (tstate->c_profilefunc != NULL));
     243           0 :         tstate->tracing--;
     244             :     }
     245           0 :     return result;
     246             : }
     247             : 
     248             : static int
     249           0 : trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
     250             : {
     251             :     PyObject *type, *value, *traceback, *arg;
     252             :     int err;
     253             : 
     254           0 :     if (tstate->c_tracefunc == NULL)
     255           0 :         return 0;
     256             : 
     257           0 :     PyErr_Fetch(&type, &value, &traceback);
     258           0 :     if (value == NULL) {
     259           0 :         value = Py_None;
     260           0 :         Py_INCREF(value);
     261             :     }
     262           0 :     arg = PyTuple_Pack(3, type, value, traceback);
     263           0 :     if (arg == NULL) {
     264           0 :         PyErr_Restore(type, value, traceback);
     265           0 :         return 0;
     266             :     }
     267           0 :     err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
     268           0 :     Py_DECREF(arg);
     269           0 :     if (err == 0)
     270           0 :         PyErr_Restore(type, value, traceback);
     271             :     else {
     272           0 :         Py_XDECREF(type);
     273           0 :         Py_XDECREF(value);
     274           0 :         Py_XDECREF(traceback);
     275             :     }
     276           0 :     return err;
     277             : }
     278             : #endif
     279             : 
     280             : static PyObject*
     281           0 : call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
     282             :                 xmlparseobject *self)
     283             : {
     284           0 :     PyThreadState *tstate = PyThreadState_GET();
     285             :     PyFrameObject *f;
     286             :     PyObject *res;
     287             : 
     288           0 :     if (c == NULL)
     289           0 :         return NULL;
     290             : 
     291           0 :     f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
     292           0 :     if (f == NULL)
     293           0 :         return NULL;
     294           0 :     tstate->frame = f;
     295             : #ifdef FIX_TRACE
     296           0 :     if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
     297           0 :         return NULL;
     298             :     }
     299             : #endif
     300           0 :     res = PyEval_CallObject(func, args);
     301           0 :     if (res == NULL) {
     302           0 :         if (tstate->curexc_traceback == NULL)
     303           0 :             PyTraceBack_Here(f);
     304           0 :         XML_StopParser(self->itself, XML_FALSE);
     305             : #ifdef FIX_TRACE
     306           0 :         if (trace_frame_exc(tstate, f) < 0) {
     307           0 :             return NULL;
     308             :         }
     309             :     }
     310             :     else {
     311           0 :         if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
     312           0 :             Py_XDECREF(res);
     313           0 :             res = NULL;
     314             :         }
     315             :     }
     316             : #else
     317             :     }
     318             : #endif
     319           0 :     tstate->frame = f->f_back;
     320           0 :     Py_DECREF(f);
     321           0 :     return res;
     322             : }
     323             : 
     324             : static PyObject*
     325           0 : string_intern(xmlparseobject *self, const char* str)
     326             : {
     327           0 :     PyObject *result = conv_string_to_unicode(str);
     328             :     PyObject *value;
     329             :     /* result can be NULL if the unicode conversion failed. */
     330           0 :     if (!result)
     331           0 :         return result;
     332           0 :     if (!self->intern)
     333           0 :         return result;
     334           0 :     value = PyDict_GetItem(self->intern, result);
     335           0 :     if (!value) {
     336           0 :         if (PyDict_SetItem(self->intern, result, result) == 0)
     337           0 :             return result;
     338             :         else
     339           0 :             return NULL;
     340             :     }
     341           0 :     Py_INCREF(value);
     342           0 :     Py_DECREF(result);
     343           0 :     return value;
     344             : }
     345             : 
     346             : /* Return 0 on success, -1 on exception.
     347             :  * flag_error() will be called before return if needed.
     348             :  */
     349             : static int
     350           0 : call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
     351             : {
     352             :     PyObject *args;
     353             :     PyObject *temp;
     354             : 
     355           0 :     if (!have_handler(self, CharacterData))
     356           0 :         return -1;
     357             : 
     358           0 :     args = PyTuple_New(1);
     359           0 :     if (args == NULL)
     360           0 :         return -1;
     361           0 :     temp = (conv_string_len_to_unicode(buffer, len));
     362           0 :     if (temp == NULL) {
     363           0 :         Py_DECREF(args);
     364           0 :         flag_error(self);
     365           0 :         XML_SetCharacterDataHandler(self->itself,
     366             :                                     noop_character_data_handler);
     367           0 :         return -1;
     368             :     }
     369           0 :     PyTuple_SET_ITEM(args, 0, temp);
     370             :     /* temp is now a borrowed reference; consider it unused. */
     371           0 :     self->in_callback = 1;
     372           0 :     temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
     373           0 :                            self->handlers[CharacterData], args, self);
     374             :     /* temp is an owned reference again, or NULL */
     375           0 :     self->in_callback = 0;
     376           0 :     Py_DECREF(args);
     377           0 :     if (temp == NULL) {
     378           0 :         flag_error(self);
     379           0 :         XML_SetCharacterDataHandler(self->itself,
     380             :                                     noop_character_data_handler);
     381           0 :         return -1;
     382             :     }
     383           0 :     Py_DECREF(temp);
     384           0 :     return 0;
     385             : }
     386             : 
     387             : static int
     388           0 : flush_character_buffer(xmlparseobject *self)
     389             : {
     390             :     int rc;
     391           0 :     if (self->buffer == NULL || self->buffer_used == 0)
     392           0 :         return 0;
     393           0 :     rc = call_character_handler(self, self->buffer, self->buffer_used);
     394           0 :     self->buffer_used = 0;
     395           0 :     return rc;
     396             : }
     397             : 
     398             : static void
     399           0 : my_CharacterDataHandler(void *userData, const XML_Char *data, int len)
     400             : {
     401           0 :     xmlparseobject *self = (xmlparseobject *) userData;
     402           0 :     if (self->buffer == NULL)
     403           0 :         call_character_handler(self, data, len);
     404             :     else {
     405           0 :         if ((self->buffer_used + len) > self->buffer_size) {
     406           0 :             if (flush_character_buffer(self) < 0)
     407           0 :                 return;
     408             :             /* handler might have changed; drop the rest on the floor
     409             :              * if there isn't a handler anymore
     410             :              */
     411           0 :             if (!have_handler(self, CharacterData))
     412           0 :                 return;
     413             :         }
     414           0 :         if (len > self->buffer_size) {
     415           0 :             call_character_handler(self, data, len);
     416           0 :             self->buffer_used = 0;
     417             :         }
     418             :         else {
     419           0 :             memcpy(self->buffer + self->buffer_used,
     420             :                    data, len * sizeof(XML_Char));
     421           0 :             self->buffer_used += len;
     422             :         }
     423             :     }
     424             : }
     425             : 
     426             : static void
     427           0 : my_StartElementHandler(void *userData,
     428             :                        const XML_Char *name, const XML_Char *atts[])
     429             : {
     430           0 :     xmlparseobject *self = (xmlparseobject *)userData;
     431             : 
     432           0 :     if (have_handler(self, StartElement)) {
     433             :         PyObject *container, *rv, *args;
     434             :         int i, max;
     435             : 
     436           0 :         if (flush_character_buffer(self) < 0)
     437           0 :             return;
     438             :         /* Set max to the number of slots filled in atts[]; max/2 is
     439             :          * the number of attributes we need to process.
     440             :          */
     441           0 :         if (self->specified_attributes) {
     442           0 :             max = XML_GetSpecifiedAttributeCount(self->itself);
     443             :         }
     444             :         else {
     445           0 :             max = 0;
     446           0 :             while (atts[max] != NULL)
     447           0 :                 max += 2;
     448             :         }
     449             :         /* Build the container. */
     450           0 :         if (self->ordered_attributes)
     451           0 :             container = PyList_New(max);
     452             :         else
     453           0 :             container = PyDict_New();
     454           0 :         if (container == NULL) {
     455           0 :             flag_error(self);
     456           0 :             return;
     457             :         }
     458           0 :         for (i = 0; i < max; i += 2) {
     459           0 :             PyObject *n = string_intern(self, (XML_Char *) atts[i]);
     460             :             PyObject *v;
     461           0 :             if (n == NULL) {
     462           0 :                 flag_error(self);
     463           0 :                 Py_DECREF(container);
     464           0 :                 return;
     465             :             }
     466           0 :             v = conv_string_to_unicode((XML_Char *) atts[i+1]);
     467           0 :             if (v == NULL) {
     468           0 :                 flag_error(self);
     469           0 :                 Py_DECREF(container);
     470           0 :                 Py_DECREF(n);
     471           0 :                 return;
     472             :             }
     473           0 :             if (self->ordered_attributes) {
     474           0 :                 PyList_SET_ITEM(container, i, n);
     475           0 :                 PyList_SET_ITEM(container, i+1, v);
     476             :             }
     477           0 :             else if (PyDict_SetItem(container, n, v)) {
     478           0 :                 flag_error(self);
     479           0 :                 Py_DECREF(n);
     480           0 :                 Py_DECREF(v);
     481           0 :                 return;
     482             :             }
     483             :             else {
     484           0 :                 Py_DECREF(n);
     485           0 :                 Py_DECREF(v);
     486             :             }
     487             :         }
     488           0 :         args = string_intern(self, name);
     489           0 :         if (args != NULL)
     490           0 :             args = Py_BuildValue("(NN)", args, container);
     491           0 :         if (args == NULL) {
     492           0 :             Py_DECREF(container);
     493           0 :             return;
     494             :         }
     495             :         /* Container is now a borrowed reference; ignore it. */
     496           0 :         self->in_callback = 1;
     497           0 :         rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
     498           0 :                              self->handlers[StartElement], args, self);
     499           0 :         self->in_callback = 0;
     500           0 :         Py_DECREF(args);
     501           0 :         if (rv == NULL) {
     502           0 :             flag_error(self);
     503           0 :             return;
     504             :         }
     505           0 :         Py_DECREF(rv);
     506             :     }
     507             : }
     508             : 
     509             : #define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
     510             :                 RETURN, GETUSERDATA) \
     511             : static RC \
     512             : my_##NAME##Handler PARAMS {\
     513             :     xmlparseobject *self = GETUSERDATA ; \
     514             :     PyObject *args = NULL; \
     515             :     PyObject *rv = NULL; \
     516             :     INIT \
     517             : \
     518             :     if (have_handler(self, NAME)) { \
     519             :         if (flush_character_buffer(self) < 0) \
     520             :             return RETURN; \
     521             :         args = Py_BuildValue PARAM_FORMAT ;\
     522             :         if (!args) { flag_error(self); return RETURN;} \
     523             :         self->in_callback = 1; \
     524             :         rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
     525             :                              self->handlers[NAME], args, self); \
     526             :         self->in_callback = 0; \
     527             :         Py_DECREF(args); \
     528             :         if (rv == NULL) { \
     529             :             flag_error(self); \
     530             :             return RETURN; \
     531             :         } \
     532             :         CONVERSION \
     533             :         Py_DECREF(rv); \
     534             :     } \
     535             :     return RETURN; \
     536             : }
     537             : 
     538             : #define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
     539             :         RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
     540             :         (xmlparseobject *)userData)
     541             : 
     542             : #define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
     543             :         RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
     544             :                         rc = PyLong_AsLong(rv);, rc, \
     545             :         (xmlparseobject *)userData)
     546             : 
     547           0 : VOID_HANDLER(EndElement,
     548             :              (void *userData, const XML_Char *name),
     549           0 :              ("(N)", string_intern(self, name)))
     550             : 
     551           0 : VOID_HANDLER(ProcessingInstruction,
     552             :              (void *userData,
     553             :               const XML_Char *target,
     554             :               const XML_Char *data),
     555           0 :              ("(NO&)", string_intern(self, target), conv_string_to_unicode ,data))
     556             : 
     557           0 : VOID_HANDLER(UnparsedEntityDecl,
     558             :              (void *userData,
     559             :               const XML_Char *entityName,
     560             :               const XML_Char *base,
     561             :               const XML_Char *systemId,
     562             :               const XML_Char *publicId,
     563             :               const XML_Char *notationName),
     564             :              ("(NNNNN)",
     565             :               string_intern(self, entityName), string_intern(self, base),
     566             :               string_intern(self, systemId), string_intern(self, publicId),
     567           0 :               string_intern(self, notationName)))
     568             : 
     569           0 : VOID_HANDLER(EntityDecl,
     570             :              (void *userData,
     571             :               const XML_Char *entityName,
     572             :               int is_parameter_entity,
     573             :               const XML_Char *value,
     574             :               int value_length,
     575             :               const XML_Char *base,
     576             :               const XML_Char *systemId,
     577             :               const XML_Char *publicId,
     578             :               const XML_Char *notationName),
     579             :              ("NiNNNNN",
     580             :               string_intern(self, entityName), is_parameter_entity,
     581             :               (conv_string_len_to_unicode(value, value_length)),
     582             :               string_intern(self, base), string_intern(self, systemId),
     583             :               string_intern(self, publicId),
     584           0 :               string_intern(self, notationName)))
     585             : 
     586           0 : VOID_HANDLER(XmlDecl,
     587             :              (void *userData,
     588             :               const XML_Char *version,
     589             :               const XML_Char *encoding,
     590             :               int standalone),
     591             :              ("(O&O&i)",
     592             :               conv_string_to_unicode ,version, conv_string_to_unicode ,encoding,
     593           0 :               standalone))
     594             : 
     595             : static PyObject *
     596           0 : conv_content_model(XML_Content * const model,
     597             :                    PyObject *(*conv_string)(const XML_Char *))
     598             : {
     599           0 :     PyObject *result = NULL;
     600           0 :     PyObject *children = PyTuple_New(model->numchildren);
     601             :     int i;
     602             : 
     603           0 :     if (children != NULL) {
     604             :         assert(model->numchildren < INT_MAX);
     605           0 :         for (i = 0; i < (int)model->numchildren; ++i) {
     606           0 :             PyObject *child = conv_content_model(&model->children[i],
     607             :                                                  conv_string);
     608           0 :             if (child == NULL) {
     609           0 :                 Py_XDECREF(children);
     610           0 :                 return NULL;
     611             :             }
     612           0 :             PyTuple_SET_ITEM(children, i, child);
     613             :         }
     614           0 :         result = Py_BuildValue("(iiO&N)",
     615           0 :                                model->type, model->quant,
     616             :                                conv_string,model->name, children);
     617             :     }
     618           0 :     return result;
     619             : }
     620             : 
     621             : static void
     622           0 : my_ElementDeclHandler(void *userData,
     623             :                       const XML_Char *name,
     624             :                       XML_Content *model)
     625             : {
     626           0 :     xmlparseobject *self = (xmlparseobject *)userData;
     627           0 :     PyObject *args = NULL;
     628             : 
     629           0 :     if (have_handler(self, ElementDecl)) {
     630           0 :         PyObject *rv = NULL;
     631             :         PyObject *modelobj, *nameobj;
     632             : 
     633           0 :         if (flush_character_buffer(self) < 0)
     634           0 :             goto finally;
     635           0 :         modelobj = conv_content_model(model, (conv_string_to_unicode));
     636           0 :         if (modelobj == NULL) {
     637           0 :             flag_error(self);
     638           0 :             goto finally;
     639             :         }
     640           0 :         nameobj = string_intern(self, name);
     641           0 :         if (nameobj == NULL) {
     642           0 :             Py_DECREF(modelobj);
     643           0 :             flag_error(self);
     644           0 :             goto finally;
     645             :         }
     646           0 :         args = Py_BuildValue("NN", nameobj, modelobj);
     647           0 :         if (args == NULL) {
     648           0 :             Py_DECREF(modelobj);
     649           0 :             flag_error(self);
     650           0 :             goto finally;
     651             :         }
     652           0 :         self->in_callback = 1;
     653           0 :         rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
     654           0 :                              self->handlers[ElementDecl], args, self);
     655           0 :         self->in_callback = 0;
     656           0 :         if (rv == NULL) {
     657           0 :             flag_error(self);
     658           0 :             goto finally;
     659             :         }
     660           0 :         Py_DECREF(rv);
     661             :     }
     662             :  finally:
     663           0 :     Py_XDECREF(args);
     664           0 :     XML_FreeContentModel(self->itself, model);
     665           0 :     return;
     666             : }
     667             : 
     668           0 : VOID_HANDLER(AttlistDecl,
     669             :              (void *userData,
     670             :               const XML_Char *elname,
     671             :               const XML_Char *attname,
     672             :               const XML_Char *att_type,
     673             :               const XML_Char *dflt,
     674             :               int isrequired),
     675             :              ("(NNO&O&i)",
     676             :               string_intern(self, elname), string_intern(self, attname),
     677             :               conv_string_to_unicode ,att_type, conv_string_to_unicode ,dflt,
     678           0 :               isrequired))
     679             : 
     680             : #if XML_COMBINED_VERSION >= 19504
     681           0 : VOID_HANDLER(SkippedEntity,
     682             :              (void *userData,
     683             :               const XML_Char *entityName,
     684             :               int is_parameter_entity),
     685             :              ("Ni",
     686           0 :               string_intern(self, entityName), is_parameter_entity))
     687             : #endif
     688             : 
     689           0 : VOID_HANDLER(NotationDecl,
     690             :                 (void *userData,
     691             :                         const XML_Char *notationName,
     692             :                         const XML_Char *base,
     693             :                         const XML_Char *systemId,
     694             :                         const XML_Char *publicId),
     695             :                 ("(NNNN)",
     696             :                  string_intern(self, notationName), string_intern(self, base),
     697           0 :                  string_intern(self, systemId), string_intern(self, publicId)))
     698             : 
     699           0 : VOID_HANDLER(StartNamespaceDecl,
     700             :                 (void *userData,
     701             :                       const XML_Char *prefix,
     702             :                       const XML_Char *uri),
     703             :                 ("(NN)",
     704           0 :                  string_intern(self, prefix), string_intern(self, uri)))
     705             : 
     706           0 : VOID_HANDLER(EndNamespaceDecl,
     707             :                 (void *userData,
     708             :                     const XML_Char *prefix),
     709           0 :                 ("(N)", string_intern(self, prefix)))
     710             : 
     711           0 : VOID_HANDLER(Comment,
     712             :                (void *userData, const XML_Char *data),
     713           0 :                 ("(O&)", conv_string_to_unicode ,data))
     714             : 
     715           0 : VOID_HANDLER(StartCdataSection,
     716             :                (void *userData),
     717           0 :                 ("()"))
     718             : 
     719           0 : VOID_HANDLER(EndCdataSection,
     720             :                (void *userData),
     721           0 :                 ("()"))
     722             : 
     723           0 : VOID_HANDLER(Default,
     724             :               (void *userData, const XML_Char *s, int len),
     725           0 :               ("(N)", (conv_string_len_to_unicode(s,len))))
     726             : 
     727           0 : VOID_HANDLER(DefaultHandlerExpand,
     728             :               (void *userData, const XML_Char *s, int len),
     729           0 :               ("(N)", (conv_string_len_to_unicode(s,len))))
     730             : 
     731           0 : INT_HANDLER(NotStandalone,
     732             :                 (void *userData),
     733           0 :                 ("()"))
     734             : 
     735           0 : RC_HANDLER(int, ExternalEntityRef,
     736             :                 (XML_Parser parser,
     737             :                     const XML_Char *context,
     738             :                     const XML_Char *base,
     739             :                     const XML_Char *systemId,
     740             :                     const XML_Char *publicId),
     741             :                 int rc=0;,
     742             :                 ("(O&NNN)",
     743             :                  conv_string_to_unicode ,context, string_intern(self, base),
     744             :                  string_intern(self, systemId), string_intern(self, publicId)),
     745             :                 rc = PyLong_AsLong(rv);, rc,
     746           0 :                 XML_GetUserData(parser))
     747             : 
     748             : /* XXX UnknownEncodingHandler */
     749             : 
     750           0 : VOID_HANDLER(StartDoctypeDecl,
     751             :              (void *userData, const XML_Char *doctypeName,
     752             :               const XML_Char *sysid, const XML_Char *pubid,
     753             :               int has_internal_subset),
     754             :              ("(NNNi)", string_intern(self, doctypeName),
     755             :               string_intern(self, sysid), string_intern(self, pubid),
     756           0 :               has_internal_subset))
     757             : 
     758           0 : VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
     759             : 
     760             : /* ---------------------------------------------------------------- */
     761             : 
     762             : static PyObject *
     763           0 : get_parse_result(xmlparseobject *self, int rv)
     764             : {
     765           0 :     if (PyErr_Occurred()) {
     766           0 :         return NULL;
     767             :     }
     768           0 :     if (rv == 0) {
     769           0 :         return set_error(self, XML_GetErrorCode(self->itself));
     770             :     }
     771           0 :     if (flush_character_buffer(self) < 0) {
     772           0 :         return NULL;
     773             :     }
     774           0 :     return PyLong_FromLong(rv);
     775             : }
     776             : 
     777             : PyDoc_STRVAR(xmlparse_Parse__doc__,
     778             : "Parse(data[, isfinal])\n\
     779             : Parse XML data.  `isfinal' should be true at end of input.");
     780             : 
     781             : static PyObject *
     782           0 : xmlparse_Parse(xmlparseobject *self, PyObject *args)
     783             : {
     784             :     char *s;
     785             :     int slen;
     786           0 :     int isFinal = 0;
     787             : 
     788           0 :     if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
     789           0 :         return NULL;
     790             : 
     791           0 :     return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
     792             : }
     793             : 
     794             : /* File reading copied from cPickle */
     795             : 
     796             : #define BUF_SIZE 2048
     797             : 
     798             : static int
     799           0 : readinst(char *buf, int buf_size, PyObject *meth)
     800             : {
     801             :     PyObject *str;
     802             :     Py_ssize_t len;
     803             :     char *ptr;
     804             : 
     805           0 :     str = PyObject_CallFunction(meth, "n", buf_size);
     806           0 :     if (str == NULL)
     807           0 :         goto error;
     808             : 
     809           0 :     if (PyBytes_Check(str))
     810           0 :         ptr = PyBytes_AS_STRING(str);
     811           0 :     else if (PyByteArray_Check(str))
     812           0 :         ptr = PyByteArray_AS_STRING(str);
     813             :     else {
     814           0 :         PyErr_Format(PyExc_TypeError,
     815             :                      "read() did not return a bytes object (type=%.400s)",
     816           0 :                      Py_TYPE(str)->tp_name);
     817           0 :         goto error;
     818             :     }
     819           0 :     len = Py_SIZE(str);
     820           0 :     if (len > buf_size) {
     821           0 :         PyErr_Format(PyExc_ValueError,
     822             :                      "read() returned too much data: "
     823             :                      "%i bytes requested, %zd returned",
     824             :                      buf_size, len);
     825           0 :         goto error;
     826             :     }
     827           0 :     memcpy(buf, ptr, len);
     828           0 :     Py_DECREF(str);
     829             :     /* len <= buf_size <= INT_MAX */
     830           0 :     return (int)len;
     831             : 
     832             : error:
     833           0 :     Py_XDECREF(str);
     834           0 :     return -1;
     835             : }
     836             : 
     837             : PyDoc_STRVAR(xmlparse_ParseFile__doc__,
     838             : "ParseFile(file)\n\
     839             : Parse XML data from file-like object.");
     840             : 
     841             : static PyObject *
     842           0 : xmlparse_ParseFile(xmlparseobject *self, PyObject *f)
     843             : {
     844           0 :     int rv = 1;
     845           0 :     PyObject *readmethod = NULL;
     846             :     _Py_IDENTIFIER(read);
     847             : 
     848           0 :     readmethod = _PyObject_GetAttrId(f, &PyId_read);
     849           0 :     if (readmethod == NULL) {
     850           0 :         PyErr_SetString(PyExc_TypeError,
     851             :                         "argument must have 'read' attribute");
     852           0 :         return NULL;
     853             :     }
     854             :     for (;;) {
     855             :         int bytes_read;
     856           0 :         void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
     857           0 :         if (buf == NULL) {
     858           0 :             Py_XDECREF(readmethod);
     859           0 :             return PyErr_NoMemory();
     860             :         }
     861             : 
     862           0 :         bytes_read = readinst(buf, BUF_SIZE, readmethod);
     863           0 :         if (bytes_read < 0) {
     864           0 :             Py_DECREF(readmethod);
     865           0 :             return NULL;
     866             :         }
     867           0 :         rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
     868           0 :         if (PyErr_Occurred()) {
     869           0 :             Py_XDECREF(readmethod);
     870           0 :             return NULL;
     871             :         }
     872             : 
     873           0 :         if (!rv || bytes_read == 0)
     874             :             break;
     875           0 :     }
     876           0 :     Py_XDECREF(readmethod);
     877           0 :     return get_parse_result(self, rv);
     878             : }
     879             : 
     880             : PyDoc_STRVAR(xmlparse_SetBase__doc__,
     881             : "SetBase(base_url)\n\
     882             : Set the base URL for the parser.");
     883             : 
     884             : static PyObject *
     885           0 : xmlparse_SetBase(xmlparseobject *self, PyObject *args)
     886             : {
     887             :     char *base;
     888             : 
     889           0 :     if (!PyArg_ParseTuple(args, "s:SetBase", &base))
     890           0 :         return NULL;
     891           0 :     if (!XML_SetBase(self->itself, base)) {
     892           0 :         return PyErr_NoMemory();
     893             :     }
     894           0 :     Py_INCREF(Py_None);
     895           0 :     return Py_None;
     896             : }
     897             : 
     898             : PyDoc_STRVAR(xmlparse_GetBase__doc__,
     899             : "GetBase() -> url\n\
     900             : Return base URL string for the parser.");
     901             : 
     902             : static PyObject *
     903           0 : xmlparse_GetBase(xmlparseobject *self, PyObject *unused)
     904             : {
     905           0 :     return Py_BuildValue("z", XML_GetBase(self->itself));
     906             : }
     907             : 
     908             : PyDoc_STRVAR(xmlparse_GetInputContext__doc__,
     909             : "GetInputContext() -> string\n\
     910             : Return the untranslated text of the input that caused the current event.\n\
     911             : If the event was generated by a large amount of text (such as a start tag\n\
     912             : for an element with many attributes), not all of the text may be available.");
     913             : 
     914             : static PyObject *
     915           0 : xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
     916             : {
     917           0 :     if (self->in_callback) {
     918             :         int offset, size;
     919           0 :         const char *buffer
     920           0 :             = XML_GetInputContext(self->itself, &offset, &size);
     921             : 
     922           0 :         if (buffer != NULL)
     923           0 :             return PyBytes_FromStringAndSize(buffer + offset,
     924             :                                               size - offset);
     925             :         else
     926           0 :             Py_RETURN_NONE;
     927             :     }
     928             :     else
     929           0 :         Py_RETURN_NONE;
     930             : }
     931             : 
     932             : PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
     933             : "ExternalEntityParserCreate(context[, encoding])\n\
     934             : Create a parser for parsing an external entity based on the\n\
     935             : information passed to the ExternalEntityRefHandler.");
     936             : 
     937             : static PyObject *
     938           0 : xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
     939             : {
     940             :     char *context;
     941           0 :     char *encoding = NULL;
     942             :     xmlparseobject *new_parser;
     943             :     int i;
     944             : 
     945           0 :     if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
     946             :                           &context, &encoding)) {
     947           0 :         return NULL;
     948             :     }
     949             : 
     950           0 :     new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
     951           0 :     if (new_parser == NULL)
     952           0 :         return NULL;
     953           0 :     new_parser->buffer_size = self->buffer_size;
     954           0 :     new_parser->buffer_used = 0;
     955           0 :     new_parser->buffer = NULL;
     956           0 :     new_parser->ordered_attributes = self->ordered_attributes;
     957           0 :     new_parser->specified_attributes = self->specified_attributes;
     958           0 :     new_parser->in_callback = 0;
     959           0 :     new_parser->ns_prefixes = self->ns_prefixes;
     960           0 :     new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
     961             :                                                         encoding);
     962           0 :     new_parser->handlers = 0;
     963           0 :     new_parser->intern = self->intern;
     964           0 :     Py_XINCREF(new_parser->intern);
     965           0 :     PyObject_GC_Track(new_parser);
     966             : 
     967           0 :     if (self->buffer != NULL) {
     968           0 :         new_parser->buffer = malloc(new_parser->buffer_size);
     969           0 :         if (new_parser->buffer == NULL) {
     970           0 :             Py_DECREF(new_parser);
     971           0 :             return PyErr_NoMemory();
     972             :         }
     973             :     }
     974           0 :     if (!new_parser->itself) {
     975           0 :         Py_DECREF(new_parser);
     976           0 :         return PyErr_NoMemory();
     977             :     }
     978             : 
     979           0 :     XML_SetUserData(new_parser->itself, (void *)new_parser);
     980             : 
     981             :     /* allocate and clear handlers first */
     982           0 :     for (i = 0; handler_info[i].name != NULL; i++)
     983             :         /* do nothing */;
     984             : 
     985           0 :     new_parser->handlers = malloc(sizeof(PyObject *) * i);
     986           0 :     if (!new_parser->handlers) {
     987           0 :         Py_DECREF(new_parser);
     988           0 :         return PyErr_NoMemory();
     989             :     }
     990           0 :     clear_handlers(new_parser, 1);
     991             : 
     992             :     /* then copy handlers from self */
     993           0 :     for (i = 0; handler_info[i].name != NULL; i++) {
     994           0 :         PyObject *handler = self->handlers[i];
     995           0 :         if (handler != NULL) {
     996           0 :             Py_INCREF(handler);
     997           0 :             new_parser->handlers[i] = handler;
     998           0 :             handler_info[i].setter(new_parser->itself,
     999             :                                    handler_info[i].handler);
    1000             :         }
    1001             :     }
    1002           0 :     return (PyObject *)new_parser;
    1003             : }
    1004             : 
    1005             : PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
    1006             : "SetParamEntityParsing(flag) -> success\n\
    1007             : Controls parsing of parameter entities (including the external DTD\n\
    1008             : subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
    1009             : XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
    1010             : XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
    1011             : was successful.");
    1012             : 
    1013             : static PyObject*
    1014           0 : xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
    1015             : {
    1016             :     int flag;
    1017           0 :     if (!PyArg_ParseTuple(args, "i", &flag))
    1018           0 :         return NULL;
    1019           0 :     flag = XML_SetParamEntityParsing(p->itself, flag);
    1020           0 :     return PyLong_FromLong(flag);
    1021             : }
    1022             : 
    1023             : 
    1024             : #if XML_COMBINED_VERSION >= 19505
    1025             : PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
    1026             : "UseForeignDTD([flag])\n\
    1027             : Allows the application to provide an artificial external subset if one is\n\
    1028             : not specified as part of the document instance.  This readily allows the\n\
    1029             : use of a 'default' document type controlled by the application, while still\n\
    1030             : getting the advantage of providing document type information to the parser.\n\
    1031             : 'flag' defaults to True if not provided.");
    1032             : 
    1033             : static PyObject *
    1034           0 : xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
    1035             : {
    1036           0 :     int flag = 1;
    1037             :     enum XML_Error rc;
    1038           0 :     if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", &flag))
    1039           0 :         return NULL;
    1040           0 :     rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);
    1041           0 :     if (rc != XML_ERROR_NONE) {
    1042           0 :         return set_error(self, rc);
    1043             :     }
    1044           0 :     Py_INCREF(Py_None);
    1045           0 :     return Py_None;
    1046             : }
    1047             : #endif
    1048             : 
    1049             : static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs);
    1050             : 
    1051             : static struct PyMethodDef xmlparse_methods[] = {
    1052             :     {"Parse",     (PyCFunction)xmlparse_Parse,
    1053             :                   METH_VARARGS, xmlparse_Parse__doc__},
    1054             :     {"ParseFile", (PyCFunction)xmlparse_ParseFile,
    1055             :                   METH_O,       xmlparse_ParseFile__doc__},
    1056             :     {"SetBase",   (PyCFunction)xmlparse_SetBase,
    1057             :                   METH_VARARGS, xmlparse_SetBase__doc__},
    1058             :     {"GetBase",   (PyCFunction)xmlparse_GetBase,
    1059             :                   METH_NOARGS, xmlparse_GetBase__doc__},
    1060             :     {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
    1061             :                   METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
    1062             :     {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
    1063             :                   METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
    1064             :     {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
    1065             :                   METH_NOARGS, xmlparse_GetInputContext__doc__},
    1066             : #if XML_COMBINED_VERSION >= 19505
    1067             :     {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
    1068             :                   METH_VARARGS, xmlparse_UseForeignDTD__doc__},
    1069             : #endif
    1070             :     {"__dir__", xmlparse_dir, METH_NOARGS},
    1071             :     {NULL,        NULL}         /* sentinel */
    1072             : };
    1073             : 
    1074             : /* ---------- */
    1075             : 
    1076             : 
    1077             : 
    1078             : /* pyexpat international encoding support.
    1079             :    Make it as simple as possible.
    1080             : */
    1081             : 
    1082             : static char template_buffer[257];
    1083             : 
    1084             : static void
    1085           0 : init_template_buffer(void)
    1086             : {
    1087             :     int i;
    1088           0 :     for (i = 0; i < 256; i++) {
    1089           0 :         template_buffer[i] = i;
    1090             :     }
    1091           0 :     template_buffer[256] = 0;
    1092           0 : }
    1093             : 
    1094             : static int
    1095           0 : PyUnknownEncodingHandler(void *encodingHandlerData,
    1096             :                          const XML_Char *name,
    1097             :                          XML_Encoding *info)
    1098             : {
    1099           0 :     PyUnicodeObject *_u_string = NULL;
    1100           0 :     int result = 0;
    1101             :     int i;
    1102             :     int kind;
    1103             :     void *data;
    1104             : 
    1105             :     /* Yes, supports only 8bit encodings */
    1106           0 :     _u_string = (PyUnicodeObject *)
    1107             :         PyUnicode_Decode(template_buffer, 256, name, "replace");
    1108             : 
    1109           0 :     if (_u_string == NULL || PyUnicode_READY(_u_string) == -1)
    1110           0 :         return result;
    1111             : 
    1112           0 :     kind = PyUnicode_KIND(_u_string);
    1113           0 :     data = PyUnicode_DATA(_u_string);
    1114             : 
    1115           0 :     for (i = 0; i < 256; i++) {
    1116             :         /* Stupid to access directly, but fast */
    1117           0 :         Py_UCS4 c = PyUnicode_READ(kind, data, i);
    1118           0 :         if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
    1119           0 :             info->map[i] = -1;
    1120             :         else
    1121           0 :             info->map[i] = c;
    1122             :     }
    1123           0 :     info->data = NULL;
    1124           0 :     info->convert = NULL;
    1125           0 :     info->release = NULL;
    1126           0 :     result = 1;
    1127           0 :     Py_DECREF(_u_string);
    1128           0 :     return result;
    1129             : }
    1130             : 
    1131             : 
    1132             : static PyObject *
    1133           0 : newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
    1134             : {
    1135             :     int i;
    1136             :     xmlparseobject *self;
    1137             : 
    1138           0 :     self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
    1139           0 :     if (self == NULL)
    1140           0 :         return NULL;
    1141             : 
    1142           0 :     self->buffer = NULL;
    1143           0 :     self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
    1144           0 :     self->buffer_used = 0;
    1145           0 :     self->ordered_attributes = 0;
    1146           0 :     self->specified_attributes = 0;
    1147           0 :     self->in_callback = 0;
    1148           0 :     self->ns_prefixes = 0;
    1149           0 :     self->handlers = NULL;
    1150           0 :     if (namespace_separator != NULL) {
    1151           0 :         self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
    1152             :     }
    1153             :     else {
    1154           0 :         self->itself = XML_ParserCreate(encoding);
    1155             :     }
    1156             : #if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)
    1157             :     /* This feature was added upstream in libexpat 2.1.0.  Our expat copy
    1158             :      * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
    1159             :      * to indicate that we can still use it. */
    1160           0 :     XML_SetHashSalt(self->itself,
    1161           0 :                     (unsigned long)_Py_HashSecret.prefix);
    1162             : #endif
    1163           0 :     self->intern = intern;
    1164           0 :     Py_XINCREF(self->intern);
    1165           0 :     PyObject_GC_Track(self);
    1166           0 :     if (self->itself == NULL) {
    1167           0 :         PyErr_SetString(PyExc_RuntimeError,
    1168             :                         "XML_ParserCreate failed");
    1169           0 :         Py_DECREF(self);
    1170           0 :         return NULL;
    1171             :     }
    1172           0 :     XML_SetUserData(self->itself, (void *)self);
    1173           0 :     XML_SetUnknownEncodingHandler(self->itself,
    1174             :                   (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
    1175             : 
    1176           0 :     for (i = 0; handler_info[i].name != NULL; i++)
    1177             :         /* do nothing */;
    1178             : 
    1179           0 :     self->handlers = malloc(sizeof(PyObject *) * i);
    1180           0 :     if (!self->handlers) {
    1181           0 :         Py_DECREF(self);
    1182           0 :         return PyErr_NoMemory();
    1183             :     }
    1184           0 :     clear_handlers(self, 1);
    1185             : 
    1186           0 :     return (PyObject*)self;
    1187             : }
    1188             : 
    1189             : 
    1190             : static void
    1191           0 : xmlparse_dealloc(xmlparseobject *self)
    1192             : {
    1193             :     int i;
    1194           0 :     PyObject_GC_UnTrack(self);
    1195           0 :     if (self->itself != NULL)
    1196           0 :         XML_ParserFree(self->itself);
    1197           0 :     self->itself = NULL;
    1198             : 
    1199           0 :     if (self->handlers != NULL) {
    1200             :         PyObject *temp;
    1201           0 :         for (i = 0; handler_info[i].name != NULL; i++) {
    1202           0 :             temp = self->handlers[i];
    1203           0 :             self->handlers[i] = NULL;
    1204           0 :             Py_XDECREF(temp);
    1205             :         }
    1206           0 :         free(self->handlers);
    1207           0 :         self->handlers = NULL;
    1208             :     }
    1209           0 :     if (self->buffer != NULL) {
    1210           0 :         free(self->buffer);
    1211           0 :         self->buffer = NULL;
    1212             :     }
    1213           0 :     Py_XDECREF(self->intern);
    1214           0 :     PyObject_GC_Del(self);
    1215           0 : }
    1216             : 
    1217             : static int
    1218           0 : handlername2int(PyObject *name)
    1219             : {
    1220             :     int i;
    1221           0 :     for (i = 0; handler_info[i].name != NULL; i++) {
    1222           0 :         if (PyUnicode_CompareWithASCIIString(
    1223             :                 name, handler_info[i].name) == 0) {
    1224           0 :             return i;
    1225             :         }
    1226             :     }
    1227           0 :     return -1;
    1228             : }
    1229             : 
    1230             : static PyObject *
    1231           0 : get_pybool(int istrue)
    1232             : {
    1233           0 :     PyObject *result = istrue ? Py_True : Py_False;
    1234           0 :     Py_INCREF(result);
    1235           0 :     return result;
    1236             : }
    1237             : 
    1238             : static PyObject *
    1239           0 : xmlparse_getattro(xmlparseobject *self, PyObject *nameobj)
    1240             : {
    1241             :     Py_UCS4 first_char;
    1242           0 :     int handlernum = -1;
    1243             : 
    1244           0 :     if (!PyUnicode_Check(nameobj))
    1245           0 :         goto generic;
    1246           0 :     if (PyUnicode_READY(nameobj))
    1247           0 :         return NULL;
    1248             : 
    1249           0 :     handlernum = handlername2int(nameobj);
    1250             : 
    1251           0 :     if (handlernum != -1) {
    1252           0 :         PyObject *result = self->handlers[handlernum];
    1253           0 :         if (result == NULL)
    1254           0 :             result = Py_None;
    1255           0 :         Py_INCREF(result);
    1256           0 :         return result;
    1257             :     }
    1258             : 
    1259           0 :     first_char = PyUnicode_READ_CHAR(nameobj, 0);
    1260           0 :     if (first_char == 'E') {
    1261           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorCode") == 0)
    1262           0 :             return PyLong_FromLong((long)
    1263           0 :                                   XML_GetErrorCode(self->itself));
    1264           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorLineNumber") == 0)
    1265           0 :             return PyLong_FromLong((long)
    1266           0 :                                   XML_GetErrorLineNumber(self->itself));
    1267           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorColumnNumber") == 0)
    1268           0 :             return PyLong_FromLong((long)
    1269           0 :                                   XML_GetErrorColumnNumber(self->itself));
    1270           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "ErrorByteIndex") == 0)
    1271           0 :             return PyLong_FromLong((long)
    1272             :                                   XML_GetErrorByteIndex(self->itself));
    1273             :     }
    1274           0 :     if (first_char == 'C') {
    1275           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentLineNumber") == 0)
    1276           0 :             return PyLong_FromLong((long)
    1277           0 :                                   XML_GetCurrentLineNumber(self->itself));
    1278           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentColumnNumber") == 0)
    1279           0 :             return PyLong_FromLong((long)
    1280           0 :                                   XML_GetCurrentColumnNumber(self->itself));
    1281           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "CurrentByteIndex") == 0)
    1282           0 :             return PyLong_FromLong((long)
    1283             :                                   XML_GetCurrentByteIndex(self->itself));
    1284             :     }
    1285           0 :     if (first_char == 'b') {
    1286           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_size") == 0)
    1287           0 :             return PyLong_FromLong((long) self->buffer_size);
    1288           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_text") == 0)
    1289           0 :             return get_pybool(self->buffer != NULL);
    1290           0 :         if (PyUnicode_CompareWithASCIIString(nameobj, "buffer_used") == 0)
    1291           0 :             return PyLong_FromLong((long) self->buffer_used);
    1292             :     }
    1293           0 :     if (PyUnicode_CompareWithASCIIString(nameobj, "namespace_prefixes") == 0)
    1294           0 :         return get_pybool(self->ns_prefixes);
    1295           0 :     if (PyUnicode_CompareWithASCIIString(nameobj, "ordered_attributes") == 0)
    1296           0 :         return get_pybool(self->ordered_attributes);
    1297           0 :     if (PyUnicode_CompareWithASCIIString(nameobj, "specified_attributes") == 0)
    1298           0 :         return get_pybool((long) self->specified_attributes);
    1299           0 :     if (PyUnicode_CompareWithASCIIString(nameobj, "intern") == 0) {
    1300           0 :         if (self->intern == NULL) {
    1301           0 :             Py_INCREF(Py_None);
    1302           0 :             return Py_None;
    1303             :         }
    1304             :         else {
    1305           0 :             Py_INCREF(self->intern);
    1306           0 :             return self->intern;
    1307             :         }
    1308             :     }
    1309             :   generic:
    1310           0 :     return PyObject_GenericGetAttr((PyObject*)self, nameobj);
    1311             : }
    1312             : 
    1313             : static PyObject *
    1314           0 : xmlparse_dir(PyObject *self, PyObject* noargs)
    1315             : {
    1316             : #define APPEND(list, str)                               \
    1317             :         do {                                            \
    1318             :                 PyObject *o = PyUnicode_FromString(str);        \
    1319             :                 if (o != NULL)                          \
    1320             :                         PyList_Append(list, o);         \
    1321             :                 Py_XDECREF(o);                          \
    1322             :         } while (0)
    1323             : 
    1324             :     int i;
    1325           0 :     PyObject *rc = PyList_New(0);
    1326           0 :     if (!rc)
    1327           0 :         return NULL;
    1328           0 :     for (i = 0; handler_info[i].name != NULL; i++) {
    1329           0 :         PyObject *o = get_handler_name(&handler_info[i]);
    1330           0 :         if (o != NULL)
    1331           0 :             PyList_Append(rc, o);
    1332           0 :         Py_XDECREF(o);
    1333             :     }
    1334           0 :     APPEND(rc, "ErrorCode");
    1335           0 :     APPEND(rc, "ErrorLineNumber");
    1336           0 :     APPEND(rc, "ErrorColumnNumber");
    1337           0 :     APPEND(rc, "ErrorByteIndex");
    1338           0 :     APPEND(rc, "CurrentLineNumber");
    1339           0 :     APPEND(rc, "CurrentColumnNumber");
    1340           0 :     APPEND(rc, "CurrentByteIndex");
    1341           0 :     APPEND(rc, "buffer_size");
    1342           0 :     APPEND(rc, "buffer_text");
    1343           0 :     APPEND(rc, "buffer_used");
    1344           0 :     APPEND(rc, "namespace_prefixes");
    1345           0 :     APPEND(rc, "ordered_attributes");
    1346           0 :     APPEND(rc, "specified_attributes");
    1347           0 :     APPEND(rc, "intern");
    1348             : 
    1349             : #undef APPEND
    1350             : 
    1351           0 :     if (PyErr_Occurred()) {
    1352           0 :         Py_DECREF(rc);
    1353           0 :         rc = NULL;
    1354             :     }
    1355             : 
    1356           0 :     return rc;
    1357             : }
    1358             : 
    1359             : static int
    1360           0 : sethandler(xmlparseobject *self, PyObject *name, PyObject* v)
    1361             : {
    1362           0 :     int handlernum = handlername2int(name);
    1363           0 :     if (handlernum >= 0) {
    1364           0 :         xmlhandler c_handler = NULL;
    1365           0 :         PyObject *temp = self->handlers[handlernum];
    1366             : 
    1367           0 :         if (v == Py_None) {
    1368             :             /* If this is the character data handler, and a character
    1369             :                data handler is already active, we need to be more
    1370             :                careful.  What we can safely do is replace the existing
    1371             :                character data handler callback function with a no-op
    1372             :                function that will refuse to call Python.  The downside
    1373             :                is that this doesn't completely remove the character
    1374             :                data handler from the C layer if there's any callback
    1375             :                active, so Expat does a little more work than it
    1376             :                otherwise would, but that's really an odd case.  A more
    1377             :                elaborate system of handlers and state could remove the
    1378             :                C handler more effectively. */
    1379           0 :             if (handlernum == CharacterData && self->in_callback)
    1380           0 :                 c_handler = noop_character_data_handler;
    1381           0 :             v = NULL;
    1382             :         }
    1383           0 :         else if (v != NULL) {
    1384           0 :             Py_INCREF(v);
    1385           0 :             c_handler = handler_info[handlernum].handler;
    1386             :         }
    1387           0 :         self->handlers[handlernum] = v;
    1388           0 :         Py_XDECREF(temp);
    1389           0 :         handler_info[handlernum].setter(self->itself, c_handler);
    1390           0 :         return 1;
    1391             :     }
    1392           0 :     return 0;
    1393             : }
    1394             : 
    1395             : static int
    1396           0 : xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
    1397             : {
    1398             :     /* Set attribute 'name' to value 'v'. v==NULL means delete */
    1399           0 :     if (v == NULL) {
    1400           0 :         PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
    1401           0 :         return -1;
    1402             :     }
    1403             :     assert(PyUnicode_Check(name));
    1404           0 :     if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
    1405           0 :         int b = PyObject_IsTrue(v);
    1406           0 :         if (b < 0)
    1407           0 :             return -1;
    1408           0 :         if (b) {
    1409           0 :             if (self->buffer == NULL) {
    1410           0 :                 self->buffer = malloc(self->buffer_size);
    1411           0 :                 if (self->buffer == NULL) {
    1412           0 :                     PyErr_NoMemory();
    1413           0 :                     return -1;
    1414             :                 }
    1415           0 :                 self->buffer_used = 0;
    1416             :             }
    1417             :         }
    1418           0 :         else if (self->buffer != NULL) {
    1419           0 :             if (flush_character_buffer(self) < 0)
    1420           0 :                 return -1;
    1421           0 :             free(self->buffer);
    1422           0 :             self->buffer = NULL;
    1423             :         }
    1424           0 :         return 0;
    1425             :     }
    1426           0 :     if (PyUnicode_CompareWithASCIIString(name, "namespace_prefixes") == 0) {
    1427           0 :         int b = PyObject_IsTrue(v);
    1428           0 :         if (b < 0)
    1429           0 :             return -1;
    1430           0 :         self->ns_prefixes = b;
    1431           0 :         XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
    1432           0 :         return 0;
    1433             :     }
    1434           0 :     if (PyUnicode_CompareWithASCIIString(name, "ordered_attributes") == 0) {
    1435           0 :         int b = PyObject_IsTrue(v);
    1436           0 :         if (b < 0)
    1437           0 :             return -1;
    1438           0 :         self->ordered_attributes = b;
    1439           0 :         return 0;
    1440             :     }
    1441           0 :     if (PyUnicode_CompareWithASCIIString(name, "specified_attributes") == 0) {
    1442           0 :         int b = PyObject_IsTrue(v);
    1443           0 :         if (b < 0)
    1444           0 :             return -1;
    1445           0 :         self->specified_attributes = b;
    1446           0 :         return 0;
    1447             :     }
    1448             : 
    1449           0 :     if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
    1450             :       long new_buffer_size;
    1451           0 :       if (!PyLong_Check(v)) {
    1452           0 :         PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
    1453           0 :         return -1;
    1454             :       }
    1455             : 
    1456           0 :       new_buffer_size=PyLong_AS_LONG(v);
    1457             :       /* trivial case -- no change */
    1458           0 :       if (new_buffer_size == self->buffer_size) {
    1459           0 :         return 0;
    1460             :       }
    1461             : 
    1462           0 :       if (new_buffer_size <= 0) {
    1463           0 :         PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
    1464           0 :         return -1;
    1465             :       }
    1466             : 
    1467             :       /* check maximum */
    1468             :       if (new_buffer_size > INT_MAX) {
    1469             :         char errmsg[100];
    1470             :         sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
    1471             :         PyErr_SetString(PyExc_ValueError, errmsg);
    1472             :         return -1;
    1473             :       }
    1474             : 
    1475           0 :       if (self->buffer != NULL) {
    1476             :         /* there is already a buffer */
    1477           0 :         if (self->buffer_used != 0) {
    1478           0 :           flush_character_buffer(self);
    1479             :         }
    1480             :         /* free existing buffer */
    1481           0 :         free(self->buffer);
    1482             :       }
    1483           0 :       self->buffer = malloc(new_buffer_size);
    1484           0 :       if (self->buffer == NULL) {
    1485           0 :         PyErr_NoMemory();
    1486           0 :         return -1;
    1487             :       }
    1488           0 :       self->buffer_size = new_buffer_size;
    1489           0 :       return 0;
    1490             :     }
    1491             : 
    1492           0 :     if (PyUnicode_CompareWithASCIIString(name, "CharacterDataHandler") == 0) {
    1493             :         /* If we're changing the character data handler, flush all
    1494             :          * cached data with the old handler.  Not sure there's a
    1495             :          * "right" thing to do, though, but this probably won't
    1496             :          * happen.
    1497             :          */
    1498           0 :         if (flush_character_buffer(self) < 0)
    1499           0 :             return -1;
    1500             :     }
    1501           0 :     if (sethandler(self, name, v)) {
    1502           0 :         return 0;
    1503             :     }
    1504           0 :     PyErr_SetObject(PyExc_AttributeError, name);
    1505           0 :     return -1;
    1506             : }
    1507             : 
    1508             : static int
    1509           0 : xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
    1510             : {
    1511             :     int i;
    1512           0 :     for (i = 0; handler_info[i].name != NULL; i++)
    1513           0 :         Py_VISIT(op->handlers[i]);
    1514           0 :     return 0;
    1515             : }
    1516             : 
    1517             : static int
    1518           0 : xmlparse_clear(xmlparseobject *op)
    1519             : {
    1520           0 :     clear_handlers(op, 0);
    1521           0 :     Py_CLEAR(op->intern);
    1522           0 :     return 0;
    1523             : }
    1524             : 
    1525             : PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
    1526             : 
    1527             : static PyTypeObject Xmlparsetype = {
    1528             :         PyVarObject_HEAD_INIT(NULL, 0)
    1529             :         "pyexpat.xmlparser",            /*tp_name*/
    1530             :         sizeof(xmlparseobject),         /*tp_basicsize*/
    1531             :         0,                              /*tp_itemsize*/
    1532             :         /* methods */
    1533             :         (destructor)xmlparse_dealloc,   /*tp_dealloc*/
    1534             :         (printfunc)0,           /*tp_print*/
    1535             :         0,                      /*tp_getattr*/
    1536             :         0,  /*tp_setattr*/
    1537             :         0,                      /*tp_reserved*/
    1538             :         (reprfunc)0,            /*tp_repr*/
    1539             :         0,                      /*tp_as_number*/
    1540             :         0,              /*tp_as_sequence*/
    1541             :         0,              /*tp_as_mapping*/
    1542             :         (hashfunc)0,            /*tp_hash*/
    1543             :         (ternaryfunc)0,         /*tp_call*/
    1544             :         (reprfunc)0,            /*tp_str*/
    1545             :         (getattrofunc)xmlparse_getattro, /* tp_getattro */
    1546             :         (setattrofunc)xmlparse_setattro,              /* tp_setattro */
    1547             :         0,              /* tp_as_buffer */
    1548             :         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
    1549             :         Xmlparsetype__doc__, /* tp_doc - Documentation string */
    1550             :         (traverseproc)xmlparse_traverse,        /* tp_traverse */
    1551             :         (inquiry)xmlparse_clear,                /* tp_clear */
    1552             :         0,                              /* tp_richcompare */
    1553             :         0,                              /* tp_weaklistoffset */
    1554             :         0,                              /* tp_iter */
    1555             :         0,                              /* tp_iternext */
    1556             :         xmlparse_methods,               /* tp_methods */
    1557             : };
    1558             : 
    1559             : /* End of code for xmlparser objects */
    1560             : /* -------------------------------------------------------- */
    1561             : 
    1562             : PyDoc_STRVAR(pyexpat_ParserCreate__doc__,
    1563             : "ParserCreate([encoding[, namespace_separator]]) -> parser\n\
    1564             : Return a new XML parser object.");
    1565             : 
    1566             : static PyObject *
    1567           0 : pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
    1568             : {
    1569           0 :     char *encoding = NULL;
    1570           0 :     char *namespace_separator = NULL;
    1571           0 :     PyObject *intern = NULL;
    1572             :     PyObject *result;
    1573           0 :     int intern_decref = 0;
    1574             :     static char *kwlist[] = {"encoding", "namespace_separator",
    1575             :                                    "intern", NULL};
    1576             : 
    1577           0 :     if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
    1578             :                                      &encoding, &namespace_separator, &intern))
    1579           0 :         return NULL;
    1580           0 :     if (namespace_separator != NULL
    1581           0 :         && strlen(namespace_separator) > 1) {
    1582           0 :         PyErr_SetString(PyExc_ValueError,
    1583             :                         "namespace_separator must be at most one"
    1584             :                         " character, omitted, or None");
    1585           0 :         return NULL;
    1586             :     }
    1587             :     /* Explicitly passing None means no interning is desired.
    1588             :        Not passing anything means that a new dictionary is used. */
    1589           0 :     if (intern == Py_None)
    1590           0 :         intern = NULL;
    1591           0 :     else if (intern == NULL) {
    1592           0 :         intern = PyDict_New();
    1593           0 :         if (!intern)
    1594           0 :             return NULL;
    1595           0 :         intern_decref = 1;
    1596             :     }
    1597           0 :     else if (!PyDict_Check(intern)) {
    1598           0 :         PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
    1599           0 :         return NULL;
    1600             :     }
    1601             : 
    1602           0 :     result = newxmlparseobject(encoding, namespace_separator, intern);
    1603           0 :     if (intern_decref) {
    1604           0 :         Py_DECREF(intern);
    1605             :     }
    1606           0 :     return result;
    1607             : }
    1608             : 
    1609             : PyDoc_STRVAR(pyexpat_ErrorString__doc__,
    1610             : "ErrorString(errno) -> string\n\
    1611             : Returns string error for given number.");
    1612             : 
    1613             : static PyObject *
    1614           0 : pyexpat_ErrorString(PyObject *self, PyObject *args)
    1615             : {
    1616           0 :     long code = 0;
    1617             : 
    1618           0 :     if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
    1619           0 :         return NULL;
    1620           0 :     return Py_BuildValue("z", XML_ErrorString((int)code));
    1621             : }
    1622             : 
    1623             : /* List of methods defined in the module */
    1624             : 
    1625             : static struct PyMethodDef pyexpat_methods[] = {
    1626             :     {"ParserCreate",    (PyCFunction)pyexpat_ParserCreate,
    1627             :      METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
    1628             :     {"ErrorString",     (PyCFunction)pyexpat_ErrorString,
    1629             :      METH_VARARGS,      pyexpat_ErrorString__doc__},
    1630             : 
    1631             :     {NULL,       (PyCFunction)NULL, 0, NULL}            /* sentinel */
    1632             : };
    1633             : 
    1634             : /* Module docstring */
    1635             : 
    1636             : PyDoc_STRVAR(pyexpat_module_documentation,
    1637             : "Python wrapper for Expat parser.");
    1638             : 
    1639             : /* Initialization function for the module */
    1640             : 
    1641             : #ifndef MODULE_NAME
    1642             : #define MODULE_NAME "pyexpat"
    1643             : #endif
    1644             : 
    1645             : #ifndef MODULE_INITFUNC
    1646             : #define MODULE_INITFUNC PyInit_pyexpat
    1647             : #endif
    1648             : 
    1649             : #ifndef PyMODINIT_FUNC
    1650             : #   ifdef MS_WINDOWS
    1651             : #       define PyMODINIT_FUNC __declspec(dllexport) void
    1652             : #   else
    1653             : #       define PyMODINIT_FUNC void
    1654             : #   endif
    1655             : #endif
    1656             : 
    1657             : PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
    1658             : 
    1659             : static struct PyModuleDef pyexpatmodule = {
    1660             :         PyModuleDef_HEAD_INIT,
    1661             :         MODULE_NAME,
    1662             :         pyexpat_module_documentation,
    1663             :         -1,
    1664             :         pyexpat_methods,
    1665             :         NULL,
    1666             :         NULL,
    1667             :         NULL,
    1668             :         NULL
    1669             : };
    1670             : 
    1671             : PyMODINIT_FUNC
    1672           0 : MODULE_INITFUNC(void)
    1673             : {
    1674             :     PyObject *m, *d;
    1675           0 :     PyObject *errmod_name = PyUnicode_FromString(MODULE_NAME ".errors");
    1676             :     PyObject *errors_module;
    1677             :     PyObject *modelmod_name;
    1678             :     PyObject *model_module;
    1679             :     PyObject *sys_modules;
    1680             :     PyObject *tmpnum, *tmpstr;
    1681             :     PyObject *codes_dict;
    1682             :     PyObject *rev_codes_dict;
    1683             :     int res;
    1684             :     static struct PyExpat_CAPI capi;
    1685             :     PyObject *capi_object;
    1686             : 
    1687           0 :     if (errmod_name == NULL)
    1688           0 :         return NULL;
    1689           0 :     modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
    1690           0 :     if (modelmod_name == NULL)
    1691           0 :         return NULL;
    1692             : 
    1693           0 :     if (PyType_Ready(&Xmlparsetype) < 0)
    1694           0 :         return NULL;
    1695             : 
    1696             :     /* Create the module and add the functions */
    1697           0 :     m = PyModule_Create(&pyexpatmodule);
    1698           0 :     if (m == NULL)
    1699           0 :         return NULL;
    1700             : 
    1701             :     /* Add some symbolic constants to the module */
    1702           0 :     if (ErrorObject == NULL) {
    1703           0 :         ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
    1704             :                                          NULL, NULL);
    1705           0 :         if (ErrorObject == NULL)
    1706           0 :             return NULL;
    1707             :     }
    1708           0 :     Py_INCREF(ErrorObject);
    1709           0 :     PyModule_AddObject(m, "error", ErrorObject);
    1710           0 :     Py_INCREF(ErrorObject);
    1711           0 :     PyModule_AddObject(m, "ExpatError", ErrorObject);
    1712           0 :     Py_INCREF(&Xmlparsetype);
    1713           0 :     PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
    1714             : 
    1715           0 :     PyModule_AddStringConstant(m, "EXPAT_VERSION",
    1716           0 :                                (char *) XML_ExpatVersion());
    1717             :     {
    1718           0 :         XML_Expat_Version info = XML_ExpatVersionInfo();
    1719           0 :         PyModule_AddObject(m, "version_info",
    1720             :                            Py_BuildValue("(iii)", info.major,
    1721             :                                          info.minor, info.micro));
    1722             :     }
    1723           0 :     init_template_buffer();
    1724             :     /* XXX When Expat supports some way of figuring out how it was
    1725             :        compiled, this should check and set native_encoding
    1726             :        appropriately.
    1727             :     */
    1728           0 :     PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
    1729             : 
    1730           0 :     sys_modules = PySys_GetObject("modules");
    1731           0 :     d = PyModule_GetDict(m);
    1732           0 :     errors_module = PyDict_GetItem(d, errmod_name);
    1733           0 :     if (errors_module == NULL) {
    1734           0 :         errors_module = PyModule_New(MODULE_NAME ".errors");
    1735           0 :         if (errors_module != NULL) {
    1736           0 :             PyDict_SetItem(sys_modules, errmod_name, errors_module);
    1737             :             /* gives away the reference to errors_module */
    1738           0 :             PyModule_AddObject(m, "errors", errors_module);
    1739             :         }
    1740             :     }
    1741           0 :     Py_DECREF(errmod_name);
    1742           0 :     model_module = PyDict_GetItem(d, modelmod_name);
    1743           0 :     if (model_module == NULL) {
    1744           0 :         model_module = PyModule_New(MODULE_NAME ".model");
    1745           0 :         if (model_module != NULL) {
    1746           0 :             PyDict_SetItem(sys_modules, modelmod_name, model_module);
    1747             :             /* gives away the reference to model_module */
    1748           0 :             PyModule_AddObject(m, "model", model_module);
    1749             :         }
    1750             :     }
    1751           0 :     Py_DECREF(modelmod_name);
    1752           0 :     if (errors_module == NULL || model_module == NULL)
    1753             :         /* Don't core dump later! */
    1754           0 :         return NULL;
    1755             : 
    1756             : #if XML_COMBINED_VERSION > 19505
    1757             :     {
    1758           0 :         const XML_Feature *features = XML_GetFeatureList();
    1759           0 :         PyObject *list = PyList_New(0);
    1760           0 :         if (list == NULL)
    1761             :             /* just ignore it */
    1762           0 :             PyErr_Clear();
    1763             :         else {
    1764           0 :             int i = 0;
    1765           0 :             for (; features[i].feature != XML_FEATURE_END; ++i) {
    1766             :                 int ok;
    1767           0 :                 PyObject *item = Py_BuildValue("si", features[i].name,
    1768           0 :                                                features[i].value);
    1769           0 :                 if (item == NULL) {
    1770           0 :                     Py_DECREF(list);
    1771           0 :                     list = NULL;
    1772           0 :                     break;
    1773             :                 }
    1774           0 :                 ok = PyList_Append(list, item);
    1775           0 :                 Py_DECREF(item);
    1776           0 :                 if (ok < 0) {
    1777           0 :                     PyErr_Clear();
    1778           0 :                     break;
    1779             :                 }
    1780             :             }
    1781           0 :             if (list != NULL)
    1782           0 :                 PyModule_AddObject(m, "features", list);
    1783             :         }
    1784             :     }
    1785             : #endif
    1786             : 
    1787           0 :     codes_dict = PyDict_New();
    1788           0 :     rev_codes_dict = PyDict_New();
    1789           0 :     if (codes_dict == NULL || rev_codes_dict == NULL) {
    1790           0 :         Py_XDECREF(codes_dict);
    1791           0 :         Py_XDECREF(rev_codes_dict);
    1792           0 :         return NULL;
    1793             :     }
    1794             : 
    1795             : #define MYCONST(name) \
    1796             :     if (PyModule_AddStringConstant(errors_module, #name,               \
    1797             :                                    (char *)XML_ErrorString(name)) < 0) \
    1798             :         return NULL;                                                   \
    1799             :     tmpnum = PyLong_FromLong(name);                                    \
    1800             :     if (tmpnum == NULL) return NULL;                                   \
    1801             :     res = PyDict_SetItemString(codes_dict,                             \
    1802             :                                XML_ErrorString(name), tmpnum);         \
    1803             :     if (res < 0) return NULL;                                          \
    1804             :     tmpstr = PyUnicode_FromString(XML_ErrorString(name));              \
    1805             :     if (tmpstr == NULL) return NULL;                                   \
    1806             :     res = PyDict_SetItem(rev_codes_dict, tmpnum, tmpstr);              \
    1807             :     Py_DECREF(tmpstr);                                                 \
    1808             :     Py_DECREF(tmpnum);                                                 \
    1809             :     if (res < 0) return NULL;                                          \
    1810             : 
    1811           0 :     MYCONST(XML_ERROR_NO_MEMORY);
    1812           0 :     MYCONST(XML_ERROR_SYNTAX);
    1813           0 :     MYCONST(XML_ERROR_NO_ELEMENTS);
    1814           0 :     MYCONST(XML_ERROR_INVALID_TOKEN);
    1815           0 :     MYCONST(XML_ERROR_UNCLOSED_TOKEN);
    1816           0 :     MYCONST(XML_ERROR_PARTIAL_CHAR);
    1817           0 :     MYCONST(XML_ERROR_TAG_MISMATCH);
    1818           0 :     MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
    1819           0 :     MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
    1820           0 :     MYCONST(XML_ERROR_PARAM_ENTITY_REF);
    1821           0 :     MYCONST(XML_ERROR_UNDEFINED_ENTITY);
    1822           0 :     MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
    1823           0 :     MYCONST(XML_ERROR_ASYNC_ENTITY);
    1824           0 :     MYCONST(XML_ERROR_BAD_CHAR_REF);
    1825           0 :     MYCONST(XML_ERROR_BINARY_ENTITY_REF);
    1826           0 :     MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
    1827           0 :     MYCONST(XML_ERROR_MISPLACED_XML_PI);
    1828           0 :     MYCONST(XML_ERROR_UNKNOWN_ENCODING);
    1829           0 :     MYCONST(XML_ERROR_INCORRECT_ENCODING);
    1830           0 :     MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
    1831           0 :     MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
    1832           0 :     MYCONST(XML_ERROR_NOT_STANDALONE);
    1833           0 :     MYCONST(XML_ERROR_UNEXPECTED_STATE);
    1834           0 :     MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
    1835           0 :     MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
    1836           0 :     MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
    1837             :     /* Added in Expat 1.95.7. */
    1838           0 :     MYCONST(XML_ERROR_UNBOUND_PREFIX);
    1839             :     /* Added in Expat 1.95.8. */
    1840           0 :     MYCONST(XML_ERROR_UNDECLARING_PREFIX);
    1841           0 :     MYCONST(XML_ERROR_INCOMPLETE_PE);
    1842           0 :     MYCONST(XML_ERROR_XML_DECL);
    1843           0 :     MYCONST(XML_ERROR_TEXT_DECL);
    1844           0 :     MYCONST(XML_ERROR_PUBLICID);
    1845           0 :     MYCONST(XML_ERROR_SUSPENDED);
    1846           0 :     MYCONST(XML_ERROR_NOT_SUSPENDED);
    1847           0 :     MYCONST(XML_ERROR_ABORTED);
    1848           0 :     MYCONST(XML_ERROR_FINISHED);
    1849           0 :     MYCONST(XML_ERROR_SUSPEND_PE);
    1850             : 
    1851           0 :     if (PyModule_AddStringConstant(errors_module, "__doc__",
    1852             :                                    "Constants used to describe "
    1853             :                                    "error conditions.") < 0)
    1854           0 :         return NULL;
    1855             : 
    1856           0 :     if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0)
    1857           0 :         return NULL;
    1858           0 :     if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0)
    1859           0 :         return NULL;
    1860             : 
    1861             : #undef MYCONST
    1862             : 
    1863             : #define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
    1864           0 :     MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
    1865           0 :     MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
    1866           0 :     MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
    1867             : #undef MYCONST
    1868             : 
    1869             : #define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
    1870           0 :     PyModule_AddStringConstant(model_module, "__doc__",
    1871             :                      "Constants used to interpret content model information.");
    1872             : 
    1873           0 :     MYCONST(XML_CTYPE_EMPTY);
    1874           0 :     MYCONST(XML_CTYPE_ANY);
    1875           0 :     MYCONST(XML_CTYPE_MIXED);
    1876           0 :     MYCONST(XML_CTYPE_NAME);
    1877           0 :     MYCONST(XML_CTYPE_CHOICE);
    1878           0 :     MYCONST(XML_CTYPE_SEQ);
    1879             : 
    1880           0 :     MYCONST(XML_CQUANT_NONE);
    1881           0 :     MYCONST(XML_CQUANT_OPT);
    1882           0 :     MYCONST(XML_CQUANT_REP);
    1883           0 :     MYCONST(XML_CQUANT_PLUS);
    1884             : #undef MYCONST
    1885             : 
    1886             :     /* initialize pyexpat dispatch table */
    1887           0 :     capi.size = sizeof(capi);
    1888           0 :     capi.magic = PyExpat_CAPI_MAGIC;
    1889           0 :     capi.MAJOR_VERSION = XML_MAJOR_VERSION;
    1890           0 :     capi.MINOR_VERSION = XML_MINOR_VERSION;
    1891           0 :     capi.MICRO_VERSION = XML_MICRO_VERSION;
    1892           0 :     capi.ErrorString = XML_ErrorString;
    1893           0 :     capi.GetErrorCode = XML_GetErrorCode;
    1894           0 :     capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
    1895           0 :     capi.GetErrorLineNumber = XML_GetErrorLineNumber;
    1896           0 :     capi.Parse = XML_Parse;
    1897           0 :     capi.ParserCreate_MM = XML_ParserCreate_MM;
    1898           0 :     capi.ParserFree = XML_ParserFree;
    1899           0 :     capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
    1900           0 :     capi.SetCommentHandler = XML_SetCommentHandler;
    1901           0 :     capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
    1902           0 :     capi.SetElementHandler = XML_SetElementHandler;
    1903           0 :     capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
    1904           0 :     capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
    1905           0 :     capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
    1906           0 :     capi.SetUserData = XML_SetUserData;
    1907           0 :     capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
    1908             : 
    1909             :     /* export using capsule */
    1910           0 :     capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
    1911           0 :     if (capi_object)
    1912           0 :         PyModule_AddObject(m, "expat_CAPI", capi_object);
    1913           0 :     return m;
    1914             : }
    1915             : 
    1916             : static void
    1917           0 : clear_handlers(xmlparseobject *self, int initial)
    1918             : {
    1919           0 :     int i = 0;
    1920             :     PyObject *temp;
    1921             : 
    1922           0 :     for (; handler_info[i].name != NULL; i++) {
    1923           0 :         if (initial)
    1924           0 :             self->handlers[i] = NULL;
    1925             :         else {
    1926           0 :             temp = self->handlers[i];
    1927           0 :             self->handlers[i] = NULL;
    1928           0 :             Py_XDECREF(temp);
    1929           0 :             handler_info[i].setter(self->itself, NULL);
    1930             :         }
    1931             :     }
    1932           0 : }
    1933             : 
    1934             : static struct HandlerInfo handler_info[] = {
    1935             :     {"StartElementHandler",
    1936             :      (xmlhandlersetter)XML_SetStartElementHandler,
    1937             :      (xmlhandler)my_StartElementHandler},
    1938             :     {"EndElementHandler",
    1939             :      (xmlhandlersetter)XML_SetEndElementHandler,
    1940             :      (xmlhandler)my_EndElementHandler},
    1941             :     {"ProcessingInstructionHandler",
    1942             :      (xmlhandlersetter)XML_SetProcessingInstructionHandler,
    1943             :      (xmlhandler)my_ProcessingInstructionHandler},
    1944             :     {"CharacterDataHandler",
    1945             :      (xmlhandlersetter)XML_SetCharacterDataHandler,
    1946             :      (xmlhandler)my_CharacterDataHandler},
    1947             :     {"UnparsedEntityDeclHandler",
    1948             :      (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
    1949             :      (xmlhandler)my_UnparsedEntityDeclHandler},
    1950             :     {"NotationDeclHandler",
    1951             :      (xmlhandlersetter)XML_SetNotationDeclHandler,
    1952             :      (xmlhandler)my_NotationDeclHandler},
    1953             :     {"StartNamespaceDeclHandler",
    1954             :      (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
    1955             :      (xmlhandler)my_StartNamespaceDeclHandler},
    1956             :     {"EndNamespaceDeclHandler",
    1957             :      (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
    1958             :      (xmlhandler)my_EndNamespaceDeclHandler},
    1959             :     {"CommentHandler",
    1960             :      (xmlhandlersetter)XML_SetCommentHandler,
    1961             :      (xmlhandler)my_CommentHandler},
    1962             :     {"StartCdataSectionHandler",
    1963             :      (xmlhandlersetter)XML_SetStartCdataSectionHandler,
    1964             :      (xmlhandler)my_StartCdataSectionHandler},
    1965             :     {"EndCdataSectionHandler",
    1966             :      (xmlhandlersetter)XML_SetEndCdataSectionHandler,
    1967             :      (xmlhandler)my_EndCdataSectionHandler},
    1968             :     {"DefaultHandler",
    1969             :      (xmlhandlersetter)XML_SetDefaultHandler,
    1970             :      (xmlhandler)my_DefaultHandler},
    1971             :     {"DefaultHandlerExpand",
    1972             :      (xmlhandlersetter)XML_SetDefaultHandlerExpand,
    1973             :      (xmlhandler)my_DefaultHandlerExpandHandler},
    1974             :     {"NotStandaloneHandler",
    1975             :      (xmlhandlersetter)XML_SetNotStandaloneHandler,
    1976             :      (xmlhandler)my_NotStandaloneHandler},
    1977             :     {"ExternalEntityRefHandler",
    1978             :      (xmlhandlersetter)XML_SetExternalEntityRefHandler,
    1979             :      (xmlhandler)my_ExternalEntityRefHandler},
    1980             :     {"StartDoctypeDeclHandler",
    1981             :      (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
    1982             :      (xmlhandler)my_StartDoctypeDeclHandler},
    1983             :     {"EndDoctypeDeclHandler",
    1984             :      (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
    1985             :      (xmlhandler)my_EndDoctypeDeclHandler},
    1986             :     {"EntityDeclHandler",
    1987             :      (xmlhandlersetter)XML_SetEntityDeclHandler,
    1988             :      (xmlhandler)my_EntityDeclHandler},
    1989             :     {"XmlDeclHandler",
    1990             :      (xmlhandlersetter)XML_SetXmlDeclHandler,
    1991             :      (xmlhandler)my_XmlDeclHandler},
    1992             :     {"ElementDeclHandler",
    1993             :      (xmlhandlersetter)XML_SetElementDeclHandler,
    1994             :      (xmlhandler)my_ElementDeclHandler},
    1995             :     {"AttlistDeclHandler",
    1996             :      (xmlhandlersetter)XML_SetAttlistDeclHandler,
    1997             :      (xmlhandler)my_AttlistDeclHandler},
    1998             : #if XML_COMBINED_VERSION >= 19504
    1999             :     {"SkippedEntityHandler",
    2000             :      (xmlhandlersetter)XML_SetSkippedEntityHandler,
    2001             :      (xmlhandler)my_SkippedEntityHandler},
    2002             : #endif
    2003             : 
    2004             :     {NULL, NULL, NULL} /* sentinel */
    2005             : };

Generated by: LCOV version 1.10