-
-
Notifications
You must be signed in to change notification settings - Fork 35k
bpo-31373: fix undefined floating-point demotions #3396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Fix several possible instances of undefined behavior due to floating-point | ||
| demotions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2233,21 +2233,23 @@ _PyFloat_Pack4(double x, unsigned char *p, int le) | |
|
|
||
| } | ||
| else { | ||
| float y = (float)x; | ||
| const unsigned char *s = (unsigned char*)&y; | ||
| int i, incr = 1; | ||
|
|
||
| if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x)) | ||
| if (fabs(x) > FLT_MAX && !Py_IS_INFINITY(x)) | ||
| goto Overflow; | ||
|
|
||
| unsigned char s[sizeof(float)]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would be more confident with an assert(sizeof(float) == 4); just in case.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code only executes if floats are in IEE754 format and are therefore 4 bytes. |
||
| float y = (float)x; | ||
| memcpy(s, &y, sizeof(float)); | ||
|
|
||
| if ((float_format == ieee_little_endian_format && !le) | ||
| || (float_format == ieee_big_endian_format && le)) { | ||
| p += 3; | ||
| incr = -1; | ||
| } | ||
|
|
||
| for (i = 0; i < 4; i++) { | ||
| *p = *s++; | ||
| *p = s[i]; | ||
| p += incr; | ||
| } | ||
| return 0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| #include "Python.h" | ||
|
|
||
| #include <ctype.h> | ||
| #include <float.h> | ||
|
|
||
|
|
||
| #ifdef __cplusplus | ||
|
|
@@ -858,6 +859,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, | |
| double dval = PyFloat_AsDouble(arg); | ||
| if (PyErr_Occurred()) | ||
| RETURN_ERR_OCCURRED; | ||
| else if (dval > FLT_MAX) | ||
| *p = (float)INFINITY; | ||
| else if (dval < -FLT_MAX) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to use FLT_MIN.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| *p = (float)-INFINITY; | ||
| else | ||
| *p = (float) dval; | ||
| break; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why you remove Py_IS_INFINITY(y).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yis no longer defined at this point.