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