@@ -583,9 +583,9 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
583
583
return -1 ;
584
584
}
585
585
std::memset (view, 0 , sizeof (Py_buffer));
586
- buffer_info * info = nullptr ;
586
+ std::unique_ptr< buffer_info> info = nullptr ;
587
587
try {
588
- info = tinfo->get_buffer (obj, tinfo->get_buffer_data );
588
+ info. reset ( tinfo->get_buffer (obj, tinfo->get_buffer_data ) );
589
589
} catch (...) {
590
590
try_translate_exceptions ();
591
591
raise_from (PyExc_BufferError, " Error getting buffer" );
@@ -596,17 +596,13 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
596
596
}
597
597
598
598
if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly ) {
599
- delete info;
600
599
// view->obj = nullptr; // Was just memset to 0, so not necessary
601
600
set_error (PyExc_BufferError, " Writable buffer requested for readonly storage" );
602
601
return -1 ;
603
602
}
604
603
605
604
// Fill in all the information, and then downgrade as requested by the caller, or raise an
606
605
// error if that's not possible.
607
- view->obj = obj;
608
- view->internal = info;
609
- view->buf = info->ptr ;
610
606
view->itemsize = info->itemsize ;
611
607
view->len = view->itemsize ;
612
608
for (auto s : info->shape ) {
@@ -624,23 +620,20 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
624
620
if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) {
625
621
if (PyBuffer_IsContiguous (view, ' C' ) == 0 ) {
626
622
std::memset (view, 0 , sizeof (Py_buffer));
627
- delete info;
628
623
set_error (PyExc_BufferError,
629
624
" C-contiguous buffer requested for discontiguous storage" );
630
625
return -1 ;
631
626
}
632
627
} else if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) {
633
628
if (PyBuffer_IsContiguous (view, ' F' ) == 0 ) {
634
629
std::memset (view, 0 , sizeof (Py_buffer));
635
- delete info;
636
630
set_error (PyExc_BufferError,
637
631
" Fortran-contiguous buffer requested for discontiguous storage" );
638
632
return -1 ;
639
633
}
640
634
} else if ((flags & PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS) {
641
635
if (PyBuffer_IsContiguous (view, ' A' ) == 0 ) {
642
636
std::memset (view, 0 , sizeof (Py_buffer));
643
- delete info;
644
637
set_error (PyExc_BufferError, " Contiguous buffer requested for discontiguous storage" );
645
638
return -1 ;
646
639
}
@@ -650,7 +643,6 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
650
643
// https://docs.python.org/3/c-api/buffer.html#contiguity-requests
651
644
if (PyBuffer_IsContiguous (view, ' C' ) == 0 ) {
652
645
std::memset (view, 0 , sizeof (Py_buffer));
653
- delete info;
654
646
set_error (PyExc_BufferError,
655
647
" C-contiguous buffer requested for discontiguous storage" );
656
648
return -1 ;
@@ -665,6 +657,11 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
665
657
}
666
658
}
667
659
660
+ // Set these after all checks so they don't leak out into the caller, and can be automatically
661
+ // cleaned up on error.
662
+ view->buf = info->ptr ;
663
+ view->internal = info.release ();
664
+ view->obj = obj;
668
665
Py_INCREF (view->obj );
669
666
return 0 ;
670
667
}
0 commit comments