diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2021-12-07 16:17:22 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-07 16:17:22 +0000 |
commit | d596acbd3b4f6716ed98895eb0b48e9830e0b320 (patch) | |
tree | c6d4de09bfb5f014bffe9ddb8dccc41e85057397 /Python/traceback.c | |
parent | 8319114feedd2a5b77378bba24eb9fb2689c5033 (diff) | |
download | cpython-d596acbd3b4f6716ed98895eb0b48e9830e0b320.tar.gz cpython-d596acbd3b4f6716ed98895eb0b48e9830e0b320.zip |
bpo-45635: standardize error handling in traceback.c (GH-29905)
Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
Diffstat (limited to 'Python/traceback.c')
-rw-r--r-- | Python/traceback.c | 170 |
1 files changed, 104 insertions, 66 deletions
diff --git a/Python/traceback.c b/Python/traceback.c index 8aef3d810d3..b0ff5e9a6b0 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -385,16 +385,14 @@ finally: int _Py_WriteIndent(int indent, PyObject *f) { - int err = 0; char buf[11] = " "; assert(strlen(buf) == 10); while (indent > 0) { if (indent < 10) { buf[indent] = '\0'; } - err = PyFile_WriteString(buf, f); - if (err != 0) { - return err; + if (PyFile_WriteString(buf, f) < 0) { + return -1; } indent -= 10; } @@ -407,11 +405,15 @@ _Py_WriteIndent(int indent, PyObject *f) int _Py_WriteIndentedMargin(int indent, const char *margin, PyObject *f) { - int err = _Py_WriteIndent(indent, f); - if (err == 0 && margin) { - err = PyFile_WriteString(margin, f); + if (_Py_WriteIndent(indent, f) < 0) { + return -1; } - return err; + if (margin) { + if (PyFile_WriteString(margin, f) < 0) { + return -1; + } + } + return 0; } static int @@ -419,7 +421,6 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int int margin_indent, const char *margin, int *truncation, PyObject **line) { - int err = 0; int fd; int i; char *found_encoding; @@ -502,19 +503,20 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int lineobj = PyFile_GetLine(fob, -1); if (!lineobj) { PyErr_Clear(); - err = -1; break; } } res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close); - if (res) + if (res) { Py_DECREF(res); - else + } + else { PyErr_Clear(); + } Py_DECREF(fob); if (!lineobj || !PyUnicode_Check(lineobj)) { Py_XDECREF(lineobj); - return err; + return -1; } if (line) { @@ -545,23 +547,29 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int *truncation = i - indent; } - if (err == 0) { - err = _Py_WriteIndentedMargin(margin_indent, margin, f); + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { + goto error; } + /* Write some spaces before the line */ - if (err == 0) { - err = _Py_WriteIndent(indent, f); + if (_Py_WriteIndent(indent, f) < 0) { + goto error; } /* finally display the line */ - if (err == 0) { - err = PyFile_WriteObject(lineobj, f, Py_PRINT_RAW); + if (PyFile_WriteObject(lineobj, f, Py_PRINT_RAW) < 0) { + goto error; } - Py_DECREF(lineobj); - if (err == 0) { - err = PyFile_WriteString("\n", f); + + if (PyFile_WriteString("\n", f) < 0) { + goto error; } - return err; + + Py_DECREF(lineobj); + return 0; +error: + Py_DECREF(lineobj); + return -1; } int @@ -723,41 +731,51 @@ static inline int print_error_location_carets(PyObject *f, int offset, Py_ssize_t start_offset, Py_ssize_t end_offset, Py_ssize_t right_start_offset, Py_ssize_t left_end_offset, const char *primary, const char *secondary) { - int err = 0; int special_chars = (left_end_offset != -1 || right_start_offset != -1); + const char *str; while (++offset <= end_offset) { if (offset <= start_offset || offset > end_offset) { - err = PyFile_WriteString(" ", f); + str = " "; } else if (special_chars && left_end_offset < offset && offset <= right_start_offset) { - err = PyFile_WriteString(secondary, f); + str = secondary; } else { - err = PyFile_WriteString(primary, f); + str = primary; + } + if (PyFile_WriteString(str, f) < 0) { + return -1; } } - err = PyFile_WriteString("\n", f); - return err; + if (PyFile_WriteString("\n", f) < 0) { + return -1; + } + return 0; } static int tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int lineno, PyFrameObject *frame, PyObject *name, int margin_indent, const char *margin) { - int err; - PyObject *line; + if (filename == NULL || name == NULL) { + return -1; + } - if (filename == NULL || name == NULL) + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { return -1; - line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", - filename, lineno, name); - if (line == NULL) + } + + PyObject *line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", + filename, lineno, name); + if (line == NULL) { return -1; - err = _Py_WriteIndentedMargin(margin_indent, margin, f); - if (err == 0) { - err = PyFile_WriteObject(line, f, Py_PRINT_RAW); } + + int res = PyFile_WriteObject(line, f, Py_PRINT_RAW); Py_DECREF(line); - if (err != 0) - return err; + if (res < 0) { + return -1; + } + + int err = 0; int truncation = _TRACEBACK_SOURCE_LINE_INDENT; PyObject* source_line = NULL; @@ -849,11 +867,16 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen end_offset = i + 1; } - err = _Py_WriteIndentedMargin(margin_indent, margin, f); - if (err == 0) { - err = print_error_location_carets(f, truncation, start_offset, end_offset, - right_start_offset, left_end_offset, - primary_error_char, secondary_error_char); + if (_Py_WriteIndentedMargin(margin_indent, margin, f) < 0) { + err = -1; + goto done; + } + + if (print_error_location_carets(f, truncation, start_offset, end_offset, + right_start_offset, left_end_offset, + primary_error_char, secondary_error_char) < 0) { + err = -1; + goto done; } done: @@ -884,7 +907,7 @@ static int tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, int indent, const char *margin) { - int err = 0; + PyCodeObject *code = NULL; Py_ssize_t depth = 0; PyObject *last_file = NULL; int last_line = -1; @@ -899,14 +922,16 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, depth--; tb = tb->tb_next; } - while (tb != NULL && err == 0) { - PyCodeObject *code = PyFrame_GetCode(tb->tb_frame); + while (tb != NULL) { + code = PyFrame_GetCode(tb->tb_frame); if (last_file == NULL || code->co_filename != last_file || last_line == -1 || tb->tb_lineno != last_line || last_name == NULL || code->co_name != last_name) { if (cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); + if (tb_print_line_repeated(f, cnt) < 0) { + goto error; + } } last_file = code->co_filename; last_line = tb->tb_lineno; @@ -914,20 +939,28 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit, cnt = 0; } cnt++; - if (err == 0 && cnt <= TB_RECURSIVE_CUTOFF) { - err = tb_displayline(tb, f, code->co_filename, tb->tb_lineno, - tb->tb_frame, code->co_name, indent, margin); - if (err == 0) { - err = PyErr_CheckSignals(); + if (cnt <= TB_RECURSIVE_CUTOFF) { + if (tb_displayline(tb, f, code->co_filename, tb->tb_lineno, + tb->tb_frame, code->co_name, indent, margin) < 0) { + goto error; + } + + if (PyErr_CheckSignals() < 0) { + goto error; } } - Py_DECREF(code); + Py_CLEAR(code); tb = tb->tb_next; } - if (err == 0 && cnt > TB_RECURSIVE_CUTOFF) { - err = tb_print_line_repeated(f, cnt); + if (cnt > TB_RECURSIVE_CUTOFF) { + if (tb_print_line_repeated(f, cnt) < 0) { + goto error; + } } - return err; + return 0; +error: + Py_XDECREF(code); + return -1; } #define PyTraceBack_LIMIT 1000 @@ -936,12 +969,12 @@ int _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, const char *header_margin, const char *header, PyObject *f) { - int err; PyObject *limitv; long limit = PyTraceBack_LIMIT; - if (v == NULL) + if (v == NULL) { return 0; + } if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; @@ -957,14 +990,19 @@ _PyTraceBack_Print_Indented(PyObject *v, int indent, const char *margin, return 0; } } - err = _Py_WriteIndentedMargin(indent, header_margin, f); - if (err == 0) { - err = PyFile_WriteString(header, f); + if (_Py_WriteIndentedMargin(indent, header_margin, f) < 0) { + return -1; + } + + if (PyFile_WriteString(header, f) < 0) { + return -1; } - if (err == 0) { - err = tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin); + + if (tb_printinternal((PyTracebackObject *)v, f, limit, indent, margin) < 0) { + return -1; } - return err; + + return 0; } int |