[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)

763763

Py_ssize_t i;

764764

int err;

765765766+

if (len < 0) {

767+

return NULL;

768+

}

766769

for (i = 1; i < len; ++i) {

767770

/* elem must always be a sequence, however simple */

768771

PyObject* elem = PySequence_GetItem(tuple, i);

@@ -783,7 +786,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)

783786

if (type == -1 && PyErr_Occurred()) {

784787

Py_DECREF(temp);

785788

Py_DECREF(elem);

786-

return 0;

789+

return NULL;

787790

}

788791

}

789792

Py_DECREF(temp);

@@ -795,7 +798,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)

795798

PyErr_SetObject(parser_error, err);

796799

Py_XDECREF(err);

797800

Py_XDECREF(elem);

798-

return (0);

801+

return NULL;

799802

}

800803

if (ISTERMINAL(type)) {

801804

Py_ssize_t len = PyObject_Size(elem);

@@ -804,58 +807,64 @@ build_node_children(PyObject *tuple, node *root, int *line_num)

804807805808

if ((len != 2) && (len != 3)) {

806809

err_string("terminal nodes must have 2 or 3 entries");

807-

return 0;

810+

Py_DECREF(elem);

811+

return NULL;

808812

}

809813

temp = PySequence_GetItem(elem, 1);

810-

if (temp == NULL)

811-

return 0;

814+

if (temp == NULL) {

815+

Py_DECREF(elem);

816+

return NULL;

817+

}

812818

if (!PyUnicode_Check(temp)) {

813819

PyErr_Format(parser_error,

814820

"second item in terminal node must be a string,"

815821

" found %s",

816822

Py_TYPE(temp)->tp_name);

817823

Py_DECREF(temp);

818824

Py_DECREF(elem);

819-

return 0;

825+

return NULL;

820826

}

821827

if (len == 3) {

822828

PyObject *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()) {

839837

Py_DECREF(o);

840838

Py_DECREF(temp);

841839

Py_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);

844849

Py_DECREF(o);

850+

Py_DECREF(temp);

851+

Py_DECREF(elem);

852+

return NULL;

845853

}

854+

Py_DECREF(o);

846855

}

847856

temp_str = _PyUnicode_AsStringAndSize(temp, &len);

848857

if (temp_str == NULL) {

849858

Py_DECREF(temp);

850-

Py_XDECREF(elem);

851-

return 0;

859+

Py_DECREF(elem);

860+

return NULL;

852861

}

853862

strn = (char *)PyObject_MALLOC(len + 1);

854863

if (strn == NULL) {

855864

Py_DECREF(temp);

856-

Py_XDECREF(elem);

865+

Py_DECREF(elem);

857866

PyErr_NoMemory();

858-

return 0;

867+

return NULL;

859868

}

860869

(void) memcpy(strn, temp_str, len + 1);

861870

Py_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.");

869878

PyErr_SetObject(parser_error, err);

870879

Py_XDECREF(err);

871-

Py_XDECREF(elem);

872-

return (0);

880+

Py_DECREF(elem);

881+

return NULL;

873882

}

874883

err = PyNode_AddChild(root, type, strn, *line_num, 0);

875884

if (err == E_NOMEM) {

876-

Py_XDECREF(elem);

885+

Py_DECREF(elem);

877886

PyObject_FREE(strn);

878-

return (node *) PyErr_NoMemory();

887+

PyErr_NoMemory();

888+

return NULL;

879889

}

880890

if (err == E_OVERFLOW) {

881-

Py_XDECREF(elem);

891+

Py_DECREF(elem);

882892

PyObject_FREE(strn);

883893

PyErr_SetString(PyExc_ValueError,

884894

"unsupported number of child nodes");

@@ -889,14 +899,14 @@ build_node_children(PyObject *tuple, node *root, int *line_num)

889899

node* new_child = CHILD(root, i - 1);

890900891901

if (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

}

896906

else 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

}

901911

return root;

902912

}

@@ -931,10 +941,23 @@ build_node_tree(PyObject *tuple)

931941932942

if (num == encoding_decl) {

933943

encoding = 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 */

935956

tuple = PySequence_GetSlice(tuple, 0, 2);

936-

if (tuple == NULL)

957+

if (tuple == NULL) {

958+

Py_DECREF(encoding);

937959

return NULL;

960+

}

938961

}

939962

res = PyNode_New(num);

940963

if (res != NULL) {

@@ -947,31 +970,33 @@ build_node_tree(PyObject *tuple)

947970

const char *temp;

948971

temp = _PyUnicode_AsStringAndSize(encoding, &len);

949972

if (temp == NULL) {

950-

Py_DECREF(res);

973+

PyNode_Free(res);

951974

Py_DECREF(encoding);

952975

Py_DECREF(tuple);

953976

return NULL;

954977

}

955978

res->n_str = (char *)PyObject_MALLOC(len + 1);

956979

if (res->n_str == NULL) {

957-

Py_DECREF(res);

980+

PyNode_Free(res);

958981

Py_DECREF(encoding);

959982

Py_DECREF(tuple);

960983

PyErr_NoMemory();

961984

return 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

}

969994

else {

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.");

9761001

PyErr_SetObject(parser_error, err);

9771002

Py_XDECREF(err);

@@ -3433,7 +3458,6 @@ parser__pickler(PyObject *self, PyObject *args)

34333458

result = Py_BuildValue("O(O)", pickle_constructor, tuple);

34343459

Py_DECREF(tuple);

34353460

}

3436-

Py_DECREF(empty_dict);

34373461

Py_DECREF(newargs);

34383462

}

34393463

finally: