@@ -740,6 +740,9 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
740740 Py_ssize_t i ;
741741 int err ;
742742
743+ if (len < 0 ) {
744+ return NULL ;
745+ }
743746 for (i = 1 ; i < len ; ++ i ) {
744747 /* elem must always be a sequence, however simple */
745748 PyObject * elem = PySequence_GetItem (tuple , i );
@@ -766,67 +769,83 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
766769 PyErr_SetObject (parser_error , err );
767770 Py_XDECREF (err );
768771 Py_XDECREF (elem );
769- return ( 0 ) ;
772+ return NULL ;
770773 }
771774 if (ISTERMINAL (type )) {
772775 Py_ssize_t len = PyObject_Size (elem );
773776 PyObject * temp ;
774777
775778 if ((len != 2 ) && (len != 3 )) {
776779 err_string ("terminal nodes must have 2 or 3 entries" );
777- return 0 ;
780+ Py_DECREF (elem );
781+ return NULL ;
778782 }
779783 temp = PySequence_GetItem (elem , 1 );
780- if (temp == NULL )
781- return 0 ;
784+ if (temp == NULL ) {
785+ Py_DECREF (elem );
786+ return NULL ;
787+ }
782788 if (!PyString_Check (temp )) {
783789 PyErr_Format (parser_error ,
784790 "second item in terminal node must be a string,"
785791 " found %s" ,
786792 Py_TYPE (temp )-> tp_name );
787793 Py_DECREF (temp );
788- return 0 ;
794+ Py_DECREF (elem );
795+ return NULL ;
789796 }
790797 if (len == 3 ) {
791798 PyObject * o = PySequence_GetItem (elem , 2 );
792- if (o ! = NULL ) {
793- if ( PyInt_Check ( o ))
794- * line_num = PyInt_AS_LONG ( o );
795- else {
796- PyErr_Format ( parser_error ,
797- "third item in terminal node must be an"
798- " integer, found %s" ,
799- Py_TYPE ( temp ) -> tp_name );
800- Py_DECREF ( o );
801- Py_DECREF ( temp );
802- return 0 ;
803- }
799+ if (o = = NULL ) {
800+ Py_DECREF ( temp );
801+ Py_DECREF ( elem );
802+ return NULL ;
803+ }
804+ if ( PyInt_Check ( o ))
805+ * line_num = PyInt_AS_LONG ( o );
806+ else {
807+ PyErr_Format ( parser_error ,
808+ "third item in terminal node must be an"
809+ " integer, found %s" ,
810+ Py_TYPE ( temp ) -> tp_name );
804811 Py_DECREF (o );
812+ Py_DECREF (temp );
813+ Py_DECREF (elem );
814+ return NULL ;
805815 }
816+ Py_DECREF (o );
806817 }
807818 len = PyString_GET_SIZE (temp ) + 1 ;
808819 strn = (char * )PyObject_MALLOC (len );
809- if (strn != NULL )
810- (void ) memcpy (strn , PyString_AS_STRING (temp ), len );
820+ if (strn == NULL ) {
821+ Py_DECREF (temp );
822+ Py_DECREF (elem );
823+ PyErr_NoMemory ();
824+ return NULL ;
825+ }
826+ (void ) memcpy (strn , PyString_AS_STRING (temp ), len );
811827 Py_DECREF (temp );
812828 }
813829 else if (!ISNONTERMINAL (type )) {
814830 /*
815831 * It has to be one or the other; this is an error.
816832 * Raise an exception.
817833 */
818- PyObject * err = Py_BuildValue ("os " , elem , "unknown node type." );
834+ PyObject * err = Py_BuildValue ("Os " , elem , "unknown node type." );
819835 PyErr_SetObject (parser_error , err );
820836 Py_XDECREF (err );
821- Py_XDECREF (elem );
822- return ( 0 ) ;
837+ Py_DECREF (elem );
838+ return NULL ;
823839 }
824840 err = PyNode_AddChild (root , type , strn , * line_num , 0 );
825841 if (err == E_NOMEM ) {
842+ Py_DECREF (elem );
826843 PyObject_FREE (strn );
827- return (node * ) PyErr_NoMemory ();
844+ PyErr_NoMemory ();
845+ return NULL ;
828846 }
829847 if (err == E_OVERFLOW ) {
848+ Py_DECREF (elem );
830849 PyObject_FREE (strn );
831850 PyErr_SetString (PyExc_ValueError ,
832851 "unsupported number of child nodes" );
@@ -837,14 +856,14 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
837856 node * new_child = CHILD (root , i - 1 );
838857
839858 if (new_child != build_node_children (elem , new_child , line_num )) {
840- Py_XDECREF (elem );
841- return ( 0 ) ;
859+ Py_DECREF (elem );
860+ return NULL ;
842861 }
843862 }
844863 else if (type == NEWLINE ) { /* It's true: we increment the */
845864 ++ (* line_num ); /* line number *after* the newline! */
846865 }
847- Py_XDECREF (elem );
866+ Py_DECREF (elem );
848867 }
849868 return root ;
850869}
@@ -879,8 +898,23 @@ build_node_tree(PyObject *tuple)
879898
880899 if (num == encoding_decl ) {
881900 encoding = PySequence_GetItem (tuple , 2 );
901+ if (encoding == NULL ) {
902+ PyErr_SetString (parser_error , "missed encoding" );
903+ return NULL ;
904+ }
905+ if (!PyString_Check (encoding )) {
906+ PyErr_Format (parser_error ,
907+ "encoding must be a string, found %.200s" ,
908+ Py_TYPE (encoding )-> tp_name );
909+ Py_DECREF (encoding );
910+ return NULL ;
911+ }
882912 /* tuple isn't borrowed anymore here, need to DECREF */
883913 tuple = PySequence_GetSlice (tuple , 0 , 2 );
914+ if (tuple == NULL ) {
915+ Py_DECREF (encoding );
916+ return NULL ;
917+ }
884918 }
885919 res = PyNode_New (num );
886920 if (res != NULL ) {
@@ -892,19 +926,27 @@ build_node_tree(PyObject *tuple)
892926 Py_ssize_t len ;
893927 len = PyString_GET_SIZE (encoding ) + 1 ;
894928 res -> n_str = (char * )PyObject_MALLOC (len );
895- if (res -> n_str != NULL )
896- (void ) memcpy (res -> n_str , PyString_AS_STRING (encoding ), len );
897- Py_DECREF (encoding );
898- Py_DECREF (tuple );
929+ if (res -> n_str == NULL ) {
930+ PyNode_Free (res );
931+ Py_DECREF (encoding );
932+ Py_DECREF (tuple );
933+ PyErr_NoMemory ();
934+ return NULL ;
935+ }
936+ (void ) memcpy (res -> n_str , PyString_AS_STRING (encoding ), len );
899937 }
900938 }
939+ if (encoding != NULL ) {
940+ Py_DECREF (encoding );
941+ Py_DECREF (tuple );
942+ }
901943 }
902944 else {
903945 /* The tuple is illegal -- if the number is neither TERMINAL nor
904946 * NONTERMINAL, we can't use it. Not sure the implementation
905947 * allows this condition, but the API doesn't preclude it.
906948 */
907- PyObject * err = Py_BuildValue ("os " , tuple ,
949+ PyObject * err = Py_BuildValue ("Os " , tuple ,
908950 "Illegal component tuple." );
909951 PyErr_SetObject (parser_error , err );
910952 Py_XDECREF (err );
@@ -3371,7 +3413,6 @@ parser__pickler(PyObject *self, PyObject *args)
33713413 result = Py_BuildValue ("O(O)" , pickle_constructor , tuple );
33723414 Py_DECREF (tuple );
33733415 }
3374- Py_DECREF (empty_dict );
33753416 Py_DECREF (newargs );
33763417 }
33773418 finally :
0 commit comments