GNOME Bugzilla – Bug 652521
get_length fails in Clutter.Path when length is greater than 46340
Last modified: 2012-04-27 11:40:49 UTC
I've found a small bug when creating a ClutterBehaviour object (with python bindings and Gnome Introspection) Python bindings: >>> import clutter >>> knots = "M 0 0 L 46340 0" >>> path = clutter.Path(knots) >>> path.get_length() 46340L >>> knots = "M 0 0 L 46341 0" >>> path = clutter.Path(knots) >>> path.get_length() 2147483648L Gnome Introspection: >>> from gi.repository import Clutter >>> knots = "M 0 0 L 46340 0" >>> path = Clutter.Path() >>> path.add_string(knots) True >>> path.get_length() 46340L >>> knots = "M 0 0 L 46341 0" >>> path.add_string(knots) True >>> path.get_length() 2147529988L
Created attachment 212611 [details] C reproducer This is not a bug in pygobject or the GI bindings. If you use the C API directly, you get exactly the same problem: $ gcc -o /tmp/clutter clutter.c `pkg-config --cflags --libs clutter-1.0` $ /tmp/clutter len: -2147483648
get_length() returns an unsigned integer, not a signed long. the distance between two points (x_a, y_a) and (x_b, y_b) is: sqrt ((x_b - x_a) * (x_b - x_a) + (y_b - y_a) * (y_b - y_a)) which, for (0, 0) - (46341, 0) resolves as sqrt (46341 * 46341) which overflows the integer range. then, the whole issue gets hidden by the fact that get_distance() returns an unsigned integer (ugh) value. the whole ClutterPath is a mess - but the only way to actually fix it is to break API and move to floating point everywhere.
Created attachment 212620 [details] [review] path: Avoid integer overflow in get_distance() This should fix the overflow; I added a test case to the conformance test suite as well.
Attachment 212620 [details] pushed to master as commit 0fca11ec