Skip to content

Commit b3e8b33

Browse files
committed
gh-156867: struct.pack() check for overflows for Zf type
1 parent 5056ac5 commit b3e8b33

3 files changed

Lines changed: 20 additions & 3 deletions

File tree

Lib/test/test_struct.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,16 @@ def test_705836(self):
424424
self.assertRaises(OverflowError, struct.pack, "<e", big)
425425
self.assertRaises(OverflowError, struct.pack, "e", big)
426426

427+
def test_156867(self):
428+
big_real = 1e300
429+
self.assertRaises(OverflowError, struct.pack, ">Zf", big_real)
430+
self.assertRaises(OverflowError, struct.pack, "<Zf", big_real)
431+
self.assertRaises(OverflowError, struct.pack, "Zf", big_real)
432+
big_imag = 1e300j
433+
self.assertRaises(OverflowError, struct.pack, ">Zf", big_imag)
434+
self.assertRaises(OverflowError, struct.pack, "<Zf", big_imag)
435+
self.assertRaises(OverflowError, struct.pack, "Zf", big_imag)
436+
427437
def test_1530559(self):
428438
for code, byteorder in iter_integer_formats():
429439
format = byteorder + code
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Raise :exc:`OverflowError`'s for native ``'Zf'`` format in :func:`struct.pack`,
2+
like for ``'f'`` format. Previously overflows in the :c:expr:`float complex`
3+
type were silent. Patch by Sergey B Kirpichev.

Modules/_struct.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -790,15 +790,19 @@ np_float_complex(_structmodulestate *state, char *p, PyObject *v,
790790
const formatdef *f)
791791
{
792792
Py_complex c = PyComplex_AsCComplex(v);
793-
float x[2] = {(float)c.real, (float)c.imag};
794793

795794
if (c.real == -1 && PyErr_Occurred()) {
796795
PyErr_SetString(state->StructError,
797796
"required argument is not a complex");
798797
return -1;
799798
}
800-
memcpy(p, &x, sizeof(x));
801-
return 0;
799+
800+
int ret = PyFloat_Pack4(c.real, p, PY_LITTLE_ENDIAN);
801+
802+
if (ret) {
803+
return ret;
804+
}
805+
return PyFloat_Pack4(c.imag, p + sizeof(float), PY_LITTLE_ENDIAN);
802806
}
803807

804808
static int

0 commit comments

Comments
 (0)