bpo-31373: fix undefined floating-point demotions (#3396) · pythoncapi/cpython@a853a8b · GitHub
Skip to content

Commit a853a8b

Browse files
authored
bpo-31373: fix undefined floating-point demotions (python#3396)
1 parent c988ae0 commit a853a8b

5 files changed

Lines changed: 52 additions & 31 deletions

File tree

Include/pymath.h

Lines changed: 23 additions & 11 deletions
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix several possible instances of undefined behavior due to floating-point
2+
demotions.

Objects/floatobject.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,21 +2233,23 @@ _PyFloat_Pack4(double x, unsigned char *p, int le)
22332233

22342234
}
22352235
else {
2236-
float y = (float)x;
2237-
const unsigned char *s = (unsigned char*)&y;
22382236
int i, incr = 1;
22392237

2240-
if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
2238+
if (fabs(x) > FLT_MAX && !Py_IS_INFINITY(x))
22412239
goto Overflow;
22422240

2241+
unsigned char s[sizeof(float)];
2242+
float y = (float)x;
2243+
memcpy(s, &y, sizeof(float));
2244+
22432245
if ((float_format == ieee_little_endian_format && !le)
22442246
|| (float_format == ieee_big_endian_format && le)) {
22452247
p += 3;
22462248
incr = -1;
22472249
}
22482250

22492251
for (i = 0; i < 4; i++) {
2250-
*p = *s++;
2252+
*p = s[i];
22512253
p += incr;
22522254
}
22532255
return 0;

Python/getargs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "Python.h"
55

66
#include <ctype.h>
7+
#include <float.h>
78

89

910
#ifdef __cplusplus
@@ -858,6 +859,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
858859
double dval = PyFloat_AsDouble(arg);
859860
if (PyErr_Occurred())
860861
RETURN_ERR_OCCURRED;
862+
else if (dval > FLT_MAX)
863+
*p = (float)INFINITY;
864+
else if (dval < -FLT_MAX)
865+
*p = (float)-INFINITY;
861866
else
862867
*p = (float) dval;
863868
break;

Python/pytime.c

Lines changed: 16 additions & 16 deletions

0 commit comments

Comments
 (0)