Mailing List Archive

bpo-45635: standardize error handling in traceback.c (GH-29905)
https://github.com/python/cpython/commit/d596acbd3b4f6716ed98895eb0b48e9830e0b320
commit: d596acbd3b4f6716ed98895eb0b48e9830e0b320
branch: main
author: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel@users.noreply.github.com>
date: 2021-12-07T16:17:22Z
summary:

bpo-45635: standardize error handling in traceback.c (GH-29905)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>

files:
M Python/traceback.c

diff --git a/Python/traceback.c b/Python/traceback.c
index 8aef3d810d316..b0ff5e9a6b075 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -385,16 +385,14 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
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

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins