[3.5] bpo-30070: Fixed leaks and crashes in errors handling in the pa… · python/cpython@952a05e
@@ -763,6 +763,9 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
763763Py_ssize_t i;
764764int err;
765765766+if (len < 0) {
767+return NULL;
768+ }
766769for (i = 1; i < len; ++i) {
767770/* elem must always be a sequence, however simple */
768771PyObject* elem = PySequence_GetItem(tuple, i);
@@ -783,7 +786,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
783786if (type == -1 && PyErr_Occurred()) {
784787Py_DECREF(temp);
785788Py_DECREF(elem);
786-return 0;
789+return NULL;
787790 }
788791 }
789792Py_DECREF(temp);
@@ -795,7 +798,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
795798PyErr_SetObject(parser_error, err);
796799Py_XDECREF(err);
797800Py_XDECREF(elem);
798-return (0);
801+return NULL;
799802 }
800803if (ISTERMINAL(type)) {
801804Py_ssize_t len = PyObject_Size(elem);
@@ -804,58 +807,64 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
804807805808if ((len != 2) && (len != 3)) {
806809err_string("terminal nodes must have 2 or 3 entries");
807-return 0;
810+Py_DECREF(elem);
811+return NULL;
808812 }
809813temp = PySequence_GetItem(elem, 1);
810-if (temp == NULL)
811-return 0;
814+if (temp == NULL) {
815+Py_DECREF(elem);
816+return NULL;
817+ }
812818if (!PyUnicode_Check(temp)) {
813819PyErr_Format(parser_error,
814820"second item in terminal node must be a string,"
815821" found %s",
816822Py_TYPE(temp)->tp_name);
817823Py_DECREF(temp);
818824Py_DECREF(elem);
819-return 0;
825+return NULL;
820826 }
821827if (len == 3) {
822828PyObject *o = PySequence_GetItem(elem, 2);
823-if (o != NULL) {
824-if (PyLong_Check(o)) {
825-int num = _PyLong_AsInt(o);
826-if (num == -1 && PyErr_Occurred()) {
827-Py_DECREF(o);
828-Py_DECREF(temp);
829-Py_DECREF(elem);
830-return 0;
831- }
832-*line_num = num;
833- }
834-else {
835-PyErr_Format(parser_error,
836-"third item in terminal node must be an"
837-" integer, found %s",
838-Py_TYPE(temp)->tp_name);
829+if (o == NULL) {
830+Py_DECREF(temp);
831+Py_DECREF(elem);
832+return NULL;
833+ }
834+if (PyLong_Check(o)) {
835+int num = _PyLong_AsInt(o);
836+if (num == -1 && PyErr_Occurred()) {
839837Py_DECREF(o);
840838Py_DECREF(temp);
841839Py_DECREF(elem);
842-return 0;
840+return NULL;
843841 }
842+*line_num = num;
843+ }
844+else {
845+PyErr_Format(parser_error,
846+"third item in terminal node must be an"
847+" integer, found %s",
848+Py_TYPE(temp)->tp_name);
844849Py_DECREF(o);
850+Py_DECREF(temp);
851+Py_DECREF(elem);
852+return NULL;
845853 }
854+Py_DECREF(o);
846855 }
847856temp_str = _PyUnicode_AsStringAndSize(temp, &len);
848857if (temp_str == NULL) {
849858Py_DECREF(temp);
850-Py_XDECREF(elem);
851-return 0;
859+Py_DECREF(elem);
860+return NULL;
852861 }
853862strn = (char *)PyObject_MALLOC(len + 1);
854863if (strn == NULL) {
855864Py_DECREF(temp);
856-Py_XDECREF(elem);
865+Py_DECREF(elem);
857866PyErr_NoMemory();
858-return 0;
867+return NULL;
859868 }
860869 (void) memcpy(strn, temp_str, len + 1);
861870Py_DECREF(temp);
@@ -865,20 +874,21 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
865874 * It has to be one or the other; this is an error.
866875 * Raise an exception.
867876 */
868-PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
877+PyObject *err = Py_BuildValue("Os", elem, "unknown node type.");
869878PyErr_SetObject(parser_error, err);
870879Py_XDECREF(err);
871-Py_XDECREF(elem);
872-return (0);
880+Py_DECREF(elem);
881+return NULL;
873882 }
874883err = PyNode_AddChild(root, type, strn, *line_num, 0);
875884if (err == E_NOMEM) {
876-Py_XDECREF(elem);
885+Py_DECREF(elem);
877886PyObject_FREE(strn);
878-return (node *) PyErr_NoMemory();
887+PyErr_NoMemory();
888+return NULL;
879889 }
880890if (err == E_OVERFLOW) {
881-Py_XDECREF(elem);
891+Py_DECREF(elem);
882892PyObject_FREE(strn);
883893PyErr_SetString(PyExc_ValueError,
884894"unsupported number of child nodes");
@@ -889,14 +899,14 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
889899node* new_child = CHILD(root, i - 1);
890900891901if (new_child != build_node_children(elem, new_child, line_num)) {
892-Py_XDECREF(elem);
893-return (0);
902+Py_DECREF(elem);
903+return NULL;
894904 }
895905 }
896906else if (type == NEWLINE) { /* It's true: we increment the */
897907++(*line_num); /* line number *after* the newline! */
898908 }
899-Py_XDECREF(elem);
909+Py_DECREF(elem);
900910 }
901911return root;
902912}
@@ -931,10 +941,23 @@ build_node_tree(PyObject *tuple)
931941932942if (num == encoding_decl) {
933943encoding = PySequence_GetItem(tuple, 2);
944+if (encoding == NULL) {
945+PyErr_SetString(parser_error, "missed encoding");
946+return NULL;
947+ }
948+if (!PyUnicode_Check(encoding)) {
949+PyErr_Format(parser_error,
950+"encoding must be a string, found %.200s",
951+Py_TYPE(encoding)->tp_name);
952+Py_DECREF(encoding);
953+return NULL;
954+ }
934955/* tuple isn't borrowed anymore here, need to DECREF */
935956tuple = PySequence_GetSlice(tuple, 0, 2);
936-if (tuple == NULL)
957+if (tuple == NULL) {
958+Py_DECREF(encoding);
937959return NULL;
960+ }
938961 }
939962res = PyNode_New(num);
940963if (res != NULL) {
@@ -947,31 +970,33 @@ build_node_tree(PyObject *tuple)
947970const char *temp;
948971temp = _PyUnicode_AsStringAndSize(encoding, &len);
949972if (temp == NULL) {
950-Py_DECREF(res);
973+PyNode_Free(res);
951974Py_DECREF(encoding);
952975Py_DECREF(tuple);
953976return NULL;
954977 }
955978res->n_str = (char *)PyObject_MALLOC(len + 1);
956979if (res->n_str == NULL) {
957-Py_DECREF(res);
980+PyNode_Free(res);
958981Py_DECREF(encoding);
959982Py_DECREF(tuple);
960983PyErr_NoMemory();
961984return NULL;
962985 }
963986 (void) memcpy(res->n_str, temp, len + 1);
964-Py_DECREF(encoding);
965-Py_DECREF(tuple);
966987 }
967988 }
989+if (encoding != NULL) {
990+Py_DECREF(encoding);
991+Py_DECREF(tuple);
992+ }
968993 }
969994else {
970995/* The tuple is illegal -- if the number is neither TERMINAL nor
971996 * NONTERMINAL, we can't use it. Not sure the implementation
972997 * allows this condition, but the API doesn't preclude it.
973998 */
974-PyObject *err = Py_BuildValue("os", tuple,
999+PyObject *err = Py_BuildValue("Os", tuple,
9751000"Illegal component tuple.");
9761001PyErr_SetObject(parser_error, err);
9771002Py_XDECREF(err);
@@ -3433,7 +3458,6 @@ parser__pickler(PyObject *self, PyObject *args)
34333458result = Py_BuildValue("O(O)", pickle_constructor, tuple);
34343459Py_DECREF(tuple);
34353460 }
3436-Py_DECREF(empty_dict);
34373461Py_DECREF(newargs);
34383462 }
34393463finally: