[geos-commits] [SCM] GEOS branch main updated. 9d3b5dad1c4d0ecc577ade69cd5cde3f4daa0857

git at osgeo.org git at osgeo.org
Sat Oct 30 14:15:51 PDT 2021


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, main has been updated
       via  9d3b5dad1c4d0ecc577ade69cd5cde3f4daa0857 (commit)
       via  c652f5b55d6e91da754e3e26a57ffbb8370c454d (commit)
      from  7440d0c7b77c72b03ca26bae4865279361f3c723 (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 9d3b5dad1c4d0ecc577ade69cd5cde3f4daa0857
Merge: 7440d0c7b c652f5b55
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Sat Oct 30 14:15:47 2021 -0700

    Merge branch 'rouault-fix_geojson_reader_crash' into main


commit c652f5b55d6e91da754e3e26a57ffbb8370c454d
Author: Even Rouault <even.rouault at spatialys.com>
Date:   Sat Oct 30 22:44:26 2021 +0200

    GeoJSON reader: fix crashes (in debug mode) on invalid GeoJSON
    
    json::operator[] is advertised as having undefined behavior when the
    request member doesn't exist or the json item is not an object.
    json::at() is similar but emits a C++ exception on those situations.
    
    Fixes #1138

diff --git a/src/io/GeoJSONReader.cpp b/src/io/GeoJSONReader.cpp
index 82cb922a5..4733bbe4d 100644
--- a/src/io/GeoJSONReader.cpp
+++ b/src/io/GeoJSONReader.cpp
@@ -49,7 +49,7 @@ std::unique_ptr<geom::Geometry> GeoJSONReader::read(const std::string& geoJsonTe
 {
     try {
         const json& j = json::parse(geoJsonText);
-        const std::string& type = j["type"];
+        const std::string& type = j.at("type");
         if (type == "Feature") {
             return readFeatureForGeometry(j);
         }
@@ -69,7 +69,7 @@ GeoJSONFeatureCollection GeoJSONReader::readFeatures(const std::string& geoJsonT
 {
     try {
         const json& j = json::parse(geoJsonText);
-        const std::string& type = j["type"];
+        const std::string& type = j.at("type");
         if (type == "Feature") {
             const auto& feature = readFeature(j);
             return GeoJSONFeatureCollection { std::vector<GeoJSONFeature>{feature} };
@@ -90,15 +90,15 @@ GeoJSONFeatureCollection GeoJSONReader::readFeatures(const std::string& geoJsonT
 std::unique_ptr<geom::Geometry> GeoJSONReader::readFeatureForGeometry(
     const geos_nlohmann::json& j) const
 {
-    const auto& geometryJson = j["geometry"];
+    const auto& geometryJson = j.at("geometry");
     auto geometry = readGeometry(geometryJson);
     return geometry;
 }
 
 GeoJSONFeature GeoJSONReader::readFeature(const geos_nlohmann::json& j) const
 {
-    const auto& geometryJson = j["geometry"];
-    const auto& properties = j["properties"];
+    const auto& geometryJson = j.at("geometry");
+    const auto& properties = j.at("properties");
     return GeoJSONFeature{readGeometry(geometryJson), readProperties(properties)};
 }
 
@@ -147,7 +147,7 @@ GeoJSONValue GeoJSONReader::readProperty(
 std::unique_ptr<geom::Geometry> GeoJSONReader::readFeatureCollectionForGeometry(
     const geos_nlohmann::json& j) const
 {
-    const auto& featuresJson = j["features"];
+    const auto& featuresJson = j.at("features");
     std::vector<std::unique_ptr<geom::Geometry>> geometries;
     geometries.reserve(featuresJson.size());
     for (const auto& featureJson : featuresJson) {
@@ -160,7 +160,7 @@ std::unique_ptr<geom::Geometry> GeoJSONReader::readFeatureCollectionForGeometry(
 GeoJSONFeatureCollection GeoJSONReader::readFeatureCollection(
     const geos_nlohmann::json& j) const
 {
-    const auto& featuresJson = j["features"];
+    const auto& featuresJson = j.at("features");
     std::vector<GeoJSONFeature> features;
     features.reserve(featuresJson.size());
     for (const auto& featureJson : featuresJson) {
@@ -173,7 +173,7 @@ GeoJSONFeatureCollection GeoJSONReader::readFeatureCollection(
 std::unique_ptr<geom::Geometry> GeoJSONReader::readGeometry(
     const geos_nlohmann::json& j) const
 {
-    const std::string& type = j["type"];
+    const std::string& type = j.at("type");
     if (type == "Point") {
         return readPoint(j);
     }
@@ -217,7 +217,7 @@ geom::Coordinate GeoJSONReader::readCoordinate(
 std::unique_ptr<geom::Point> GeoJSONReader::readPoint(
     const geos_nlohmann::json& j) const
 {
-    const auto& coords = j["coordinates"].get<std::vector<double>>();
+    const auto& coords = j.at("coordinates").get<std::vector<double>>();
     if (coords.size() == 1) {
         throw  ParseException("Expected two coordinates found one");
     }
@@ -233,7 +233,7 @@ std::unique_ptr<geom::Point> GeoJSONReader::readPoint(
 std::unique_ptr<geom::LineString> GeoJSONReader::readLineString(
     const geos_nlohmann::json& j) const
 {
-    const auto& coords = j["coordinates"].get<std::vector<std::vector<double>>>();
+    const auto& coords = j.at("coordinates").get<std::vector<std::vector<double>>>();
     std::vector<geom::Coordinate> coordinates;
     coordinates.reserve(coords.size());
     for (const auto& coord : coords) {
@@ -245,9 +245,9 @@ std::unique_ptr<geom::LineString> GeoJSONReader::readLineString(
 }
 
 std::unique_ptr<geom::Polygon> GeoJSONReader::readPolygon(
-    const geos_nlohmann::json& json) const
+    const geos_nlohmann::json& j) const
 {
-    const auto& polygonCoords = json["coordinates"].get<std::vector<std::vector<std::vector<double>>>>();
+    const auto& polygonCoords = j.at("coordinates").get<std::vector<std::vector<std::vector<double>>>>();
     return readPolygon(polygonCoords);
 }
 
@@ -286,7 +286,7 @@ std::unique_ptr<geom::Polygon> GeoJSONReader::readPolygon(
 std::unique_ptr<geom::MultiPoint> GeoJSONReader::readMultiPoint(
     const geos_nlohmann::json& j) const
 {
-    const auto& coords = j["coordinates"].get<std::vector<std::vector<double>>>();
+    const auto& coords = j.at("coordinates").get<std::vector<std::vector<double>>>();
     std::vector<std::unique_ptr<geom::Point>> points;
     points.reserve(coords.size());
     for (const auto& coord : coords) {
@@ -297,9 +297,9 @@ std::unique_ptr<geom::MultiPoint> GeoJSONReader::readMultiPoint(
 }
 
 std::unique_ptr<geom::MultiLineString> GeoJSONReader::readMultiLineString(
-    const geos_nlohmann::json& json) const
+    const geos_nlohmann::json& j) const
 {
-    const auto& listOfCoords = json["coordinates"].get<std::vector<std::vector<std::vector<double>>>>();
+    const auto& listOfCoords = j.at("coordinates").get<std::vector<std::vector<std::vector<double>>>>();
     std::vector<std::unique_ptr<geom::LineString>> lines;
     lines.reserve(listOfCoords.size());
     for (const auto& coords :  listOfCoords) {
@@ -316,9 +316,9 @@ std::unique_ptr<geom::MultiLineString> GeoJSONReader::readMultiLineString(
 }
 
 std::unique_ptr<geom::MultiPolygon> GeoJSONReader::readMultiPolygon(
-    const geos_nlohmann::json& json) const
+    const geos_nlohmann::json& j) const
 {
-    const auto& multiPolygonCoords = json["coordinates"].get<std::vector<std::vector<std::vector<std::vector<double>>>>>();
+    const auto& multiPolygonCoords = j.at("coordinates").get<std::vector<std::vector<std::vector<std::vector<double>>>>>();
     std::vector<std::unique_ptr<geom::Polygon>> polygons;
     polygons.reserve(multiPolygonCoords.size());
     for (const auto& polygonCoords : multiPolygonCoords) {
@@ -330,7 +330,7 @@ std::unique_ptr<geom::MultiPolygon> GeoJSONReader::readMultiPolygon(
 std::unique_ptr<geom::GeometryCollection> GeoJSONReader::readGeometryCollection(
     const geos_nlohmann::json& j) const
 {
-    const auto& jsonGeometries = j["geometries"];
+    const auto& jsonGeometries = j.at("geometries");
     std::vector<std::unique_ptr<geom::Geometry>> geometries;
     geometries.reserve(jsonGeometries.size());
     for (const auto& jsonGeometry : jsonGeometries) {
diff --git a/tests/unit/io/GeoJSONReaderTest.cpp b/tests/unit/io/GeoJSONReaderTest.cpp
index 462ca11fa..cfba3f020 100644
--- a/tests/unit/io/GeoJSONReaderTest.cpp
+++ b/tests/unit/io/GeoJSONReaderTest.cpp
@@ -437,5 +437,22 @@ void object::test<29>
     ensure_equals("ParseException: Expected two coordinates found more than two", errorMessage);
 }
 
+// Throw ParseException for bad GeoJSON
+template<>
+template<>
+void object::test<30>
+()
+{
+    std::string errorMessage;
+    std::string geojson { "{ \"missing\": \"type\" }" };
+    bool error = false;
+    try {
+        GeomPtr geom(geojsonreader.read(geojson));
+    } catch (geos::io::ParseException& e) {
+        error = true;
+    }
+    ensure(error == true);
+}
+
 }
 

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

Summary of changes:
 src/io/GeoJSONReader.cpp            | 36 ++++++++++++++++++------------------
 tests/unit/io/GeoJSONReaderTest.cpp | 17 +++++++++++++++++
 2 files changed, 35 insertions(+), 18 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list