Fix crash on ST_AsGML('POLYGON EMPTY') (#681)

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
This commit is contained in:
Sandro Santilli 2011-12-14 16:02:44 +00:00
parent ebcbd6dc1a
commit 8b9b187c8e
4 changed files with 162 additions and 124 deletions

View 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};

View 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);
ptr += sprintf(ptr, "<%sPolygon", prefix);
if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
if ( lwpoly_is_empty(poly) ) {
ptr += sprintf(ptr, "/>");
return (ptr-output);
}
else
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, "<%sPolygon>", prefix);
}
if ( ! lwpoly_is_empty(poly) )
{
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,15 +906,22 @@ 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);
else ptr += sprintf(ptr, "<%sposList>", prefix);
@ -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++)
{

View 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);

View 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/>