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

Additional potential string -> float conversion issues. #51991

Closed
mdickinson opened this issue Jan 20, 2010 · 7 comments
Closed

Additional potential string -> float conversion issues. #51991

mdickinson opened this issue Jan 20, 2010 · 7 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@mdickinson
Copy link
Member

BPO 7743
Nosy @mdickinson, @ericvsmith, @cjw296

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/mdickinson'
closed_at = <Date 2010-01-23.20:49:21.607>
created_at = <Date 2010-01-20.13:12:18.056>
labels = ['interpreter-core', 'type-bug']
title = 'Additional potential string -> float conversion issues.'
updated_at = <Date 2010-01-23.20:49:21.605>
user = 'https://github.com/mdickinson'

bugs.python.org fields:

activity = <Date 2010-01-23.20:49:21.605>
actor = 'mark.dickinson'
assignee = 'mark.dickinson'
closed = True
closed_date = <Date 2010-01-23.20:49:21.607>
closer = 'mark.dickinson'
components = ['Interpreter Core']
creation = <Date 2010-01-20.13:12:18.056>
creator = 'mark.dickinson'
dependencies = []
files = []
hgrepos = []
issue_num = 7743
keywords = []
message_count = 7.0
messages = ['98080', '98081', '98153', '98183', '98185', '98186', '98199']
nosy_count = 3.0
nosy_names = ['mark.dickinson', 'eric.smith', 'cjw296']
pr_nums = []
priority = 'normal'
resolution = 'fixed'
stage = 'needs patch'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue7743'
versions = ['Python 3.1', 'Python 2.7', 'Python 3.2']

@mdickinson
Copy link
Member Author

  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.

  1. 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.

@mdickinson mdickinson self-assigned this Jan 20, 2010
@mdickinson mdickinson added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Jan 20, 2010
@mdickinson
Copy link
Member Author

Okay, it's not that difficult to trigger (2). With the bigcomp functionality disabled as above:

AssertionError: Incorrectly rounded str->float conversion for 11651287494059419563861790709256988151903479322938522856916519154189084656466977171489691608488398792047332126810029685763620092606534076968286334920536334924763766067178320990794927368304039797998410780646182269333271282839761794603623958163297658510063352026077076106072540390412314438457161207373275477458821194440646557259102208197382844892733860255628785183174541939743301249188486945446244053689504749943655197464973191717009938776287102040358299419343976193341216682148401588363162253931420379903449798213003874174172790742957567330246138038659650118748200625752770984217933648838167281879845022933912352785884444833681591202045229462491699354638895656152216187535257259042082360747878839946016222830869374205287663441403533948204085390898399055004119873046875e-1075: expected 0x0.0d67b36890cfcp-1022, got 0x0.0d67b36890cfbp-1022

@mdickinson
Copy link
Member Author

Second bug listed here fixed in r77698 in the trunk.

@cjw296
Copy link
Contributor

cjw296 commented Jan 23, 2010

Out of curiosity, is it possible to write unit tests for any/all of this?

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

I presume you meant *with* bigcomp enabled?

Forgive my lack of knowledge, but why would you disable bigcomp?

@mdickinson
Copy link
Member Author

Out of curiosity, is it possible to write unit tests for any/all of this?

There are some tests in Lib/test/test_strtod.py, that I added around two weeks ago and have been updating since; I don't have mechanism for running tests with the altered STRTOD_DIGLIM value, though.

I presume you meant *with* bigcomp enabled?
I did. Thanks!

Forgive my lack of knowledge, but why would you disable bigcomp?

Just as a stress test, really: a failure that occurs with bigcomp disabled might indicate a problem that could also occur with bigcomp enabled. Or someone might want to alter the value of the STRTOD_DIGLIM threshold at some later point based on performance tests; if the code is correct then it ought to be safe to do so.

@mdickinson
Copy link
Member Author

I forgot to mention: the other reason one might want to disable the bigcomp stuff is that it seems less reliable than the rest of the code: of the 11-12 independent bugs that I found in dtoa.c recently, around 9 of them were related to the bigcomp code.

@mdickinson
Copy link
Member Author

First bug fixed (in the trunk) in r77713.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants