5
5
#include "xmlparse.h"
6
6
#endif
7
7
8
+ #ifndef PyGC_HEAD_SIZE
9
+ #define PyGC_HEAD_SIZE 0
10
+ #define PyObject_GC_Init (x )
11
+ #define PyObject_GC_Fini (m )
12
+ #define Py_TPFLAGS_GC 0
13
+ #endif
14
+
8
15
enum HandlerTypes {
9
16
StartElement ,
10
17
EndElement ,
@@ -75,6 +82,7 @@ conv_atts_using_string(XML_Char **atts)
75
82
}
76
83
if (PyDict_SetItemString (attrs_obj ,
77
84
(char * )* attrs_k , rv ) < 0 ) {
85
+ Py_DECREF (rv );
78
86
Py_DECREF (attrs_obj );
79
87
attrs_obj = NULL ;
80
88
goto finally ;
@@ -198,12 +206,12 @@ conv_string_len_to_utf8(const XML_Char *str, int len)
198
206
199
207
/* Callback routines */
200
208
201
- static void clear_handlers (xmlparseobject * self );
209
+ static void clear_handlers (xmlparseobject * self , int decref );
202
210
203
211
static void
204
212
flag_error (xmlparseobject * self )
205
213
{
206
- clear_handlers (self );
214
+ clear_handlers (self , 1 );
207
215
}
208
216
209
217
#define RC_HANDLER (RC , NAME , PARAMS , INIT , PARAM_FORMAT , CONVERSION , \
@@ -500,6 +508,13 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
500
508
if (!rv || bytes_read == 0 )
501
509
break ;
502
510
}
511
+ if (rv == 0 ) {
512
+ PyErr_Format (ErrorObject , "%.200s: line %i, column %i" ,
513
+ XML_ErrorString (XML_GetErrorCode (self -> itself )),
514
+ XML_GetErrorLineNumber (self -> itself ),
515
+ XML_GetErrorColumnNumber (self -> itself ));
516
+ return NULL ;
517
+ }
503
518
return Py_BuildValue ("i" , rv );
504
519
}
505
520
@@ -568,10 +583,13 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
568
583
#endif
569
584
570
585
new_parser -> itself = XML_ExternalEntityParserCreate (self -> itself , context ,
571
- encoding );
572
- if (!new_parser ) {
573
- Py_DECREF (new_parser );
574
- return PyErr_NoMemory ();
586
+ encoding );
587
+ new_parser -> handlers = 0 ;
588
+ PyObject_GC_Init (new_parser );
589
+
590
+ if (!new_parser -> itself ) {
591
+ Py_DECREF (new_parser );
592
+ return PyErr_NoMemory ();
575
593
}
576
594
577
595
XML_SetUserData (new_parser -> itself , (void * )new_parser );
@@ -581,7 +599,11 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
581
599
/* do nothing */ ;
582
600
583
601
new_parser -> handlers = malloc (sizeof (PyObject * )* i );
584
- clear_handlers (new_parser );
602
+ if (!new_parser -> handlers ) {
603
+ Py_DECREF (new_parser );
604
+ return PyErr_NoMemory ();
605
+ }
606
+ clear_handlers (new_parser , 0 );
585
607
586
608
/* then copy handlers from self */
587
609
for (i = 0 ; handler_info [i ].name != NULL ; i ++ ) {
@@ -615,7 +637,7 @@ static struct PyMethodDef xmlparse_methods[] = {
615
637
/* ---------- */
616
638
617
639
618
- static xmlparseobject *
640
+ static PyObject *
619
641
newxmlparseobject (char * encoding , char * namespace_separator )
620
642
{
621
643
int i ;
@@ -635,12 +657,14 @@ newxmlparseobject(char *encoding, char *namespace_separator)
635
657
636
658
self -> returns_unicode = 1 ;
637
659
#endif
660
+ self -> handlers = NULL ;
638
661
if (namespace_separator ) {
639
662
self -> itself = XML_ParserCreateNS (encoding , * namespace_separator );
640
663
}
641
664
else {
642
665
self -> itself = XML_ParserCreate (encoding );
643
666
}
667
+ PyObject_GC_Init (self );
644
668
if (self -> itself == NULL ) {
645
669
PyErr_SetString (PyExc_RuntimeError ,
646
670
"XML_ParserCreate failed" );
@@ -653,22 +677,30 @@ newxmlparseobject(char *encoding, char *namespace_separator)
653
677
/* do nothing */ ;
654
678
655
679
self -> handlers = malloc (sizeof (PyObject * )* i );
656
- clear_handlers (self );
680
+ if (!self -> handlers ){
681
+ Py_DECREF (self );
682
+ return PyErr_NoMemory ();
683
+ }
684
+ clear_handlers (self , 0 );
657
685
658
- return self ;
686
+ return ( PyObject * ) self ;
659
687
}
660
688
661
689
662
690
static void
663
691
xmlparse_dealloc (xmlparseobject * self )
664
692
{
665
693
int i ;
694
+ PyObject_GC_Fini (self );
666
695
if (self -> itself )
667
696
XML_ParserFree (self -> itself );
668
697
self -> itself = NULL ;
669
698
670
- for (i = 0 ; handler_info [i ].name != NULL ; i ++ ) {
671
- Py_XDECREF (self -> handlers [i ]);
699
+ if (self -> handlers ){
700
+ for (i = 0 ; handler_info [i ].name != NULL ; i ++ ) {
701
+ Py_XDECREF (self -> handlers [i ]);
702
+ }
703
+ free (self -> handlers );
672
704
}
673
705
#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
674
706
/* Code for versions before 1.6 */
@@ -780,14 +812,37 @@ xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
780
812
return -1 ;
781
813
}
782
814
815
+ #ifdef WITH_CYCLE_GC
816
+ static int
817
+ xmlparse_traverse (xmlparseobject * op , visitproc visit , void * arg )
818
+ {
819
+ int i , err ;
820
+ for (i = 0 ; handler_info [i ].name != NULL ; i ++ ) {
821
+ if (!op -> handlers [i ])
822
+ continue ;
823
+ err = visit (op -> handlers [i ], arg );
824
+ if (err )
825
+ return err ;
826
+ }
827
+ return 0 ;
828
+ }
829
+
830
+ static int
831
+ xmlparse_clear (xmlparseobject * op )
832
+ {
833
+ clear_handlers (op , 1 );
834
+ return 0 ;
835
+ }
836
+ #endif
837
+
783
838
static char Xmlparsetype__doc__ [] =
784
839
"XML parser" ;
785
840
786
841
static PyTypeObject Xmlparsetype = {
787
842
PyObject_HEAD_INIT (NULL )
788
843
0 , /*ob_size*/
789
844
"xmlparser" , /*tp_name*/
790
- sizeof (xmlparseobject ), /*tp_basicsize*/
845
+ sizeof (xmlparseobject ) + PyGC_HEAD_SIZE , /*tp_basicsize*/
791
846
0 , /*tp_itemsize*/
792
847
/* methods */
793
848
(destructor )xmlparse_dealloc , /*tp_dealloc*/
@@ -802,10 +857,17 @@ static PyTypeObject Xmlparsetype = {
802
857
(hashfunc )0 , /*tp_hash*/
803
858
(ternaryfunc )0 , /*tp_call*/
804
859
(reprfunc )0 , /*tp_str*/
805
-
806
- /* Space for future expansion */
807
- 0L ,0L ,0L ,0L ,
808
- Xmlparsetype__doc__ /* Documentation string */
860
+ 0 , /* tp_getattro */
861
+ 0 , /* tp_setattro */
862
+ 0 , /* tp_as_buffer */
863
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC , /*tp_flags*/
864
+ Xmlparsetype__doc__ , /* Documentation string */
865
+ #ifdef WITH_CYCLE_GC
866
+ (traverseproc )xmlparse_traverse , /* tp_traverse */
867
+ (inquiry )xmlparse_clear /* tp_clear */
868
+ #else
869
+ 0 , 0
870
+ #endif
809
871
};
810
872
811
873
/* End of code for xmlparser objects */
@@ -968,14 +1030,17 @@ initpyexpat(void)
968
1030
}
969
1031
970
1032
static void
971
- clear_handlers (xmlparseobject * self )
1033
+ clear_handlers (xmlparseobject * self , int decref )
972
1034
{
973
- int i = 0 ;
974
-
975
- for (; handler_info [i ].name != NULL ; i ++ ) {
976
- self -> handlers [i ]= NULL ;
977
- handler_info [i ].setter (self -> itself , NULL );
978
- }
1035
+ int i = 0 ;
1036
+
1037
+ for (; handler_info [i ].name != NULL ; i ++ ) {
1038
+ if (decref ){
1039
+ Py_XDECREF (self -> handlers [i ]);
1040
+ }
1041
+ self -> handlers [i ]= NULL ;
1042
+ handler_info [i ].setter (self -> itself , NULL );
1043
+ }
979
1044
}
980
1045
981
1046
typedef void (* pairsetter )(XML_Parser , void * handler1 , void * handler2 );
0 commit comments