Skip to content

Commit 0ce5b6e

Browse files
author
Stefan Krah
committed
Iaaue #25598: Fix memory_hex from #9951 for non-contiguous buffers.
1 parent e46e09d commit 0ce5b6e

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

Lib/test/test_buffer.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,11 @@ def verify(self, result, obj=-1,
841841
# test tobytes()
842842
self.assertEqual(result.tobytes(), b)
843843

844+
# test hex()
845+
m = memoryview(result)
846+
h = "".join("%02x" % c for c in b)
847+
self.assertEqual(m.hex(), h)
848+
844849
# lst := expected multi-dimensional logical representation
845850
# flatten(lst) := elements in C-order
846851
ff = fmt if fmt else 'B'

Lib/test/test_memoryview.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,13 @@ def test_ctypes_cast(self):
512512
m[2:] = memoryview(p6).cast(format)[2:]
513513
self.assertEqual(d.value, 0.6)
514514

515+
def test_memoryview_hex(self):
516+
# Issue #9951: memoryview.hex() segfaults with non-contiguous buffers.
517+
x = b'0' * 200000
518+
m1 = memoryview(x)
519+
m2 = m1[::-1]
520+
self.assertEqual(m2.hex(), '30' * 200000)
521+
515522

516523
if __name__ == "__main__":
517524
unittest.main()

Objects/memoryobject.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2156,8 +2156,23 @@ static PyObject *
21562156
memory_hex(PyMemoryViewObject *self, PyObject *dummy)
21572157
{
21582158
Py_buffer *src = VIEW_ADDR(self);
2159+
PyObject *bytes;
2160+
PyObject *ret;
2161+
21592162
CHECK_RELEASED(self);
2160-
return _Py_strhex(src->buf, src->len);
2163+
2164+
if (MV_C_CONTIGUOUS(self->flags)) {
2165+
return _Py_strhex(src->buf, src->len);
2166+
}
2167+
2168+
bytes = memory_tobytes(self, dummy);
2169+
if (bytes == NULL)
2170+
return NULL;
2171+
2172+
ret = _Py_strhex(PyBytes_AS_STRING(bytes), Py_SIZE(bytes));
2173+
Py_DECREF(bytes);
2174+
2175+
return ret;
21612176
}
21622177

21632178
static PyObject *

0 commit comments

Comments
 (0)