Issue #23517: Fix _PyTime_ObjectToDenominator()
* initialize numerator on overflow error ensure that numerator is smaller than * denominator.
This commit is contained in:
parent
a53ec7a91a
commit
67edcc905d
|
@ -60,6 +60,7 @@ _PyLong_FromTime_t(time_t t)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Round to nearest with ties going away from zero (_PyTime_ROUND_HALF_UP). */
|
||||||
static double
|
static double
|
||||||
_PyTime_RoundHalfUp(double x)
|
_PyTime_RoundHalfUp(double x)
|
||||||
{
|
{
|
||||||
|
@ -81,32 +82,31 @@ _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
|
||||||
|
|
||||||
floatpart = modf(d, &intpart);
|
floatpart = modf(d, &intpart);
|
||||||
if (floatpart < 0) {
|
if (floatpart < 0) {
|
||||||
floatpart = 1.0 + floatpart;
|
floatpart += 1.0;
|
||||||
intpart -= 1.0;
|
intpart -= 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
floatpart *= denominator;
|
floatpart *= denominator;
|
||||||
if (round == _PyTime_ROUND_HALF_UP)
|
if (round == _PyTime_ROUND_HALF_UP)
|
||||||
floatpart = _PyTime_RoundHalfUp(floatpart);
|
floatpart = _PyTime_RoundHalfUp(floatpart);
|
||||||
else if (round == _PyTime_ROUND_CEILING) {
|
else if (round == _PyTime_ROUND_CEILING)
|
||||||
floatpart = ceil(floatpart);
|
floatpart = ceil(floatpart);
|
||||||
if (floatpart >= denominator) {
|
else
|
||||||
floatpart = 0.0;
|
|
||||||
intpart += 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
floatpart = floor(floatpart);
|
floatpart = floor(floatpart);
|
||||||
|
if (floatpart >= denominator) {
|
||||||
|
floatpart -= denominator;
|
||||||
|
intpart += 1.0;
|
||||||
}
|
}
|
||||||
|
assert(0.0 <= floatpart && floatpart < denominator);
|
||||||
|
|
||||||
*sec = (time_t)intpart;
|
*sec = (time_t)intpart;
|
||||||
|
*numerator = (long)floatpart;
|
||||||
|
|
||||||
err = intpart - (double)*sec;
|
err = intpart - (double)*sec;
|
||||||
if (err <= -1.0 || err >= 1.0) {
|
if (err <= -1.0 || err >= 1.0) {
|
||||||
error_time_t_overflow();
|
error_time_t_overflow();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*numerator = (long)floatpart;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*sec = _PyLong_AsTime_t(obj);
|
*sec = _PyLong_AsTime_t(obj);
|
||||||
|
*numerator = 0;
|
||||||
if (*sec == (time_t)-1 && PyErr_Occurred())
|
if (*sec == (time_t)-1 && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
*numerator = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
|
res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
|
||||||
assert(0 <= *nsec && *nsec < SEC_TO_NS );
|
assert(0 <= *nsec && *nsec < SEC_TO_NS);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
|
res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
|
||||||
assert(0 <= *usec && *usec < SEC_TO_US );
|
assert(0 <= *usec && *usec < SEC_TO_US);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,12 +444,11 @@ _PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
|
||||||
tv->tv_sec += 1;
|
tv->tv_sec += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(0 <= usec && usec < SEC_TO_US);
|
||||||
|
tv->tv_usec = usec;
|
||||||
|
|
||||||
if (res && raise)
|
if (res && raise)
|
||||||
_PyTime_overflow();
|
_PyTime_overflow();
|
||||||
|
|
||||||
assert(0 <= usec && usec <= 999999);
|
|
||||||
|
|
||||||
tv->tv_usec = usec;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +483,7 @@ _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)
|
||||||
}
|
}
|
||||||
ts->tv_nsec = nsec;
|
ts->tv_nsec = nsec;
|
||||||
|
|
||||||
assert(0 <= ts->tv_nsec && ts->tv_nsec <= 999999999);
|
assert(0 <= ts->tv_nsec && ts->tv_nsec < SEC_TO_NS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue