summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2015-06-16 13:36:39 -0400
committerNed Batchelder <ned@nedbatchelder.com>2015-06-16 13:36:39 -0400
commit05e2907441ef6aed39feaf2355a02ef735f6cede (patch)
tree66f9c5b3f1b426f6a61b889b7d4eb5f7e3410a17 /coverage
parent3d902a9c0bde67f360bb14138ed89346f5941b01 (diff)
downloadpython-coveragepy-git-05e2907441ef6aed39feaf2355a02ef735f6cede.tar.gz
Be more careful about reading bytecodes. #375
Diffstat (limited to 'coverage')
-rw-r--r--coverage/tracer.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/coverage/tracer.c b/coverage/tracer.c
index fdd89d8c..7cdb7727 100644
--- a/coverage/tracer.c
+++ b/coverage/tracer.c
@@ -22,6 +22,7 @@
#define MyText_Type PyUnicode_Type
#define MyText_AS_BYTES(o) PyUnicode_AsASCIIString(o)
+#define MyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o)
#define MyBytes_AS_STRING(o) PyBytes_AS_STRING(o)
#define MyText_AsString(o) PyUnicode_AsUTF8(o)
#define MyText_FromFormat PyUnicode_FromFormat
@@ -34,6 +35,7 @@
#define MyText_Type PyString_Type
#define MyText_AS_BYTES(o) (Py_INCREF(o), o)
+#define MyBytes_GET_SIZE(o) PyString_GET_SIZE(o)
#define MyBytes_AS_STRING(o) PyString_AS_STRING(o)
#define MyText_AsString(o) PyString_AsString(o)
#define MyText_FromFormat PyUnicode_FromFormat
@@ -828,8 +830,18 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame)
}
if (self->pdata_stack->depth >= 0) {
if (self->tracing_arcs && self->cur_entry.file_data) {
- /* Need to distinguish between RETURN_VALUE and YIELD_VALUE. */
- int bytecode = MyBytes_AS_STRING(frame->f_code->co_code)[frame->f_lasti];
+ /* Need to distinguish between RETURN_VALUE and YIELD_VALUE. Read
+ * the current bytecode to see what it is. In unusual circumstances
+ * (Cython code), co_code can be the empty string, so range-check
+ * f_lasti before reading the byte.
+ */
+ int bytecode = RETURN_VALUE;
+ PyObject * pCode = frame->f_code->co_code;
+ int lasti = frame->f_lasti;
+
+ if (lasti < MyBytes_GET_SIZE(pCode)) {
+ bytecode = MyBytes_AS_STRING(pCode)[lasti];
+ }
if (bytecode != YIELD_VALUE) {
int first = frame->f_code->co_firstlineno;
if (CTracer_record_pair(self, self->cur_entry.last_line, -first) < 0) {