GNOME Bugzilla – Bug 498240
Floating-point number parsing overflows and gets corrupted
Last modified: 2020-08-11 15:46:23 UTC
Please describe the problem: Floating point numbers that have more than 10 digits past the "." (decimal point), get corrupted due to overflow. If you run the sec-example-2 program on this CSS file path { stroke-width: 0.9; stroke-width: 0.99; stroke-width: 0.999; stroke-width: 0.9999; stroke-width: 0.99999; stroke-wdith: 0.999999; stroke-width: 0.9999999; stroke-width: 0.99999999; stroke-width: 0.999999999; stroke-width: 0.9999999999; stroke-width: 0.99999999999; stroke-width: 0.999999999999; } you get ./sac-example-2 foo1.css path { ?@ : 0.900 ?@ : 0.990 ?@ : 0.999 ?@ : 1.000 ?@ : 1.000 ?@ : 1.000 ?@ : 1.000 ?@ : 1.000 ?@ : 1.000 ?@ : 0.141 <-----------OOOPS @ 10 digits ?@ : 0.012 ?@ : -0.001 } **Number of properties in this ruleset: 12 It's not a rounding problem. If you change the numbers to 0.111111111111 a similar result occurs. This can be triggered by using by programatically generating SVG files with python since the "str(double)" can produce 10+ digits. >>> d=0.12345678912 >>> print str(d) 0.12345678912 Steps to reproduce: - Actual results: - Expected results: Does this happen every time? yes Other information: ok, so there are a few ways to fix. The problem is in src/cr-tknzr.c limit overflow: Around line 1552, change } else { decimal_places++; dec_part = dec_part * 10 + (cur_char - '0'); } to } else if (decimal_places < 10) { decimal_places++; dec_part = dec_part * 10 + (cur_char - '0'); } Not very elegant but does the job and it's better than the number being corrupted. The other way is to change 'dec_part' from a guint32 to a gdouble, and to change (around line 1293) cr_utils_n_to_0_dot_n (glong a_n, glong decimal_places) to cr_utils_n_to_0_dot_n (gdouble a_n, glong decimal_places) (also notice the original code is passing a guint32 to a glong, which contains a signed vs. unsigned problem). I can provide a formal patch if you need.
whoops. my "fix" is wrong... should be: } else if (decimal_places < 9) { /* 9 digits max */ :-) --nickg
*** Bug 482648 has been marked as a duplicate of this bug. ***
libcroco is not under development anymore. Its codebase has been archived. Closing this report as WONTFIX as part of Bugzilla Housekeeping to reflect reality. Please feel free to reopen this ticket (or rather transfer the project to GNOME Gitlab, as GNOME Bugzilla is being shut down) if anyone takes the responsibility for active development again.