[geos-commits] [SCM] GEOS branch 3.7 updated. 6f5aa31f7401dec617cb6b51bf821fe11ca2f3e3

git at osgeo.org git at osgeo.org
Mon Apr 20 11:18:25 PDT 2020


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, 3.7 has been updated
       via  6f5aa31f7401dec617cb6b51bf821fe11ca2f3e3 (commit)
      from  45b28eb41288e31c7d489ee765ae633034efee94 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6f5aa31f7401dec617cb6b51bf821fe11ca2f3e3
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Mon Apr 20 10:17:42 2020 -0700

    WKT output of MULTIPOINT with empty member crashes #1027

diff --git a/NEWS b/NEWS
index de74976..f91d32d 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@ Changes in 3.7.3dev
   - Overlay performance improvement (#986, Paul Ramsey)
   - Avoid changing MultiLineString component order in GEOSReverse
     (#1013, Dan Baston)
+  - WKT writing of MULTIPOINT with EMPTY component crash
+    (#1027, Paul Ramsey)
 
 
 Changes in 3.7.2
diff --git a/src/io/WKTWriter.cpp b/src/io/WKTWriter.cpp
index fae7135..f30199f 100644
--- a/src/io/WKTWriter.cpp
+++ b/src/io/WKTWriter.cpp
@@ -76,7 +76,7 @@ string
 WKTWriter::toLineString(const CoordinateSequence& seq)
 {
 	stringstream buf(ios_base::in|ios_base::out);
-    buf << "LINESTRING ";
+	buf << "LINESTRING ";
 	unsigned int npts = static_cast<unsigned int>(seq.getSize());
 	if ( npts == 0 )
 	{
@@ -112,7 +112,7 @@ WKTWriter::toLineString(const Coordinate& p0, const Coordinate& p1)
 #if PRINT_Z
 	ret << " " << p1.z;
 #endif
-    ret << ")";
+	ret << ")";
 
 	return ret.str();
 }
@@ -122,7 +122,7 @@ string
 WKTWriter::toPoint(const Coordinate& p0)
 {
 	stringstream ret(ios_base::in|ios_base::out);
-    ret << "POINT (";
+	ret << "POINT (";
 #if PRINT_Z
 	ret << p0.x << " " << p0.y  << " " << p0.z << " )";
 #else
@@ -169,9 +169,9 @@ void WKTWriter::writeFormatted(const Geometry *geometry, Writer *writer) {
 
 void
 WKTWriter::writeFormatted(const Geometry *geometry, bool isFormatted,
-                          Writer *writer)
+						  Writer *writer)
 {
-        CLocalizer clocale;
+		CLocalizer clocale;
 	this->isFormatted=isFormatted;
   decimalPlaces = roundingPrecision == -1 ? geometry->getPrecisionModel()->getMaximumSignificantDigits() : roundingPrecision;
 	appendGeometryTaggedText(geometry, 0, writer);
@@ -182,51 +182,51 @@ WKTWriter::appendGeometryTaggedText(const Geometry *geometry, int level,
 		Writer *writer)
 {
   outputDimension = std::min( defaultOutputDimension,
-                         geometry->getCoordinateDimension() );
+						 geometry->getCoordinateDimension() );
 
   indent(level, writer);
   if ( const Point* point = dynamic_cast<const Point*>(geometry) )
   {
-    appendPointTaggedText(point->getCoordinate(),level,writer);
+	appendPointTaggedText(point->getCoordinate(),level,writer);
   }
   else if ( const LinearRing* lr =
-    dynamic_cast<const LinearRing*>(geometry) )
+	dynamic_cast<const LinearRing*>(geometry) )
   {
-    appendLinearRingTaggedText(lr, level, writer);
+	appendLinearRingTaggedText(lr, level, writer);
   }
   else if ( const LineString* ls =
-    dynamic_cast<const LineString*>(geometry) )
+	dynamic_cast<const LineString*>(geometry) )
   {
-    appendLineStringTaggedText(ls, level, writer);
+	appendLineStringTaggedText(ls, level, writer);
   }
   else if ( const Polygon* x =
-    dynamic_cast<const Polygon*>(geometry) )
+	dynamic_cast<const Polygon*>(geometry) )
   {
-    appendPolygonTaggedText(x, level, writer);
+	appendPolygonTaggedText(x, level, writer);
   }
   else if ( const MultiPoint* x =
-    dynamic_cast<const MultiPoint*>(geometry) )
+	dynamic_cast<const MultiPoint*>(geometry) )
   {
-    appendMultiPointTaggedText(x, level, writer);
+	appendMultiPointTaggedText(x, level, writer);
   }
   else if ( const MultiLineString* x =
-    dynamic_cast<const MultiLineString*>(geometry) )
+	dynamic_cast<const MultiLineString*>(geometry) )
   {
-    appendMultiLineStringTaggedText(x, level, writer);
+	appendMultiLineStringTaggedText(x, level, writer);
   }
   else if ( const MultiPolygon* x =
-    dynamic_cast<const MultiPolygon*>(geometry) )
+	dynamic_cast<const MultiPolygon*>(geometry) )
   {
-    appendMultiPolygonTaggedText(x, level, writer);
+	appendMultiPolygonTaggedText(x, level, writer);
   }
   else if ( const GeometryCollection* x =
-    dynamic_cast<const GeometryCollection*>(geometry) )
+	dynamic_cast<const GeometryCollection*>(geometry) )
   {
-    appendGeometryCollectionTaggedText(x, level, writer);
+	appendGeometryCollectionTaggedText(x, level, writer);
   }
   else
   {
-    assert(0); // Unsupported Geometry implementation
+	assert(0); // Unsupported Geometry implementation
   }
 }
 
