]> granicus.if.org Git - postgis/commitdiff
Fix crash on ST_AsGML('POLYGON EMPTY') (#681)
authorSandro Santilli <strk@keybit.net>
Wed, 14 Dec 2011 16:02:44 +0000 (16:02 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 14 Dec 2011 16:02:44 +0000 (16:02 +0000)
Also tweak GML of empty types to be smaller and include
regression testing both at the liblwgeom and sql level

git-svn-id: http://svn.osgeo.org/postgis/trunk@8412 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/cu_out_gml.c
liblwgeom/lwout_gml.c
regress/empty.sql
regress/empty_expected

index f0a5f45eba446495c6e2d97c4f12de729b4c7d4c..706e01b1606533005d16162ffccf8a2db256ff56 100644 (file)
@@ -208,7 +208,6 @@ static void do_gml3_extent_test(char * in, char * out, char * srs,
        lwgeom_free(g);
 }
 
-
 static void out_gml_test_precision(void)
 {
        /* GML2 - 0 precision, i.e a round */
@@ -442,19 +441,6 @@ static void out_gml_test_dims(void)
 
 static void out_gml_test_geoms(void)
 {
-       /* GML2 - LINESTRING EMPTY 
-       do_gml2_test(
-           "LINESTRING EMPTY",
-           "<gml:Polygon></gml:Polygon>",
-           NULL, 0);
-               */
-
-       /* GML2 - POLYGON EMPTY */
-       do_gml2_test(
-           "POLYGON EMPTY",
-           "<gml:Polygon></gml:Polygon>",
-           NULL, 0);
-
        /* GML2 - Linestring */
        do_gml2_test(
            "LINESTRING(0 1,2 3,4 5)",
@@ -552,18 +538,6 @@ static void out_gml_test_geoms(void)
            NULL, 0, 0);
 
 
-       /* GML2 - Empty GeometryCollection */
-       do_gml2_test(
-           "GEOMETRYCOLLECTION EMPTY",
-           "<gml:MultiGeometry></gml:MultiGeometry>",
-           NULL, 0);
-
-       /* GML3 - Empty GeometryCollection */
-       do_gml3_test(
-           "GEOMETRYCOLLECTION EMPTY",
-           "<gml:MultiGeometry></gml:MultiGeometry>",
-           NULL, 0, 0);
-
        /* GML2 - Nested GeometryCollection */
        do_gml2_test(
            "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
@@ -751,13 +725,13 @@ static void out_gml_test_geoms_prefix(void)
        /* GML2 - Empty GeometryCollection */
        do_gml2_test_prefix(
            "GEOMETRYCOLLECTION EMPTY",
-           "<custom:MultiGeometry></custom:MultiGeometry>",
+           "<custom:MultiGeometry/>",
            NULL, 0, "custom:");
 
        /* GML3 - Empty GeometryCollection */
        do_gml3_test_prefix(
            "GEOMETRYCOLLECTION EMPTY",
-           "<custom:MultiGeometry></custom:MultiGeometry>",
+           "<custom:MultiGeometry/>",
            NULL, 0, 0, "custom:");
 
        /* GML2 - Nested GeometryCollection */
@@ -885,13 +859,13 @@ static void out_gml_test_geoms_prefix(void)
        /* GML2 - Empty GeometryCollection */
        do_gml2_test_prefix(
            "GEOMETRYCOLLECTION EMPTY",
-           "<MultiGeometry></MultiGeometry>",
+           "<MultiGeometry/>",
            NULL, 0, "");
 
        /* GML3 - Empty GeometryCollection */
        do_gml3_test_prefix(
            "GEOMETRYCOLLECTION EMPTY",
-           "<MultiGeometry></MultiGeometry>",
+           "<MultiGeometry/>",
            NULL, 0, 0, "");
 
        /* GML2 - Nested GeometryCollection */
@@ -1130,6 +1104,51 @@ static void out_gml3_extent(void)
 }
 
 
+static void out_gml_test_empty(void)
+{
+       /* POINT EMPTY, GML2 */
+       do_gml2_test("POINT EMPTY", "<gml:Point/>", NULL, 0);
+
+       /* POINT EMPTY, GML3 */
+       do_gml3_test("POINT EMPTY", "<gml:Point/>", NULL, 0, 0);
+
+       /* LINESTRING EMPTY, GML2 */
+       do_gml2_test("LINESTRING EMPTY", "<gml:LineString/>", NULL, 0);
+
+       /* LINESTRING EMPTY, GML3 */
+       do_gml3_test("LINESTRING EMPTY", "<gml:Curve/>", NULL, 0, 0);
+
+       /* POLYGON EMPTY, GML2 */
+       do_gml2_test("POLYGON EMPTY", "<gml:Polygon/>", NULL, 0);
+
+       /* POLYGON EMPTY, GML3 */
+       do_gml3_test("POLYGON EMPTY", "<gml:Polygon/>", NULL, 0, 0);
+
+       /* MULTIPOINT EMPTY, GML2 */
+       do_gml2_test("MULTIPOINT EMPTY", "<gml:MultiPoint/>", NULL, 0);
+
+       /* MULTIPOINT EMPTY, GML3 */
+       do_gml3_test("MULTIPOINT EMPTY", "<gml:MultiPoint/>", NULL, 0, 0);
+
+       /* MULTILINESTRING EMPTY, GML2 */
+       do_gml2_test("MULTILINESTRING EMPTY", "<gml:MultiLineString/>", NULL, 0);
+
+       /* MULTILINESTRING EMPTY, GML3 */
+       do_gml3_test("MULTILINESTRING EMPTY", "<gml:MultiCurve/>", NULL, 0, 0);
+
+       /* MULTIPOLYGON EMPTY, GML2 */
+       do_gml2_test("MULTIPOLYGON EMPTY", "<gml:MultiPolygon/>", NULL, 0);
+
+       /* MULTIPOLYGON EMPTY, GML3 */
+       do_gml3_test("MULTIPOLYGON EMPTY", "<gml:MultiSurface/>", NULL, 0, 0);
+
+       /* GEOMETRYCOLLECTION EMPTY, GML2 */
+       do_gml2_test("GEOMETRYCOLLECTION EMPTY", "<gml:MultiGeometry/>", NULL, 0);
+
+       /* GEOMETRYCOLLECTION EMPTY, GML3 */
+       do_gml3_test("GEOMETRYCOLLECTION EMPTY", "<gml:MultiGeometry/>", NULL, 0, 0);
+
+}
 
 
 /*
@@ -1146,6 +1165,7 @@ CU_TestInfo out_gml_tests[] =
        PG_TEST(out_gml_test_geoms_nodims),
        PG_TEST(out_gml2_extent),
        PG_TEST(out_gml3_extent),
+       PG_TEST(out_gml_test_empty),
        CU_TEST_INFO_NULL
 };
-CU_SuiteInfo out_gml_suite = {"GML Out Suite",  NULL,  NULL, out_gml_tests};
+CU_SuiteInfo out_gml_suite = {"out_gml",  NULL,  NULL, out_gml_tests};
index 79046a597081718fd89b66c7a6a057671349ce94..4d390f6d3f017499b729dad29185d6aa74a56266 100644 (file)
@@ -255,14 +255,13 @@ asgml2_point_buf(const LWPOINT *point, const char *srs, char *output, int precis
 {
        char *ptr = output;
 
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sPoint srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sPoint>", prefix);
+       ptr += sprintf(ptr, "<%sPoint", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if ( lwpoint_is_empty(point) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
        ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toGML2(point->point, ptr, precision);
        ptr += sprintf(ptr, "</%scoordinates></%sPoint>", prefix, prefix);
@@ -300,14 +299,15 @@ asgml2_line_buf(const LWLINE *line, const char *srs, char *output, int precision
 {
        char *ptr=output;
 
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sLineString srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sLineString>", prefix);
+       ptr += sprintf(ptr, "<%sLineString", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if ( lwline_is_empty(line) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
+
        ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toGML2(line->points, ptr, precision);
        ptr += sprintf(ptr, "</%scoordinates></%sLineString>", prefix, prefix);
@@ -354,26 +354,22 @@ asgml2_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision
        int i;
        char *ptr=output;
 
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sPolygon>", prefix);
+       ptr += sprintf(ptr, "<%sPolygon", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if ( lwpoly_is_empty(poly) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
-       if ( ! lwpoly_is_empty(poly) )
+       ptr += sprintf(ptr, ">");
+       ptr += sprintf(ptr, "<%souterBoundaryIs><%sLinearRing><%scoordinates>",
+                      prefix, prefix, prefix);
+       ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
+       ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
+       for (i=1; i<poly->nrings; i++)
        {
-               ptr += sprintf(ptr, "<%souterBoundaryIs><%sLinearRing><%scoordinates>",
-                              prefix, prefix, prefix);
-               ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
-               ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
-               for (i=1; i<poly->nrings; i++)
-               {
-                       ptr += sprintf(ptr, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
-                       ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
-                       ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
-               }
+               ptr += sprintf(ptr, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
+               ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
+               ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
        }
        ptr += sprintf(ptr, "</%sPolygon>", prefix);
 
@@ -455,14 +451,14 @@ asgml2_multi_buf(const LWCOLLECTION *col, const char *srs, char *output,
        else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
 
        /* Open outmost tag */
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%s%s srsName=\"%s\">", prefix, gmltype, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%s%s>", prefix, gmltype);
+       ptr += sprintf(ptr, "<%s%s", prefix, gmltype);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if (!col->ngeoms) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        for (i=0; i<col->ngeoms; i++)
        {
@@ -569,14 +565,14 @@ asgml2_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in
        ptr = output;
 
        /* Open outmost tag */
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sMultiGeometry srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sMultiGeometry>", prefix);
+       ptr += sprintf(ptr, "<%sMultiGeometry", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if (!col->ngeoms) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        for (i=0; i<col->ngeoms; i++)
        {
@@ -761,14 +757,15 @@ asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precis
        int dimension=2;
 
        if (FLAGS_GET_Z(point->flags)) dimension = 3;
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sPoint srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sPoint>", prefix);
+
+       ptr += sprintf(ptr, "<%sPoint", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if ( lwpoint_is_empty(point) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+
+       ptr += sprintf(ptr, ">");
        if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%spos srsDimension=\"%d\">", prefix, dimension);
        else         ptr += sprintf(ptr, "<%spos>", prefix);
        ptr += pointArray_toGML3(point->point, ptr, precision, opts);
@@ -832,10 +829,13 @@ asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision
        }
 
        if ( srs ) {
-               ptr += sprintf(ptr, " srsName=\"%s\">", srs);
-       } else {
-               ptr += sprintf(ptr, ">");
+               ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       } 
+       if ( lwline_is_empty(line) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        if ( ! shortline ) {
                ptr += sprintf(ptr, "<%ssegments>", prefix);
@@ -906,14 +906,21 @@ asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision
        if (FLAGS_GET_Z(poly->flags)) dimension = 3;
        if (is_patch)
        {
-               if (srs) ptr += sprintf(ptr, "<%sPolygonPatch srsName=\"%s\">", prefix, srs);
-               else     ptr += sprintf(ptr, "<%sPolygonPatch>", prefix);
+               ptr += sprintf(ptr, "<%sPolygonPatch", prefix);
+
        }
        else
        {
-               if (srs) ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs);
-               else     ptr += sprintf(ptr, "<%sPolygon>", prefix);
+               ptr += sprintf(ptr, "<%sPolygon", prefix);
+       }
+
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if ( lwpoly_is_empty(poly) ) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix);
        if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
@@ -1062,14 +1069,14 @@ asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int pre
        else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
 
        /* Open outmost tag */
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%s%s srsName=\"%s\">", prefix, gmltype, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%s%s>", prefix, gmltype);
+       ptr += sprintf(ptr, "<%s%s", prefix, gmltype);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if (!col->ngeoms) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        for (i=0; i<col->ngeoms; i++)
        {
@@ -1292,14 +1299,14 @@ asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in
        ptr = output;
 
        /* Open outmost tag */
-       if ( srs )
-       {
-               ptr += sprintf(ptr, "<%sMultiGeometry srsName=\"%s\">", prefix, srs);
-       }
-       else
-       {
-               ptr += sprintf(ptr, "<%sMultiGeometry>", prefix);
+       ptr += sprintf(ptr, "<%sMultiGeometry", prefix);
+       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+
+       if (!col->ngeoms) {
+               ptr += sprintf(ptr, "/>");
+               return (ptr-output);
        }
+       ptr += sprintf(ptr, ">");
 
        for (i=0; i<col->ngeoms; i++)
        {
index 0fa92fd956ffde672333808aef1c7a30618d183a..6085cb0220ca9d61282a6427fdb653a2ddc0a2e1 100644 (file)
@@ -17,16 +17,15 @@ SELECT 'T3.3', ST_AsGML('POLYGON EMPTY');
 SELECT 'T3.4', ST_AsGML('MULTIPOLYGON EMPTY');
 SELECT 'T3.5', ST_AsGML('MULTILINESTRING EMPTY');
 SELECT 'T3.6', ST_AsGML('GEOMETRYCOLLECTION EMPTY');
--- There's a crash somewhere in here...
---SELECT 'T3.7', ST_AsGML(3,'POINT EMPTY'::geometry);
---SELECT 'T3.8', ST_AsGML(3,'LINESTRING EMPTY'::geometry);
---SELECT 'T3.9', ST_AsGML(3,'POLYGON EMPTY'::geometry);
---SELECT 'T3.10', ST_AsGML(3,'MULTIPOLYGON EMPTY'::geometry);
---SELECT 'T3.11', ST_AsGML(3,'MULTILINESTRING EMPTY'::geometry);
---SELECT 'T3.12', ST_AsGML(3,'GEOMETRYCOLLECTION EMPTY'::geometry);
---SELECT 'T3.13', ST_AsGML(3,'POINT EMPTY'::geometry);
---SELECT 'T3.14', ST_AsGML(3,'LINESTRING EMPTY'::geometry);
---SELECT 'T3.15', ST_AsGML(3,'POLYGON EMPTY'::geometry);
---SELECT 'T3.16', ST_AsGML(3,'MULTIPOLYGON EMPTY'::geometry);
---SELECT 'T3.17', ST_AsGML(3,'MULTILINESTRING EMPTY'::geometry);
---SELECT 'T3.18', ST_AsGML(3,'GEOMETRYCOLLECTION EMPTY'::geometry);
+SELECT 'T3.7', ST_AsGML(3,'POINT EMPTY'::geometry);
+SELECT 'T3.8', ST_AsGML(3,'LINESTRING EMPTY'::geometry);
+SELECT 'T3.9', ST_AsGML(3,'POLYGON EMPTY'::geometry);
+SELECT 'T3.10', ST_AsGML(3,'MULTIPOLYGON EMPTY'::geometry);
+SELECT 'T3.11', ST_AsGML(3,'MULTILINESTRING EMPTY'::geometry);
+SELECT 'T3.12', ST_AsGML(3,'GEOMETRYCOLLECTION EMPTY'::geometry);
+SELECT 'T3.13', ST_AsGML(3,'POINT EMPTY'::geometry);
+SELECT 'T3.14', ST_AsGML(3,'LINESTRING EMPTY'::geometry);
+SELECT 'T3.15', ST_AsGML(3,'POLYGON EMPTY'::geometry);
+SELECT 'T3.16', ST_AsGML(3,'MULTIPOLYGON EMPTY'::geometry);
+SELECT 'T3.17', ST_AsGML(3,'MULTILINESTRING EMPTY'::geometry);
+SELECT 'T3.18', ST_AsGML(3,'GEOMETRYCOLLECTION EMPTY'::geometry);
index ac78a9e743da25aff4aaebbf701346e4dfc804dd..becccfec5a59ccd6037bf26bddd404412a5d96b0 100644 (file)
@@ -5,9 +5,21 @@ T2.1|SRID=4326;POLYGON EMPTY
 T2.2|SRID=4326;POLYGON EMPTY
 T2.3|SRID=4326;POLYGON EMPTY
 T2.4|4326|POLYGON
-T3.1|<gml:Point><gml:coordinates></gml:coordinates></gml:Point>
-T3.2|<gml:LineString><gml:coordinates></gml:coordinates></gml:LineString>
-T3.3|<gml:Polygon></gml:Polygon>
-T3.4|<gml:MultiPolygon></gml:MultiPolygon>
-T3.5|<gml:MultiLineString></gml:MultiLineString>
-T3.6|<gml:MultiGeometry></gml:MultiGeometry>
+T3.1|<gml:Point/>
+T3.2|<gml:LineString/>
+T3.3|<gml:Polygon/>
+T3.4|<gml:MultiPolygon/>
+T3.5|<gml:MultiLineString/>
+T3.6|<gml:MultiGeometry/>
+T3.7|<gml:Point/>
+T3.8|<gml:Curve/>
+T3.9|<gml:Polygon/>
+T3.10|<gml:MultiSurface/>
+T3.11|<gml:MultiCurve/>
+T3.12|<gml:MultiGeometry/>
+T3.13|<gml:Point/>
+T3.14|<gml:Curve/>
+T3.15|<gml:Polygon/>
+T3.16|<gml:MultiSurface/>
+T3.17|<gml:MultiCurve/>
+T3.18|<gml:MultiGeometry/>