]> granicus.if.org Git - postgis/commitdiff
Crash in ST_Distance (#1951)
authorPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 15 Aug 2012 18:55:56 +0000 (18:55 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 15 Aug 2012 18:55:56 +0000 (18:55 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@10183 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
liblwgeom/cunit/cu_tree.c
liblwgeom/lwgeodetic_tree.c

diff --git a/NEWS b/NEWS
index 6c8cf83b1f67eb08d792dbc9b5113f3f2e83d76f..74a70cd04cc8a9b5c5e5ce3d184106aed7cc007c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,7 @@ PostGIS 2.1.0
            when count is zero
   - #1932, fix raster2pgsql of syntax for index tablespaces
   - #1939, remove custom data types: summarystats, histogram, quantile, valuecount
+  - #1951, remove crash on zero-length linestrings
 
 PostGIS 2.0.1
 2012/06/22
index 04c232feb7d381519a6ac0454e3a23b2f16f8949..b27a82a28a2b7c17252e65bd6e2dd5915e4279c8 100644 (file)
@@ -183,6 +183,19 @@ static void test_tree_circ_distance(void)
        
        spheroid_init(&s, 1.0, 1.0);
 
+       /* Ticket #1951 */
+       line = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(0 0, 0 0)", LW_PARSER_CHECK_NONE));
+       point = lwgeom_as_lwpoint(lwgeom_from_wkt("POINT(0.1 0.1)", LW_PARSER_CHECK_NONE));
+       cline = circ_tree_new(line->points);
+       cpoint = circ_tree_new(point->point);
+       distance_tree = circ_tree_distance_tree(cpoint, cline, &s, threshold);
+       distance_geom = lwgeom_distance_spheroid((LWGEOM*)line, (LWGEOM*)point, &s, threshold);
+       circ_tree_free(cline);
+       circ_tree_free(cpoint);
+       lwline_free(line);
+       lwpoint_free(point);
+       CU_ASSERT_DOUBLE_EQUAL(distance_geom, distance_geom, 0.0001);
+
        line = lwgeom_as_lwline(lwgeom_from_wkt("LINESTRING(-1 -1,0 -1,1 -1,1 0,1 1,0 0,-1 1,-1 0,-1 -1)", LW_PARSER_CHECK_NONE));
        point = lwgeom_as_lwpoint(lwgeom_from_wkt("POINT(-2 0)", LW_PARSER_CHECK_NONE));
        cline = circ_tree_new(line->points);
index 5231cd700bc9cf5a7351586add965c2489f85f13..8d892ceabb37d2dcf31b525e9098eb342c4fe4f6 100644 (file)
@@ -84,6 +84,22 @@ circ_node_leaf_new(const POINTARRAY* pa, int i)
        return node;
 }
 
+/**
+* Return a point node (zero radius, referencing one point)
+*/
+static CIRC_NODE* 
+circ_node_leaf_point_new(const POINTARRAY* pa)
+{
+       CIRC_NODE* tree = lwalloc(sizeof(CIRC_NODE));
+       tree->p1 = tree->p2 = (POINT2D*)getPoint_internal(pa, 0);
+       geographic_point_init(tree->p1->x, tree->p1->y, &(tree->center));
+       tree->radius = 0.0;
+       tree->nodes = NULL;
+       tree->num_nodes = 0;
+       tree->edge_num = 0;
+       return tree;
+}
+
 /**
 * Comparing on geohash ensures that nearby nodes will be close 
 * to each other in the list.
@@ -287,16 +303,7 @@ circ_tree_new(const POINTARRAY* pa)
                
        /* Special handling for a single point */
        if ( pa->npoints == 1 )
-       {
-               tree = lwalloc(sizeof(CIRC_NODE));
-               tree->p1 = tree->p2 = (POINT2D*)getPoint_internal(pa, 0);
-               geographic_point_init(tree->p1->x, tree->p1->y, &(tree->center));
-               tree->radius = 0.0;
-               tree->nodes = NULL;
-               tree->num_nodes = 0;
-               tree->edge_num = 0;
-               return tree;
-       }       
+               return circ_node_leaf_point_new(pa);
                
        /* First create a flat list of nodes, one per edge. */
        num_edges = pa->npoints - 1;
@@ -308,6 +315,10 @@ circ_tree_new(const POINTARRAY* pa)
                if ( node ) /* Not zero length? */
                        nodes[j++] = node;
        }
+       
+       /* Special case: only zero-length edges. Make a point node. */
+       if ( j == 0 )
+               return circ_node_leaf_point_new(pa);
 
        /* Merge the node list pairwise up into a tree */
        tree = circ_nodes_merge(nodes, j);