Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ff098b

Browse files
committed
FIX: segfault on truncated png
- be more paranoid in _read_png_data about failed reads and check for exceptions after both calls to it - in read_png_data kick the png error handling - only override the exception in the body of `setjmp` handler if there is not already one set closes #9256
1 parent c8c76ad commit 7ff098b

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

src/_png.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,21 @@ static void _read_png_data(PyObject *py_file_obj, png_bytep data, png_size_t len
408408
Py_ssize_t bufflen;
409409
if (read_method) {
410410
result = PyObject_CallFunction(read_method, (char *)"i", length);
411-
if (PyBytes_AsStringAndSize(result, &buffer, &bufflen) == 0) {
412-
if (bufflen == (Py_ssize_t)length) {
413-
memcpy(data, buffer, length);
414-
} else {
415-
PyErr_SetString(PyExc_IOError, "read past end of file");
416-
}
417-
}
411+
if (result) {
412+
if (PyBytes_AsStringAndSize(result, &buffer, &bufflen) == 0) {
413+
if (bufflen == (Py_ssize_t)length) {
414+
memcpy(data, buffer, length);
415+
} else {
416+
PyErr_SetString(PyExc_IOError, "read past end of file");
417+
}
418+
} else {
419+
PyErr_SetString(PyExc_IOError, "Failed to copy buffer");
420+
}
421+
} else {
422+
PyErr_SetString(PyExc_IOError, "Failed to read file");
423+
}
424+
425+
418426
}
419427
Py_XDECREF(read_method);
420428
Py_XDECREF(result);
@@ -424,6 +432,11 @@ static void read_png_data(png_structp png_ptr, png_bytep data, png_size_t length
424432
{
425433
PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
426434
_read_png_data(py_file_obj, data, length);
435+
if (PyErr_Occurred())
436+
{
437+
png_error(png_ptr, "failed to read file");
438+
}
439+
427440
}
428441

429442
static PyObject *_read_png(PyObject *filein, bool float_result)
@@ -481,6 +494,9 @@ static PyObject *_read_png(PyObject *filein, bool float_result)
481494
}
482495
Py_XDECREF(read_method);
483496
_read_png_data(py_file, header, 8);
497+
if (PyErr_Occurred()){
498+
goto exit;
499+
}
484500
}
485501

486502
if (png_sig_cmp(header, 0, 8)) {
@@ -503,7 +519,10 @@ static PyObject *_read_png(PyObject *filein, bool float_result)
503519
}
504520

505521
if (setjmp(png_jmpbuf(png_ptr))) {
506-
PyErr_SetString(PyExc_RuntimeError, "Error setting jump");
522+
if (!PyErr_Occurred())
523+
{
524+
PyErr_SetString(PyExc_RuntimeError, "Error setting jump");
525+
}
507526
goto exit;
508527
}
509528

0 commit comments

Comments
 (0)