[New-bugs-announce] [issue7743] Additional potential string -> float conversion issues.

Mark Dickinson report at bugs.python.org
Wed Jan 20 14:12:20 CET 2010


New submission from Mark Dickinson <dickinsm at gmail.com>:

1. Another potential crash caused by Python/dtoa.c:  if the bigcomp functionality is disabled by replacing "#define STRTOD_DIGLIM 40" with "#define STRTOD_DIGLIM 4000", then the following string causes a crash:

>>> s = '5254406533529552661096610603582028195612589849649138922565278497589560452182570597137658742514361936194432482059988700016338656575174473559922258529459120166686600002102838072098506622244175047522649953606315120077538558010753730576321577387528008403025962370502479105305382500086822727836607781816280407336531214924364088126680234780012085291903592543223403975751852488447885154107229587846409265285440430901153525136408849880173424692750069991045196209464308187671479664954854065777039726878381767789934729895619590000470366389383963331466851379030183764964083197053338684769252973171365139701890736933147103189912528110505014483268752328506004517760913030437151571912928276140468769502257147431182910347804663250851413437345649151934269945872064326973371182115272789687312946393533547747886024677951678751174816604738791256853675690543663283782215866825e-1180'
[38199 refs]
>>> float(s)
cmp called with a->x[a->wds-1] == 0

I haven't yet found any examples that cause this crash without bigcomp enabled.

The crash is caused by a combination of two problems. (1) there's a buggy check for the smallest denormal in the "if ((aadj = ratio(delta, bs)) <= 2.) {" block in _Py_dg_strtod:  the check ignores the possibility that bc.scale is nonzero.  (2) The Bigint functions don't deal well with zero inputs:  in particular, d2b gives strange results, and left shifting a zero Bigint can give a non-normalized result.

2. The check:

            if (!(word1(&rv) & LSB))
                break;

in _Py_dg_strtod again doesn't take into account the possibility that bc->scale is nonzero.  It's supposed to be used in exact halfway cases to determine whether the current rv is already 'even' for the purposes of round-half-to-even.  But for subnormal scaled rv, this check will (wrongly) always succeed, potentially giving an incorrectly rounded result.

However, it seems to be difficult to trigger this bug:  the input must be a subnormal exact halfway case, which implies it must have many hundred digits.  On the first pass through the strtod correction loop, the approximation is likely to be out by a few ulps, so we almost never hit the (i == 0) branch.  The adjustment for the second pass then typically gives *exactly* the right result, as a consequence of the floating-point addition using round-half-to-even.

----------
assignee: mark.dickinson
components: Interpreter Core
messages: 98080
nosy: mark.dickinson
priority: normal
severity: normal
stage: needs patch
status: open
title: Additional potential string -> float conversion issues.
type: behavior
versions: Python 2.7, Python 3.1, Python 3.2

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue7743>
_______________________________________


More information about the New-bugs-announce mailing list