@@ -401,9 +401,13 @@ WKTWriter::appendMultiPointText(const MultiPoint *multiPoint,
 			{
 				writer->write(", ");
 			}
-			appendCoordinate(
-				dynamic_cast<const Point*>(multiPoint->getGeometryN(i))->getCoordinate(),
-				writer);
+			const Coordinate* coord = multiPoint->getGeometryN(i)->getCoordinate();
+			if(coord == nullptr) {
+				writer->write("EMPTY");
+			}
+			else {
+				appendCoordinate(coord, writer);
+			}
 		}
 		writer->write(")");
 	}
diff --git a/tests/unit/io/WKTWriterTest.cpp b/tests/unit/io/WKTWriterTest.cpp
index 94be2b0..ff50a8c 100644
--- a/tests/unit/io/WKTWriterTest.cpp
+++ b/tests/unit/io/WKTWriterTest.cpp
@@ -9,6 +9,8 @@
 #include <geos/geom/PrecisionModel.h>
 #include <geos/geom/GeometryFactory.h>
 #include <geos/geom/Geometry.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/Point.h>
 // std
 #include <sstream>
 #include <string>
@@ -35,11 +37,11 @@ namespace tut
 		WKTWriter wktwriter;
 
 		test_wktwriter_data()
-                :
-                pm(1000.0),
-                gf(GeometryFactory::create(&pm)),
-                wktreader(gf.get())
-            {}
+				:
+				pm(1000.0),
+				gf(GeometryFactory::create(&pm)),
+				wktreader(gf.get())
+			{}
 
 	};
 
@@ -58,93 +60,120 @@ namespace tut
 	template<>
 	void object::test<1>()
 	{
-        GeomPtr geom ( wktreader.read("POINT(-117 33)") );
-        std::string  result;
+		GeomPtr geom ( wktreader.read("POINT(-117 33)") );
+		std::string  result;
 
-        wktwriter.setTrim(false);
-        result = wktwriter.write( geom.get() );
+		wktwriter.setTrim(false);
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result , "POINT (-117.000 33.000)" );
+		ensure_equals( result , "POINT (-117.000 33.000)" );
 
-        wktwriter.setTrim(true);
-        result = wktwriter.write( geom.get() );
+		wktwriter.setTrim(true);
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result , "POINT (-117 33)" );
-    }
+		ensure_equals( result , "POINT (-117 33)" );
+	}
 
 	// 2 - Test the output precision capability
 	template<>
 	template<>
 	void object::test<2>()
 	{
-        GeomPtr geom ( wktreader.read("POINT(-117.1234567 33.1234567)") );
-        std::string  result;
+		GeomPtr geom ( wktreader.read("POINT(-117.1234567 33.1234567)") );
+		std::string  result;
 
-        wktwriter.setTrim(false);
-        result = wktwriter.write( geom.get() );
+		wktwriter.setTrim(false);
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result , "POINT (-117.123 33.123)" );
+		ensure_equals( result , "POINT (-117.123 33.123)" );
 
