LCOV - code coverage report
Current view: | top level - Modules - pyexpat.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 162 | 826 | 19.6 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 13 | 86 | 15.1 %
|  |  | Branches: | 77 | 626 | 12.3 %

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

Generated by: LCOV version 1.14