[geos-commits] [SCM] GEOS branch main updated. 8aadb147d12b181cd470659eb6d91d595dd21395

git at osgeo.org git at osgeo.org
Fri Feb 21 09:28:17 PST 2025


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  8aadb147d12b181cd470659eb6d91d595dd21395 (commit)
      from  642e32daecee5154befff14efd6b5da873627fb3 (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 8aadb147d12b181cd470659eb6d91d595dd21395
Author: freemine <freemine at yeah.net>
Date:   Sat Feb 22 01:27:38 2025 +0800

    Enforce stricter rules when parsing WKT
    
    Closes #1241
    WKT input previously accepted odd mis-spellings of the geometry type names (eg `POIN EMPTY`) which is far more liberal than most WKT parsers. Now out of spec WKT throws `ParseException`.

diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index 19b9e115b..06a5dec49 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -1978,6 +1978,7 @@ extern void GEOS_DLL GEOSWKTReader_setFixStructure_r(
     GEOSWKTReader *reader,
     char doFix);
 
+
 /* ========== WKT Writer ========== */
 
 /** \see GEOSWKTReader_create */
diff --git a/src/io/WKTReader.cpp b/src/io/WKTReader.cpp
index fc850d220..2b4400a6b 100644
--- a/src/io/WKTReader.cpp
+++ b/src/io/WKTReader.cpp
@@ -157,7 +157,15 @@ WKTReader::getNextNumber(StringTokenizer* tokenizer)
 
 bool
 WKTReader::isTypeName(const std::string & type, const std::string & typeName) {
-    return util::startsWith(type, typeName);
+    auto l = type.size();
+    auto r = typeName.size();
+    if (l == r && type == typeName) return true;
+    if (l == r + 1 && (type == typeName + 'Z' || type == typeName + 'M')) return true;
+    if (l == r + 2 && type == typeName + "ZM") return true;
+
+    // take `POINT` as example:
+    // POI, POINTa, POINTZMx are all invalid
+    return false;
 }
 
 void
@@ -178,24 +186,34 @@ WKTReader::readOrdinateFlags(const std::string & s, OrdinateSet& ordinateFlags)
 std::string
 WKTReader::getNextEmptyOrOpener(StringTokenizer* tokenizer, OrdinateSet& ordinateFlags)
 {
+    const bool changesAllowed = ordinateFlags.changesAllowed();
     std::string nextWord = getNextWord(tokenizer);
 
     bool flagsModified = false;
 
     // Skip the Z, M or ZM of an SF1.2 3/4 dim coordinate.
     if (nextWord == "ZM") {
+        if (!changesAllowed) {
+          throw ParseException("'ZM' found but 'ZM' or 'Z' or 'M' has been specified in previous type");
+        }
         ordinateFlags.setZ(true);
         ordinateFlags.setM(true);
         flagsModified = true;
         nextWord = getNextWord(tokenizer);
     } else {
         if (nextWord == "Z") {
+            if (!changesAllowed) {
+              throw ParseException("'Z' found but 'ZM' or 'Z' or 'M' has been specified in previous type");
+            }
             ordinateFlags.setZ(true);
             flagsModified = true;
             nextWord = getNextWord(tokenizer);
         }
 
         if (nextWord == "M") {
+            if (!changesAllowed || flagsModified) {
+              throw ParseException("'M' found but 'ZM' or 'Z' or 'M' has been specified previously");
+            }
             ordinateFlags.setM(true);
             flagsModified = true;
             nextWord = getNextWord(tokenizer);
diff --git a/tests/unit/io/WKTReaderTest.cpp b/tests/unit/io/WKTReaderTest.cpp
index 59e5f1b25..af9621916 100644
--- a/tests/unit/io/WKTReaderTest.cpp
+++ b/tests/unit/io/WKTReaderTest.cpp
@@ -244,7 +244,6 @@ void object::test<9>
     ensure_dimension("POINT Z EMPTY", 3);
     ensure_dimension("POINTZM EMPTY", 4);
     ensure_dimension("POINT ZM EMPTY", 4);
-    ensure_dimension("POINT Z M EMPTY", 4);
 
     ensure_dimension("LINESTRING EMPTY", 2);
     ensure_dimension("LINESTRINGM EMPTY", 3);
@@ -253,7 +252,6 @@ void object::test<9>
     ensure_dimension("LINESTRING Z EMPTY", 3);
     ensure_dimension("LINESTRINGZM EMPTY", 4);
     ensure_dimension("LINESTRING ZM EMPTY", 4);
-    ensure_dimension("LINESTRING Z M EMPTY", 4);
 
     ensure_dimension("POLYGON EMPTY", 2);
     ensure_dimension("POLYGONM EMPTY", 3);
@@ -262,7 +260,6 @@ void object::test<9>
     ensure_dimension("POLYGON Z EMPTY", 3);
     ensure_dimension("POLYGONZM EMPTY", 4);
     ensure_dimension("POLYGON ZM EMPTY", 4);
-    ensure_dimension("POLYGON Z M EMPTY", 4);
 }
 
 
@@ -473,4 +470,33 @@ void object::test<24>
     ensure_equals(geom->getNumGeometries(), 3u);
 }
 
+// Raise exception strictly on invalid WKT
+template<>
+template<>
+void object::test<25>
+()
+{
+    ensure_parseexception("POI(1 1)");
+    ensure_parseexception("POINTx(1 1)");
+    ensure_parseexception("POINTxy(1 1)");
+    ensure_parseexception("POINTabc(1 1)");
+    ensure_parseexception("POINTZMc(1 1)");
+    ensure_parseexception("POINTaZM(1 1)");
+    ensure_parseexception("POINT Z M EMPTY");
+    ensure_parseexception("POINTZ Z EMPTY");
+    ensure_parseexception("POINTZ ZM EMPTY");
+    ensure_parseexception("POINT ZZ EMPTY");
+    ensure_parseexception("POINT ZZM EMPTY");
+    ensure_parseexception("POINT XY EMPTY");
+    ensure_parseexception("POINT MZ EMPTY");
+    ensure_parseexception("POINT ZMc EMPTY");
+    ensure_parseexception("POINT XY EMPT");
+    ensure_parseexception("POINT XY EMPT Y");
+    ensure_parseexception("POINT EMPTYY");
+
+    ensure_parseexception("POINT Z M EMPTY");
+    ensure_parseexception("LINESTRING Z M EMPTY");
+    ensure_parseexception("POLYGON Z M EMPTY");
+}
+
 } // namespace tut
diff --git a/tools/codespell.ignore b/tools/codespell.ignore
index 896a43d83..f29596743 100644
--- a/tools/codespell.ignore
+++ b/tools/codespell.ignore
@@ -15,3 +15,4 @@ seh
 bLoc
 aLo
 Wel
+EMPTYY

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

Summary of changes:
 capi/geos_c.h.in                |  1 +
 src/io/WKTReader.cpp            | 20 +++++++++++++++++++-
 tests/unit/io/WKTReaderTest.cpp | 32 +++++++++++++++++++++++++++++---
 tools/codespell.ignore          |  1 +
 4 files changed, 50 insertions(+), 4 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list