[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2022-02-07 Thread STINNER Victor


STINNER Victor  added the comment:


New changeset d3e53bc5321a9f08c7ed5b9383eefb2e03dfa6e2 by Victor Stinner in 
branch 'main':
bpo-39277: Fix PY_TIMEOUT_MAX cast in _threadmodule.c (GH-31195)
https://github.com/python/cpython/commit/d3e53bc5321a9f08c7ed5b9383eefb2e03dfa6e2


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2022-02-07 Thread STINNER Victor


Change by STINNER Victor :


--
pull_requests: +29365
pull_request: https://github.com/python/cpython/pull/31195

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-06-25 Thread Stefan Krah


Stefan Krah  added the comment:

C99, 6.3.1.4 Real floating and integer:

"""
When a value of integer type is converted to a real floating type, if the value 
being
converted can be represented exactly in the new type, it is unchanged. If the 
value being
converted is in the range of values that can be represented but cannot be 
represented

exactly, the result is either the nearest higher or nearest lower representable 
value, chosen
in an implementation-defined manner. If the value being converted is outside 
the range of
values that can be represented, the behavior is undefined.
"""

So int64_t => double is implementation defined, but not undefined.

float___trunc___impl() looks correct to me (of course we can squash
that warning).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-06-24 Thread Stefan Krah


Stefan Krah  added the comment:

Is it a bug in float.__trunc__()? It seems to me that the detailed comment 
accounts for case of rounding up.

That's why < is used instead of <=.

--
nosy: +skrah, tim.peters

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-03-12 Thread STINNER Victor


STINNER Victor  added the comment:

Oh, clang on FreeBSD spotted a similar bug in float.__trunc__()!

static PyObject *
float___trunc___impl(PyObject *self)
/*[clinic end generated code: output=dd3e289dd4c6b538 input=591b9ba0d650fdff]*/
{
double x = PyFloat_AsDouble(self);
double wholepart;   /* integral portion of x, rounded toward 0 */

(void)modf(x, &wholepart);
/* Try to get out cheap if this fits in a Python int.  The attempt
 * to cast to long must be protected, as C doesn't define what
 * happens if the double is too big to fit in a long.  Some rare
 * systems raise an exception then (RISCOS was mentioned as one,
 * and someone using a non-default option on Sun also bumped into
 * that).  Note that checking for >= and <= LONG_{MIN,MAX} would
 * still be vulnerable:  if a long has more bits of precision than
 * a double, casting MIN/MAX to double may yield an approximation,
 * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would
 * yield true from the C expression wholepart<=LONG_MAX, despite
 * that wholepart is actually greater than LONG_MAX.
 */
if (LONG_MIN < wholepart && wholepart < LONG_MAX) {  /* <=== HERE */
const long aslong = (long)wholepart;
return PyLong_FromLong(aslong);
}
return PyLong_FromDouble(wholepart);
}


Objects/floatobject.c:881:45: warning: implicit conversion from 'long' to 
'double' changes value from 9223372036854775807 to 9223372036854775808
  [-Wimplicit-int-float-conversion]
if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
  ~ ^~~~
/usr/include/sys/limits.h:64:18: note: expanded from macro 'LONG_MAX'
#define LONG_MAX__LONG_MAX  /* max for a long */
^~
/usr/include/x86/_limits.h:64:20: note: expanded from macro '__LONG_MAX'
#define __LONG_MAX  0x7fff  /* max for a long */
^~
1 warning generated.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-10 Thread STINNER Victor


STINNER Victor  added the comment:

Similar issue in HHVM:

* https://github.com/facebook/hhvm/issues/5932
* https://github.com/PPC64/hhvm/commit/7cdb76b4f495aa7aa40a696379862916c27f5828

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-10 Thread STINNER Victor


Change by STINNER Victor :


--
keywords: +patch
pull_requests: +17338
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/17933

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-10 Thread STINNER Victor


STINNER Victor  added the comment:

_PyTime_FromDouble() checks if!(_Py_DoubleInIntegralTypeRange(_PyTime_t, d)) 
with the macro:

#define _Py_InIntegralTypeRange(type, v) (_Py_IntegralTypeMin(type) <= v && v 
<= _Py_IntegralTypeMax(type))

and _Py_IntegralTypeMax(type)=2**63-1.

"v <= _Py_IntegralTypeMax(type)" compares a C double to a C int64_t: the 
compiler casts the C int64_t to a C double.

The problem is that 2**63-1 casted to a C double rounds using ROUND_HALF_EVEN 
rounding mode which gives a number *greater* than 2**63-1: we get 2**63.

To implement "v <= max", we have to round max towards zero (ROUND_DOWN), not 
round it using ROUND_HALF_EVEN.

I didn't find a way to control the rounding mode of casting C int64_t to C 
double, but we can round it *afterwards* using nextafter(max, 0.0) (ROUND_DOWN).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-09 Thread Thomas Grainger


Change by Thomas Grainger :


--
versions:  -Python 2.7

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-09 Thread STINNER Victor


STINNER Victor  added the comment:

It's a bug in _PyTime_FromDouble() which fails to detect the integer overflow 
when casting a C double to a C _PyTime_T (int64_t): bug in 
_Py_InIntegralTypeRange(_PyTime_t, d) where d is a C double.

On my Fedora 31, double is a 64-bit IEEE 754 float, _PyTime_t is int64_t 
(64-bit signed integer).

_PyTime_t maximum is 9223372036854775807. But casted as C double, it becomes 
9223372036854775808:

>>> int(float(9223372036854775807))
9223372036854775808

--
nosy: +benjamin.peterson

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39277] _PyTime_FromDouble() fails to detect an integer overflow when converting a C double to a C int64_t

2020-01-09 Thread Thomas Grainger


New submission from Thomas Grainger :

_PyTime_FromDouble() fails to detect an integer overflow when converting a C 
double to a C int64_t

Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
[GCC 9.2.1 20191008] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.sleep(9223372036.854777)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: sleep length must be non-negative

--
messages: 359682
nosy: graingert, vstinner
priority: normal
severity: normal
status: open
title: _PyTime_FromDouble() fails to detect an integer overflow when converting 
a C double to a C int64_t
type: behavior
versions: Python 2.7, Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com