-        wktwriter.setRoundingPrecision(2);
-        result = wktwriter.write( geom.get() );
+		wktwriter.setRoundingPrecision(2);
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result , "POINT (-117.12 33.12)" );
+		ensure_equals( result , "POINT (-117.12 33.12)" );
 
-    }
+	}
 
 	// 3 - Test 3D generation from a 3D geometry.
 	template<>
 	template<>
 	void object::test<3>()
 	{
-        GeomPtr geom ( wktreader.read("POINT Z (-117 33 120)") );
-        std::string  result;
+		GeomPtr geom ( wktreader.read("POINT Z (-117 33 120)") );
+		std::string  result;
 
-        wktwriter.setOutputDimension(3);
-        wktwriter.setTrim( true );
-        wktwriter.setOld3D( false );
+		wktwriter.setOutputDimension(3);
+		wktwriter.setTrim( true );
+		wktwriter.setOld3D( false );
 
-        result = wktwriter.write( geom.get() );
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result, std::string("POINT Z (-117 33 120)") );
+		ensure_equals( result, std::string("POINT Z (-117 33 120)") );
 
-        wktwriter.setOld3D( true );
-        result = wktwriter.write( geom.get() );
+		wktwriter.setOld3D( true );
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result, std::string("POINT (-117 33 120)") );
+		ensure_equals( result, std::string("POINT (-117 33 120)") );
 
-    }
+	}
 
 	// 4 - Test 2D generation from a 3D geometry.
 	template<>
 	template<>
 	void object::test<4>()
 	{
-        GeomPtr geom ( wktreader.read("POINT(-117 33 120)") );
-        std::string  result;
+		GeomPtr geom ( wktreader.read("POINT(-117 33 120)") );
+		std::string  result;
 
-        wktwriter.setOutputDimension(2);
-        wktwriter.setTrim( true );
-        wktwriter.setOld3D( false );
+		wktwriter.setOutputDimension(2);
+		wktwriter.setTrim( true );
+		wktwriter.setOld3D( false );
 
-        result = wktwriter.write( geom.get() );
+		result = wktwriter.write( geom.get() );
 
-        ensure_equals( result, std::string("POINT (-117 33)") );
-    }
+		ensure_equals( result, std::string("POINT (-117 33)") );
+	}
 
   // 5 - Test negative number of digits in precision model
   template<>
   template<>
   void object::test<5>()
   {
-    PrecisionModel pm3(0.001);
-    GeometryFactory::Ptr gf3(GeometryFactory::create(&pm3));
-    WKTReader wktreader3(gf3.get());
-    GeomPtr geom ( wktreader3.read("POINT(123456 654321)") );
+	PrecisionModel pm3(0.001);
+	GeometryFactory::Ptr gf3(GeometryFactory::create(&pm3));
+	WKTReader wktreader3(gf3.get());
+	GeomPtr geom ( wktreader3.read("POINT(123456 654321)") );
 
-    std::string  result = wktwriter.write( geom.get() );
-    ensure_equals( result, std::string("POINT (123000 654000)") );
+	std::string  result = wktwriter.write( geom.get() );
+	ensure_equals( result, std::string("POINT (123000 654000)") );
   }
 
+
+// 6 - Test writing out a multipoint with an empty member
+template<>
+template<>
+void object::test<6>
+()
+{
+	PrecisionModel pm_e(1000);
+	geos::geom::GeometryFactory::Ptr gf_e(GeometryFactory::create(&pm_e, 0));
+
+	std::unique_ptr<geos::geom::Point> empty_pt(gf_e->createPoint());
+	ensure(empty_pt != nullptr);
+
+	geos::geom::Coordinate coord(1, 2);
+	std::unique_ptr<geos::geom::Geometry> point(gf_e->createPoint(coord));
+	ensure(point != nullptr);
+
+	const std::vector<geos::geom::Geometry*> geoms{empty_pt.release(), point.release()};
+
+	std::unique_ptr<geos::geom::Geometry> col(gf_e->createMultiPoint(geoms));
+
+	wktwriter.setRoundingPrecision(2);
+	wktwriter.setTrim(true);
+	std::string result = wktwriter.write(col.get());
+	ensure_equals(result, std::string("MULTIPOINT (EMPTY, 1 2)"));
+}
+
 } // namespace tut
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                            |   2 +
 src/io/WKTWriter.cpp            |  54 +++++++++--------
 tests/unit/io/WKTWriterTest.cpp | 125 +++++++++++++++++++++++++---------------
 3 files changed, 108 insertions(+), 73 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list