Skip to content

Commit 8a85c8c

Browse files
committed
gh-156865: correctly handle overflows in memoryview
1 parent 7b4364d commit 8a85c8c

3 files changed

Lines changed: 29 additions & 4 deletions

File tree

Lib/test/test_memoryview.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,23 @@ def test_picklebuffer_reference_loop(self):
931931
gc.collect()
932932
self.assertIsNone(wr())
933933

934+
def test_overflows_in_floats(self):
935+
array = import_helper.import_module("array")
936+
half_data = array.array('e', [0.0])
937+
float_data = array.array('f', [0.0])
938+
complex_data = array.array('Zf', [0.0])
939+
half_view = memoryview(half_data)
940+
float_view = memoryview(float_data)
941+
complex_view = memoryview(complex_data)
942+
with self.assertRaises(ValueError):
943+
half_view[0] = 123456.0
944+
with self.assertRaises(ValueError):
945+
float_view[0] = 1e300
946+
with self.assertRaises(ValueError):
947+
complex_view[0] = 1e300
948+
with self.assertRaises(ValueError):
949+
complex_view[0] = 1e300j
950+
934951

935952
@threading_helper.requires_working_threading()
936953
@support.requires_resource("cpu")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Raise :exc:`ValueError`'s for overflows, while trying to change
2+
:class:`memoryview` elements with ``'f'`` and ``'Zf'`` format codes. Patch
3+
by Sergey B Kirpichev.

Objects/memoryobject.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,7 +2037,9 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt
20372037
goto err_occurred;
20382038
CHECK_RELEASED_INT_AGAIN(self);
20392039
if (fmt[0] == 'f') {
2040-
PACK_SINGLE(ptr, d, float);
2040+
if (PyFloat_Pack4(d, ptr, endian) < 0) {
2041+
goto err_occurred;
2042+
}
20412043
}
20422044
else if (fmt[0] == 'd') {
20432045
PACK_SINGLE(ptr, d, double);
@@ -2064,9 +2066,12 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt
20642066
memcpy(ptr, &x, sizeof(x));
20652067
}
20662068
else {
2067-
float x[2] = {(float)c.real, (float)c.imag};
2068-
2069-
memcpy(ptr, &x, sizeof(x));
2069+
if (PyFloat_Pack4(c.real, ptr, endian) < 0) {
2070+
goto err_occurred;
2071+
}
2072+
if (PyFloat_Pack4(c.imag, ptr + sizeof(float), endian) < 0) {
2073+
goto err_occurred;
2074+
}
20702075
}
20712076
break;
20722077

0 commit comments

Comments
 (0)