Skip to content
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

bpo-34423: Fix check for overflow when casting from a double to integral types. #8802

Open
wants to merge 5 commits into
base: master
from

Conversation

@enedil
Copy link

@enedil enedil commented Aug 17, 2018

The added comment explains the issue. This fix disallows overflow: if a double d passes the test, it can mean that d == 2**63. When casted to int64_t, the variable overflows to -2**63.

https://bugs.python.org/issue34423

…ral types

The added comment explains the issue. This fix disallows overflow: if a double `d` passes the test, it can mean that `d == 2**63`. When casted to `int64_t`, the variable overflows to -2**63.
@asottile
Copy link
Contributor

@asottile asottile commented Aug 19, 2018

this appears linked to the wrong issue -- is this the right one? https://bugs.python.org/issue34423

@enedil
Copy link
Author

@enedil enedil commented Aug 19, 2018

@asottile Yes, you're right. My branch is wrongly named too. Should I create new pull request?

@asottile
Copy link
Contributor

@asottile asottile commented Aug 19, 2018

It might be enough to edit the commit message and title? I don't actually know

@enedil enedil changed the title bpo-32367: Fix check for overflow when casting from a double to integ… bpo-34423: Fix check for overflow when casting from a double to integ… Aug 19, 2018
@serhiy-storchaka serhiy-storchaka changed the title bpo-34423: Fix check for overflow when casting from a double to integ… bpo-34423: Fix check for overflow when casting from a double to integral types. Aug 20, 2018
Copy link
Member

@vstinner vstinner left a comment

A test should be added to test_time.

enedil added 2 commits Aug 21, 2018
@@ -917,7 +918,8 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase):
Test the C _PyTime_t API.
"""
# _PyTime_t is a 64-bit signed integer
OVERFLOW_SECONDS = math.ceil((2**63 + 1) / SEC_TO_NS)
OVERFLOW_SECONDS = math.ceil((
+ 1) / SEC_TO_NS)

This comment has been minimized.

@asottile

asottile Aug 21, 2018
Contributor

unintentional change?

Copy link
Contributor

@jdemeyer jdemeyer left a comment

I don't think that the condition sizeof(*v*) == sizeof(*type*) is really the right condition. Besides, you are applying the fix (changing <= to <) unconditionally, also when the maximal value can be represented exactly.

The problem is that the maximal value 2^N - 1 is hard to work with. So I suggest to replace

v < _Py_IntegralTypeMax(type)

by something like

v < ldexp(_Py_IntegralTypeSigned(type) ? 0.5 : 1.0, CHAR_BIT * sizeof(type))
@vstinner
Copy link
Member

@vstinner vstinner commented Feb 13, 2019

I'm not sure that we will be able to find a solution using a "simple" macro. Maybe we need new functions which takes a double as input and return an integer as output and report overflow. I'm not sure that it's possible to write a generic function.

Right now, _Py_InIntegralTypeRange() is only used to convert a double to _PyTime_t (int64_t) and time_t in pytime.c. Maybe 2 functions would be enough?

About generic code, we can maybe use the preprocessor as a template engine to generate these functions.

@jdemeyer
Copy link
Contributor

@jdemeyer jdemeyer commented Feb 13, 2019

Right now, _Py_InIntegralTypeRange() is only used to convert a double to _PyTime_t (int64_t) and time_t in pytime.c. Maybe 2 functions would be enough?

It would certainly be easier to support specific types only instead of being generic. We could for example assume that the number of bits in a double (53 assuming IEEE-754) is less than the number of bits in a int64_t (63).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants