path: Avoid integer overflow in get_distance()

The get_distance() API uses machine integers to compute the distance;
this means that on 32bit we can overflow the integer size. This gets
hidden by the fact that get_distance() returns an unsigned integer as
well.

In reality, ClutterPath is an unmitigated mess, and the only way to
actually fix it is to break API.

https://bugzilla.gnome.org/show_bug.cgi?id=652521
This commit is contained in:
Emmanuele Bassi
2012-04-23 17:42:40 +01:00
parent 9428aaa3cb
commit 0fca11ec2f
2 changed files with 53 additions and 20 deletions

View File

@ -632,14 +632,14 @@ clutter_path_parse_description (const gchar *p,
node = clutter_path_node_full_new ();
nodes = g_slist_prepend (nodes, node);
node->k.type = (*p == 'M' ? CLUTTER_PATH_MOVE_TO
: *p == 'm' ? CLUTTER_PATH_REL_MOVE_TO
: *p == 'L' ? CLUTTER_PATH_LINE_TO
: CLUTTER_PATH_REL_LINE_TO);
node->k.type = (*p == 'M' ? CLUTTER_PATH_MOVE_TO :
*p == 'm' ? CLUTTER_PATH_REL_MOVE_TO :
*p == 'L' ? CLUTTER_PATH_LINE_TO :
CLUTTER_PATH_REL_LINE_TO);
p++;
if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[0].y))
if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[0].y))
goto fail;
break;
@ -648,16 +648,16 @@ clutter_path_parse_description (const gchar *p,
node = clutter_path_node_full_new ();
nodes = g_slist_prepend (nodes, node);
node->k.type = (*p == 'C' ? CLUTTER_PATH_CURVE_TO
: CLUTTER_PATH_REL_CURVE_TO);
node->k.type = (*p == 'C' ? CLUTTER_PATH_CURVE_TO :
CLUTTER_PATH_REL_CURVE_TO);
p++;
if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[0].y)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[1].x)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[1].y)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[2].x)
|| !clutter_path_parse_number (&p, TRUE, &node->k.points[2].y))
if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[0].y) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[1].x) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[1].y) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[2].x) ||
!clutter_path_parse_number (&p, TRUE, &node->k.points[2].y))
goto fail;
break;
@ -1244,11 +1244,12 @@ clutter_path_get_description (ClutterPath *path)
return g_string_free (str, FALSE);
}
static gint
static guint
clutter_path_node_distance (const ClutterKnot *start,
const ClutterKnot *end)
{
gint t;
gint64 x_d, y_d;
float t;
g_return_val_if_fail (start != NULL, 0);
g_return_val_if_fail (end != NULL, 0);
@ -1256,10 +1257,12 @@ clutter_path_node_distance (const ClutterKnot *start,
if (clutter_knot_equal (start, end))
return 0;
t = (end->x - start->x) * (end->x - start->x) +
(end->y - start->y) * (end->y - start->y);
x_d = end->x - start->x;
y_d = end->y - start->y;
return sqrtf (t);
t = floorf (sqrtf ((x_d * x_d) + (y_d * y_d)));
return (guint) t;
}
static void