diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2011-07-13 14:57:27 +0500 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2011-07-13 14:57:27 +0500 |
commit | 90c4df7a4af542707d884e53990827672bb8feea (patch) | |
tree | fcf24b0b49e8dc8e69bf17a6c3937347bf40cb9d | |
parent | e7c9f52fd960440614c30c3f852bf74f1febe6b3 (diff) | |
download | mariadb-git-90c4df7a4af542707d884e53990827672bb8feea.tar.gz |
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.
-rw-r--r-- | mysql-test/r/gis-precise.result | 13 | ||||
-rw-r--r-- | mysql-test/t/gis-precise.test | 10 | ||||
-rw-r--r-- | sql/gcalc_tools.cc | 16 | ||||
-rw-r--r-- | sql/gcalc_tools.h | 5 |
4 files changed, 35 insertions, 9 deletions
diff --git a/mysql-test/r/gis-precise.result b/mysql-test/r/gis-precise.result index d943a534137..dd27470ab5d 100644 --- a/mysql-test/r/gis-precise.result +++ b/mysql-test/r/gis-precise.result @@ -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))'), 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)) +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)) diff --git a/mysql-test/t/gis-precise.test b/mysql-test/t/gis-precise.test index bf36e6e9628..bb223b685e4 100644 --- a/mysql-test/t/gis-precise.test +++ b/mysql-test/t/gis-precise.test @@ -177,3 +177,13 @@ SELECT AsText(ST_SYMDIFFERENCE( (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)')))); +#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)))'))); + diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc index d89385fa78c..25e71d7bfca 100644 --- a/sql/gcalc_tools.cc +++ b/sql/gcalc_tools.cc @@ -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, Gcalc_result_receiver *storage, - int move_upward) + int move_upward, + res_point *first_poly_node) { res_point *next; bool glue_step= false; - res_point *first_poly_node= cur; double x, y; while (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, - Gcalc_result_receiver *storage) + Gcalc_result_receiver *storage, + res_point *first_poly_node) { res_point *glue= cur->glue; glue->up->down= NULL; free_result(glue); - return get_result_thread(cur, storage, 1) || + return get_result_thread(cur, storage, 1, first_poly_node) || storage->complete_shape(); } @@ -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(); } @@ -1129,7 +1130,8 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage) DBUG_ASSERT(insert_position); hole_position= storage->position(); 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, &position_shift)) return 1; @@ -1146,7 +1148,7 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage) p->next= polygons; polygons= p; 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; *poly_position= storage->position(); } diff --git a/sql/gcalc_tools.h b/sql/gcalc_tools.h index 32835d68666..5e55d1bdae3 100644 --- a/sql/gcalc_tools.h +++ b/sql/gcalc_tools.h @@ -304,8 +304,9 @@ private: int get_single_result(res_point *res, Gcalc_result_receiver *storage); int get_result_thread(res_point *cur, Gcalc_result_receiver *storage, - int move_upward); - int get_polygon_result(res_point *cur, Gcalc_result_receiver *storage); + int move_upward, res_point *first_poly_node); + 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); void free_result(res_point *res); |