[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