Commit 90c4df7a authored by Alexey Botchkov's avatar Alexey Botchkov

Fix for bug #804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION.

        Second smaller hole in the polygon got link to the bigger one as it's the
        outer ring. Fixed by specifying the outer ring explicitly.


per-file comments:
  mysql-test/r/gis-precise.result
Fix for bug #804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION.
        test result updated.

  mysql-test/t/gis-precise.test
Fix for bug #804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION.
        test case added.

  sql/gcalc_tools.cc
Fix for bug #804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION.
        specify the outer ring explicitly in the get_polygon_result parameter.

  sql/gcalc_tools.h
Fix for bug #804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION.
        add the outer ring as a parameter to the get_polygon_result.
parent e7c9f52f
...@@ -288,3 +288,16 @@ MultiLineStringFromText('MULTILINESTRING((7 7, 1 7, 8 5, 7 8, 7 7), ...@@ -288,3 +288,16 @@ MultiLineStringFromText('MULTILINESTRING((7 7, 1 7, 8 5, 7 8, 7 7),
(6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'), (6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'),
Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)')))) Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)'))))
GEOMETRYCOLLECTION(LINESTRING(9 9,8 4,9 0,9 9,7 7),POLYGON((0 0,0 9,7 9,7 0,0 0)),LINESTRING(7 5.28571428571429,8 5,7 8)) GEOMETRYCOLLECTION(LINESTRING(9 9,8 4,9 0,9 9,7 7),POLYGON((0 0,0 9,7 9,7 0,0 0)),LINESTRING(7 5.28571428571429,8 5,7 8))
SELECT AsText(ST_UNION(
MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
((2 2, 1 2, 3 3, 2 2, 2 2)),
((0 0, 7 5, 9 6, 0 0)),
((7 7, 5 7, 1 5, 7 1, 7 7)))'),
MultiPolygonFromText('MULTIPOLYGON(((2 2, 2 2, 1 5, 2 7, 2 2)),
((0 5, 3 5, 3 0, 0 0, 0 5), (1 1, 2 1, 2 4, 1 4, 1 1)))')));
AsText(ST_UNION(
MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
((2 2, 1 2, 3 3, 2 2, 2 2)),
((0 0, 7 5, 9 6, 0 0)),
POLYGON((0 0,0 5,1 5,2 7,2 5.5,5 7,5.5 7,7 9,9 9,7 7,7 5,9 6,7 4.66666666666667,7 1,4.25 2.83333333333333,3 2,3 0,0 0),(1 1,1 4,1.33333333333333 4,1.85714285714286 2.42857142857143,1 2,1.75 2,1 1,2 2,2 1.42857142857143,1.4 1,1 1),(1.5 1,2 1.33333333333333,2 1,1.5 1),(3 2.14285714285714,3 3,3.4 3.4,4.10344827586207 2.93103448275862,3 2.14285714285714))
...@@ -177,3 +177,13 @@ SELECT AsText(ST_SYMDIFFERENCE( ...@@ -177,3 +177,13 @@ SELECT AsText(ST_SYMDIFFERENCE(
(6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'), (6 3, 3 4, 1 1, 9 9, 9 0, 8 4, 9 9))'),
Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)')))); Envelope(GeometryFromText('MULTIPOINT(7 9, 0 0, 3 7, 1 6, 0 0)'))));
#bug 804266 Memory corruption/valgrind warning/crash in move_hole() with ST_UNION
SELECT AsText(ST_UNION(
MultiPolygonFromText('MULTIPOLYGON(((9 9, 7 9, 1 1, 9 9)),
((2 2, 1 2, 3 3, 2 2, 2 2)),
((0 0, 7 5, 9 6, 0 0)),
((7 7, 5 7, 1 5, 7 1, 7 7)))'),
MultiPolygonFromText('MULTIPOLYGON(((2 2, 2 2, 1 5, 2 7, 2 2)),
((0 5, 3 5, 3 0, 0 0, 0 5), (1 1, 2 1, 2 4, 1 4, 1 1)))')));
...@@ -1023,11 +1023,11 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res, ...@@ -1023,11 +1023,11 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res,
int Gcalc_operation_reducer::get_result_thread(res_point *cur, int Gcalc_operation_reducer::get_result_thread(res_point *cur,
Gcalc_result_receiver *storage, Gcalc_result_receiver *storage,
int move_upward) int move_upward,
res_point *first_poly_node)
{ {
res_point *next; res_point *next;
bool glue_step= false; bool glue_step= false;
res_point *first_poly_node= cur;
double x, y; double x, y;
while (cur) while (cur)
{ {
...@@ -1068,12 +1068,13 @@ int Gcalc_operation_reducer::get_result_thread(res_point *cur, ...@@ -1068,12 +1068,13 @@ int Gcalc_operation_reducer::get_result_thread(res_point *cur,
int Gcalc_operation_reducer::get_polygon_result(res_point *cur, int Gcalc_operation_reducer::get_polygon_result(res_point *cur,
Gcalc_result_receiver *storage) Gcalc_result_receiver *storage,
res_point *first_poly_node)
{ {
res_point *glue= cur->glue; res_point *glue= cur->glue;
glue->up->down= NULL; glue->up->down= NULL;
free_result(glue); free_result(glue);
return get_result_thread(cur, storage, 1) || return get_result_thread(cur, storage, 1, first_poly_node) ||
storage->complete_shape(); storage->complete_shape();
} }
...@@ -1100,7 +1101,7 @@ int Gcalc_operation_reducer::get_line_result(res_point *cur, ...@@ -1100,7 +1101,7 @@ int Gcalc_operation_reducer::get_line_result(res_point *cur,
} }
} }
return get_result_thread(cur, storage, move_upward) || return get_result_thread(cur, storage, move_upward, 0) ||
storage->complete_shape(); storage->complete_shape();
} }
...@@ -1129,7 +1130,8 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage) ...@@ -1129,7 +1130,8 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
DBUG_ASSERT(insert_position); DBUG_ASSERT(insert_position);
hole_position= storage->position(); hole_position= storage->position();
storage->start_shape(Gcalc_function::shape_hole); storage->start_shape(Gcalc_function::shape_hole);
if (get_polygon_result(m_result, storage) || if (get_polygon_result(m_result, storage,
m_result->outer_poly->first_poly_node) ||
storage->move_hole(insert_position, hole_position, storage->move_hole(insert_position, hole_position,
&position_shift)) &position_shift))
return 1; return 1;
...@@ -1146,7 +1148,7 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage) ...@@ -1146,7 +1148,7 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
p->next= polygons; p->next= polygons;
polygons= p; polygons= p;
storage->start_shape(Gcalc_function::shape_polygon); storage->start_shape(Gcalc_function::shape_polygon);
if (get_polygon_result(m_result, storage)) if (get_polygon_result(m_result, storage, m_result))
return 1; return 1;
*poly_position= storage->position(); *poly_position= storage->position();
} }
......
...@@ -304,8 +304,9 @@ private: ...@@ -304,8 +304,9 @@ private:
int get_single_result(res_point *res, Gcalc_result_receiver *storage); int get_single_result(res_point *res, Gcalc_result_receiver *storage);
int get_result_thread(res_point *cur, Gcalc_result_receiver *storage, int get_result_thread(res_point *cur, Gcalc_result_receiver *storage,
int move_upward); int move_upward, res_point *first_poly_node);
int get_polygon_result(res_point *cur, Gcalc_result_receiver *storage); int get_polygon_result(res_point *cur, Gcalc_result_receiver *storage,
res_point *first_poly_node);
int get_line_result(res_point *cur, Gcalc_result_receiver *storage); int get_line_result(res_point *cur, Gcalc_result_receiver *storage);
void free_result(res_point *res); void free_result(res_point *res);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment