[geos-commits] [SCM] GEOS branch main updated. 6839f11f7cf27ed051a9900224e50a56a7d92f21

git at osgeo.org git at osgeo.org
Wed Sep 8 13:37:06 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  6839f11f7cf27ed051a9900224e50a56a7d92f21 (commit)
      from  5bb0eba2b33b924440b356334540e64b60c86201 (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 6839f11f7cf27ed051a9900224e50a56a7d92f21
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Wed Sep 8 13:37:01 2021 -0700

    Handle failure of createPolygon and clean up memory before throwing exception, closes #1111

diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index 2211d0f..350c685 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -2618,15 +2618,31 @@ extern "C" {
         return execute(extHandle, [&]() {
             GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
             const GeometryFactory* gf = handle->geomFactory;
+            bool good_holes = true, good_shell = true;
 
             // Validate input before taking ownership
-            for (size_t i = 0; i < nholes; i++) {
+            for (std::size_t i = 0; i < nholes; i++) {
                 if (!dynamic_cast<LinearRing*>(holes[i])) {
-                    throw IllegalArgumentException("Hole is not a LinearRing");
+                    good_holes = false;
+                    break;
                 }
             }
             if (!dynamic_cast<LinearRing*>(shell)) {
-                throw IllegalArgumentException("Shell is not a LinearRing");
+                good_shell = false;
+            }
+
+            // Contract for GEOSGeom_createPolygon is to take ownership of arguments
+            // which implies freeing them on exception,
+            // see https://trac.osgeo.org/geos/ticket/1111
+            if (!(good_holes && good_shell)) {
+                delete shell;
+                for (std::size_t i = 0; i < nholes; i++) {
+                    delete holes[i];
+                }
+                if (!good_shell)
+                    throw IllegalArgumentException("Shell is not a LinearRing");
+                else
+                    throw IllegalArgumentException("Hole is not a LinearRing");
             }
 
             std::unique_ptr<LinearRing> tmpshell(static_cast<LinearRing*>(shell));
diff --git a/tests/unit/capi/GEOSGeom_createPolygonTest.cpp b/tests/unit/capi/GEOSGeom_createPolygonTest.cpp
index 025d4f6..ee73562 100644
--- a/tests/unit/capi/GEOSGeom_createPolygonTest.cpp
+++ b/tests/unit/capi/GEOSGeom_createPolygonTest.cpp
@@ -50,5 +50,31 @@ void object::test<1>
     free(holes);
 }
 
+template<>
+template<>
+void object::test<2>
+()
+{
+    GEOSCoordSequence* shell_seq = GEOSCoordSeq_create(5, 2);
+
+    double shell_coords[] = {0,0, 0,10, 10,10, 10,0, 0,0};
+    for (unsigned int i = 0; i < 5; i++) {
+        GEOSCoordSeq_setXY(shell_seq, i, shell_coords[2*i], shell_coords[2*i+1]);
+    }
+
+    GEOSGeometry* shell = GEOSGeom_createLineString(shell_seq);
+    GEOSGeometry** holes = nullptr;
+    unsigned int nholes = 0;
+
+    // Returns null on exception, wrong input type for shell
+    GEOSGeometry* polygon = GEOSGeom_createPolygon(shell, holes, nholes);
+    ensure(polygon == nullptr);
+
+    // Shouldn't need this
+    if (polygon)
+        GEOSGeom_destroy(polygon);
+}
+
+
 } // namespace tut
 

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

Summary of changes:
 capi/geos_ts_c.cpp                             | 22 +++++++++++++++++++---
 tests/unit/capi/GEOSGeom_createPolygonTest.cpp | 26 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list