[postgis-tickets] r17726 - OSS Fuzz for geojson.

Darafei komzpa at gmail.com
Sun Aug 18 04:27:31 PDT 2019


Author: komzpa
Date: 2019-08-18 04:27:31 -0700 (Sun, 18 Aug 2019)
New Revision: 17726

Added:
   trunk/fuzzers/geojson_import_fuzzer.cpp
   trunk/fuzzers/geojson_import_fuzzer.dict
   trunk/fuzzers/geojson_import_fuzzer.options
   trunk/fuzzers/geos_stub.h
   trunk/fuzzers/proj_stub.h
Modified:
   trunk/NEWS
   trunk/fuzzers/build_google_oss_fuzzers.sh
   trunk/fuzzers/wkb_import_fuzzer.cpp
   trunk/fuzzers/wkt_import_fuzzer.cpp
   trunk/liblwgeom/lwcollection.c
   trunk/liblwgeom/lwgeom.c
   trunk/liblwgeom/lwin_geojson.c
   trunk/liblwgeom/lwline.c
   trunk/liblwgeom/lwmline.c
   trunk/liblwgeom/ptarray.c
Log:
OSS Fuzz for geojson.

Enable allocation testing for other fuzzers.

Closes #4387
Closes https://github.com/postgis/postgis/pull/462



Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/NEWS	2019-08-18 11:27:31 UTC (rev 17726)
@@ -230,6 +230,7 @@
   - #4406, Throw on invalid characters when decoding geohash (Raúl Marín)
   - #4459, Fix ST_Subdivide crash on intermediate EMPTY (Darafei Praliaskouski)
   - #4470, ST_GeomFromGeoJSON crash on empty rings (Darafei Praliaskouski)
+  - #4387, Re-enable OSS Fuzz and fuzz geojson parser (Darafei Praliaskouski)
 
 
 PostGIS 2.5.0

Modified: trunk/fuzzers/build_google_oss_fuzzers.sh
===================================================================
--- trunk/fuzzers/build_google_oss_fuzzers.sh	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/fuzzers/build_google_oss_fuzzers.sh	2019-08-18 11:27:31 UTC (rev 17726)
@@ -28,7 +28,7 @@
     echo "Building fuzzer $fuzzerName"
     $CXX $CXXFLAGS -std=c++11 -I$SRC_DIR/liblwgeom \
         $sourceFilename $* -o $OUT/$fuzzerName \
-        -lFuzzingEngine -lstdc++ $SRC_DIR/liblwgeom/.libs/liblwgeom.a
+        -lFuzzingEngine -lstdc++ $SRC_DIR/liblwgeom/.libs/liblwgeom.a /usr/lib/x86_64-linux-gnu/libjson-c.a
 }
 
 fuzzerFiles=$(dirname $0)/*.cpp
@@ -37,4 +37,4 @@
     build_fuzzer $fuzzerName $F
 done
 
-cp $(dirname $0)/*.dict $(dirname $0)/*.options $OUT/
\ No newline at end of file
+cp $(dirname $0)/*.dict $(dirname $0)/*.options $(dirname $0)/*.zip $OUT/

Added: trunk/fuzzers/geojson_import_fuzzer.cpp
===================================================================
--- trunk/fuzzers/geojson_import_fuzzer.cpp	                        (rev 0)
+++ trunk/fuzzers/geojson_import_fuzzer.cpp	2019-08-18 11:27:31 UTC (rev 17726)
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * Project:  PostGIS
+ * Purpose:  Fuzzer
+ * Author:   Even Rouault, even.rouault at spatialys.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <set>
+extern "C" {
+#include "liblwgeom.h"
+#include "geos_stub.h"
+#include "proj_stub.h"
+}
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv);
+
+extern "C" {
+static void
+noticereporter(const char *, va_list)
+{}
+}
+
+static void
+debuglogger(int, const char *, va_list)
+{}
+
+int
+LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/)
+{
+	lwgeom_set_handlers(malloc, realloc, free, noticereporter, noticereporter);
+	lwgeom_set_debuglogger(debuglogger);
+	return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+	char *srs = NULL;
+	char *psz = static_cast<char *>(malloc(len + 1));
+	memcpy(psz, buf, len);
+	psz[len] = '\0';
+	LWGEOM *lwgeom = lwgeom_from_geojson(psz, &srs);
+	lwgeom_free(lwgeom);
+	lwfree(srs);
+	free(psz);
+	return 0;
+}

Added: trunk/fuzzers/geojson_import_fuzzer.dict
===================================================================
--- trunk/fuzzers/geojson_import_fuzzer.dict	                        (rev 0)
+++ trunk/fuzzers/geojson_import_fuzzer.dict	2019-08-18 11:27:31 UTC (rev 17726)
@@ -0,0 +1,20 @@
+"["
+"]"
+","
+":"
+"="
+"0"
+"90"
+"180"
+"type"
+"Point"
+"LineString"
+"Polygon"
+"MultiPoint"
+"MultiLinestring"
+"MultiPolygon"
+"GeometryCollection"
+"Triangle"
+"coordinates"
+"geometry"
+space=" "

Added: trunk/fuzzers/geojson_import_fuzzer.options
===================================================================
--- trunk/fuzzers/geojson_import_fuzzer.options	                        (rev 0)
+++ trunk/fuzzers/geojson_import_fuzzer.options	2019-08-18 11:27:31 UTC (rev 17726)
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 100000

Added: trunk/fuzzers/geos_stub.h
===================================================================
--- trunk/fuzzers/geos_stub.h	                        (rev 0)
+++ trunk/fuzzers/geos_stub.h	2019-08-18 11:27:31 UTC (rev 17726)
@@ -0,0 +1,388 @@
+/******************************************************************************
+ *
+ * Project:  PostGIS
+ * Purpose:  Fuzzer
+ * Author:   Even Rouault, even.rouault at spatialys.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+#include <assert.h>
+void
+GEOSCoordSeq_destroy()
+{
+	assert(0);
+}
+void
+GEOSClipByRect()
+{
+	assert(0);
+}
+void
+GEOSUnion()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_getDimensions()
+{
+	assert(0);
+}
+void
+GEOSPreparedCovers()
+{
+	assert(0);
+}
+void
+GEOSPreparedContains()
+{
+	assert(0);
+}
+void
+GEOSSymDifference()
+{
+	assert(0);
+}
+void
+GEOSUnionCascaded()
+{
+	assert(0);
+}
+void
+GEOSGetExteriorRing()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_setX()
+{
+	assert(0);
+}
+void
+GEOSGeom_createLineString()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_getY()
+{
+	assert(0);
+}
+void
+GEOSEquals()
+{
+	assert(0);
+}
+void
+GEOSRelatePatternMatch()
+{
+	assert(0);
+}
+void
+GEOSGeom_createCollection()
+{
+	assert(0);
+}
+void
+GEOSGeom_extractUniquePoints()
+{
+	assert(0);
+}
+void
+GEOSNormalize()
+{
+	assert(0);
+}
+void
+GEOSVoronoiDiagram()
+{
+	assert(0);
+}
+void
+GEOSArea()
+{
+	assert(0);
+}
+void
+GEOSLineMerge()
+{
+	assert(0);
+}
+void
+GEOSGeom_createPolygon()
+{
+	assert(0);
+}
+void
+GEOSGetCentroid()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_create()
+{
+	assert(0);
+}
+void
+GEOSFree()
+{
+	assert(0);
+}
+void
+initGEOS()
+{
+	assert(0);
+}
+void
+GEOSIntersection()
+{
+	assert(0);
+}
+void
+GEOSEnvelope()
+{
+	assert(0);
+}
+void
+GEOSGetGeometryN()
+{
+	assert(0);
+}
+void
+GEOSSTRtree_insert()
+{
+	assert(0);
+}
+void
+GEOSGeomTypeId()
+{
+	assert(0);
+}
+void
+GEOSBoundary()
+{
+	assert(0);
+}
+void
+GEOSversion()
+{
+	assert(0);
+}
+void
+GEOSGetInteriorRingN()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_setY()
+{
+	assert(0);
+}
+void
+GEOSGetSRID()
+{
+	assert(0);
+}
+void
+GEOSGeom_destroy()
+{
+	assert(0);
+}
+void
+GEOSGeom_createEmptyPolygon()
+{
+	assert(0);
+}
+void
+GEOSPolygonize()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_getX()
+{
+	assert(0);
+}
+void
+GEOSSharedPaths()
+{
+	assert(0);
+}
+void
+GEOSSTRtree_create()
+{
+	assert(0);
+}
+void
+GEOSGeom_clone()
+{
+	assert(0);
+}
+void
+GEOSRelateBoundaryNodeRule()
+{
+	assert(0);
+}
+void
+GEOSSnap()
+{
+	assert(0);
+}
+void
+GEOSRelatePattern()
+{
+	assert(0);
+}
+void
+GEOSSetSRID()
+{
+	assert(0);
+}
+void
+GEOSisValid()
+{
+	assert(0);
+}
+void
+GEOSContains()
+{
+	assert(0);
+}
+void
+GEOSPreparedGeom_destroy()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_setZ()
+{
+	assert(0);
+}
+void
+GEOSOffsetCurve()
+{
+	assert(0);
+}
+void
+GEOSUnaryUnion()
+{
+	assert(0);
+}
+void
+GEOSPrepare()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_getSize()
+{
+	assert(0);
+}
+void
+GEOSGetNumInteriorRings()
+{
+	assert(0);
+}
+void
+GEOSGetNumGeometries()
+{
+	assert(0);
+}
+void
+GEOSisSimple()
+{
+	assert(0);
+}
+void
+GEOSDifference()
+{
+	assert(0);
+}
+void
+GEOSPreparedIntersects()
+{
+	assert(0);
+}
+void
+GEOSisEmpty()
+{
+	assert(0);
+}
+void
+GEOSPointOnSurface()
+{
+	assert(0);
+}
+void
+GEOSSTRtree_query()
+{
+	assert(0);
+}
+void
+GEOSGeom_createPoint()
+{
+	assert(0);
+}
+void
+GEOSSTRtree_destroy()
+{
+	assert(0);
+}
+void
+GEOSIntersects()
+{
+	assert(0);
+}
+void
+GEOSHasZ()
+{
+	assert(0);
+}
+void
+GEOSGeom_getCoordSeq()
+{
+	assert(0);
+}
+void
+GEOSCoordSeq_getZ()
+{
+	assert(0);
+}
+void
+GEOSGeom_createLinearRing()
+{
+	assert(0);
+}
+void
+GEOSGeomType()
+{
+	assert(0);
+}
+void
+GEOSDelaunayTriangulation()
+{
+	assert(0);
+}
+void
+GEOSNode()
+{
+	assert(0);
+}

Added: trunk/fuzzers/proj_stub.h
===================================================================
--- trunk/fuzzers/proj_stub.h	                        (rev 0)
+++ trunk/fuzzers/proj_stub.h	2019-08-18 11:27:31 UTC (rev 17726)
@@ -0,0 +1,58 @@
+/******************************************************************************
+ *
+ * Project:  PostGIS
+ * Purpose:  Fuzzer
+ * Author:   Even Rouault, even.rouault at spatialys.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+#include <assert.h>
+void
+geod_init()
+{
+	assert(0);
+}
+void
+geod_inverse()
+{
+	assert(0);
+}
+void
+geod_direct()
+{
+	assert(0);
+}
+void
+geod_polygon_init()
+{
+	assert(0);
+}
+void
+geod_polygon_addpoint()
+{
+	assert(0);
+}
+void
+geod_polygon_compute()
+{
+	assert(0);
+}

Modified: trunk/fuzzers/wkb_import_fuzzer.cpp
===================================================================
--- trunk/fuzzers/wkb_import_fuzzer.cpp	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/fuzzers/wkb_import_fuzzer.cpp	2019-08-18 11:27:31 UTC (rev 17726)
@@ -38,87 +38,8 @@
 extern "C"
 {
 #include "liblwgeom.h"
-
-void GEOSCoordSeq_destroy() { assert(0); }
-void GEOSClipByRect() { assert(0); }
-void GEOSUnion() { assert(0); }
-void GEOSCoordSeq_getDimensions() { assert(0); }
-void GEOSPreparedCovers() { assert(0); }
-void GEOSPreparedContains() { assert(0); }
-void GEOSSymDifference() { assert(0); }
-void GEOSUnionCascaded() { assert(0); }
-void GEOSGetExteriorRing() { assert(0); }
-void GEOSCoordSeq_setX() { assert(0); }
-void GEOSGeom_createLineString() { assert(0); }
-void GEOSCoordSeq_getY() { assert(0); }
-void GEOSEquals() { assert(0); }
-void GEOSRelatePatternMatch() { assert(0); }
-void GEOSGeom_createCollection() { assert(0); }
-void GEOSGeom_extractUniquePoints() { assert(0); }
-void GEOSNormalize() { assert(0); }
-void GEOSVoronoiDiagram() { assert(0); }
-void GEOSArea() { assert(0); }
-void GEOSLineMerge() { assert(0); }
-void GEOSGeom_createPolygon() { assert(0); }
-void GEOSGetCentroid() { assert(0); }
-void GEOSCoordSeq_create() { assert(0); }
-void GEOSFree() { assert(0); }
-void initGEOS() { assert(0); }
-void GEOSIntersection() { assert(0); }
-void GEOSEnvelope() { assert(0); }
-void GEOSGetGeometryN() { assert(0); }
-void GEOSSTRtree_insert() { assert(0); }
-void GEOSGeomTypeId() { assert(0); }
-void GEOSBoundary() { assert(0); }
-void GEOSversion() { assert(0); }
-void GEOSGetInteriorRingN() { assert(0); }
-void GEOSCoordSeq_setY() { assert(0); }
-void GEOSGetSRID() { assert(0); }
-void GEOSGeom_destroy() { assert(0); }
-void GEOSGeom_createEmptyPolygon() { assert(0); }
-void GEOSPolygonize() { assert(0); }
-void GEOSCoordSeq_getX() { assert(0); }
-void GEOSSharedPaths() { assert(0); }
-void GEOSSTRtree_create() { assert(0); }
-void GEOSGeom_clone() { assert(0); }
-void GEOSRelateBoundaryNodeRule() { assert(0); }
-void GEOSSnap() { assert(0); }
-void GEOSRelatePattern() { assert(0); }
-void GEOSSetSRID() { assert(0); }
-void GEOSisValid() { assert(0); }
-void GEOSContains() { assert(0); }
-void GEOSPreparedGeom_destroy() { assert(0); }
-void GEOSCoordSeq_setZ() { assert(0); }
-void GEOSOffsetCurve() { assert(0); }
-void GEOSUnaryUnion() { assert(0); }
-void GEOSPrepare() { assert(0); }
-void GEOSCoordSeq_getSize() { assert(0); }
-void GEOSGetNumInteriorRings() { assert(0); }
-void GEOSGetNumGeometries() { assert(0); }
-void GEOSisSimple() { assert(0); }
-void GEOSDifference() { assert(0); }
-void GEOSPreparedIntersects() { assert(0); }
-void GEOSisEmpty() { assert(0); }
-void GEOSPointOnSurface() { assert(0); }
-void GEOSSTRtree_query() { assert(0); }
-void GEOSGeom_createPoint() { assert(0); }
-void GEOSSTRtree_destroy() { assert(0); }
-void GEOSIntersects() { assert(0); }
-void GEOSHasZ() { assert(0); }
-void GEOSGeom_getCoordSeq() { assert(0); }
-void GEOSCoordSeq_getZ() { assert(0); }
-void GEOSGeom_createLinearRing() { assert(0); }
-void GEOSGeomType() { assert(0); }
-void GEOSDelaunayTriangulation() { assert(0); }
-void GEOSNode() { assert(0); }
-
-void geod_init() { assert(0); }
-void geod_inverse() { assert(0); }
-void geod_direct() { assert(0); }
-void geod_polygon_init() { assert(0); }
-void geod_polygon_addpoint() { assert(0); }
-void geod_polygon_compute() { assert(0); }
-
+#include "geos_stub.h"
+#include "proj_stub.h"
 }
 
 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv);
@@ -182,11 +103,10 @@
 
 int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/)
 {
-    lwgeom_set_handlers(allocator, reallocator, freeor, errorreporter, noticereporter);
-    lwgeom_set_debuglogger(debuglogger);
-    return 0;
+	lwgeom_set_handlers(malloc, realloc, free, noticereporter, noticereporter);
+	lwgeom_set_debuglogger(debuglogger);
+	return 0;
 }
-
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
 
 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)

Modified: trunk/fuzzers/wkt_import_fuzzer.cpp
===================================================================
--- trunk/fuzzers/wkt_import_fuzzer.cpp	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/fuzzers/wkt_import_fuzzer.cpp	2019-08-18 11:27:31 UTC (rev 17726)
@@ -38,87 +38,8 @@
 extern "C"
 {
 #include "liblwgeom.h"
-
-void GEOSCoordSeq_destroy() { assert(0); }
-void GEOSClipByRect() { assert(0); }
-void GEOSUnion() { assert(0); }
-void GEOSCoordSeq_getDimensions() { assert(0); }
-void GEOSPreparedCovers() { assert(0); }
-void GEOSPreparedContains() { assert(0); }
-void GEOSSymDifference() { assert(0); }
-void GEOSUnionCascaded() { assert(0); }
-void GEOSGetExteriorRing() { assert(0); }
-void GEOSCoordSeq_setX() { assert(0); }
-void GEOSGeom_createLineString() { assert(0); }
-void GEOSCoordSeq_getY() { assert(0); }
-void GEOSEquals() { assert(0); }
-void GEOSRelatePatternMatch() { assert(0); }
-void GEOSGeom_createCollection() { assert(0); }
-void GEOSGeom_extractUniquePoints() { assert(0); }
-void GEOSNormalize() { assert(0); }
-void GEOSVoronoiDiagram() { assert(0); }
-void GEOSArea() { assert(0); }
-void GEOSLineMerge() { assert(0); }
-void GEOSGeom_createPolygon() { assert(0); }
-void GEOSGetCentroid() { assert(0); }
-void GEOSCoordSeq_create() { assert(0); }
-void GEOSFree() { assert(0); }
-void initGEOS() { assert(0); }
-void GEOSIntersection() { assert(0); }
-void GEOSEnvelope() { assert(0); }
-void GEOSGetGeometryN() { assert(0); }
-void GEOSSTRtree_insert() { assert(0); }
-void GEOSGeomTypeId() { assert(0); }
-void GEOSBoundary() { assert(0); }
-void GEOSversion() { assert(0); }
-void GEOSGetInteriorRingN() { assert(0); }
-void GEOSCoordSeq_setY() { assert(0); }
-void GEOSGetSRID() { assert(0); }
-void GEOSGeom_destroy() { assert(0); }
-void GEOSGeom_createEmptyPolygon() { assert(0); }
-void GEOSPolygonize() { assert(0); }
-void GEOSCoordSeq_getX() { assert(0); }
-void GEOSSharedPaths() { assert(0); }
-void GEOSSTRtree_create() { assert(0); }
-void GEOSGeom_clone() { assert(0); }
-void GEOSRelateBoundaryNodeRule() { assert(0); }
-void GEOSSnap() { assert(0); }
-void GEOSRelatePattern() { assert(0); }
-void GEOSSetSRID() { assert(0); }
-void GEOSisValid() { assert(0); }
-void GEOSContains() { assert(0); }
-void GEOSPreparedGeom_destroy() { assert(0); }
-void GEOSCoordSeq_setZ() { assert(0); }
-void GEOSOffsetCurve() { assert(0); }
-void GEOSUnaryUnion() { assert(0); }
-void GEOSPrepare() { assert(0); }
-void GEOSCoordSeq_getSize() { assert(0); }
-void GEOSGetNumInteriorRings() { assert(0); }
-void GEOSGetNumGeometries() { assert(0); }
-void GEOSisSimple() { assert(0); }
-void GEOSDifference() { assert(0); }
-void GEOSPreparedIntersects() { assert(0); }
-void GEOSisEmpty() { assert(0); }
-void GEOSPointOnSurface() { assert(0); }
-void GEOSSTRtree_query() { assert(0); }
-void GEOSGeom_createPoint() { assert(0); }
-void GEOSSTRtree_destroy() { assert(0); }
-void GEOSIntersects() { assert(0); }
-void GEOSHasZ() { assert(0); }
-void GEOSGeom_getCoordSeq() { assert(0); }
-void GEOSCoordSeq_getZ() { assert(0); }
-void GEOSGeom_createLinearRing() { assert(0); }
-void GEOSGeomType() { assert(0); }
-void GEOSDelaunayTriangulation() { assert(0); }
-void GEOSNode() { assert(0); }
-
-void geod_init() { assert(0); }
-void geod_inverse() { assert(0); }
-void geod_direct() { assert(0); }
-void geod_polygon_init() { assert(0); }
-void geod_polygon_addpoint() { assert(0); }
-void geod_polygon_compute() { assert(0); }
-
+#include "geos_stub.h"
+#include "proj_stub.h"
 }
 
 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv);
@@ -182,9 +103,9 @@
 
 int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/)
 {
-    lwgeom_set_handlers(allocator, reallocator, freeor, errorreporter, noticereporter);
-    lwgeom_set_debuglogger(debuglogger);
-    return 0;
+	lwgeom_set_handlers(malloc, realloc, free, noticereporter, noticereporter);
+	lwgeom_set_debuglogger(debuglogger);
+	return 0;
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);

Modified: trunk/liblwgeom/lwcollection.c
===================================================================
--- trunk/liblwgeom/lwcollection.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/lwcollection.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -93,7 +93,10 @@
 {
 	LWCOLLECTION *ret;
 	if( ! lwtype_is_collection(type) )
+	{
 		lwerror("Non-collection type specified in collection constructor!");
+		return NULL;
+	}
 
 	ret = lwalloc(sizeof(LWCOLLECTION));
 	ret->type = type;

Modified: trunk/liblwgeom/lwgeom.c
===================================================================
--- trunk/liblwgeom/lwgeom.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/lwgeom.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -798,6 +798,8 @@
 LWGEOM*
 lwgeom_force_dims(const LWGEOM *geom, int hasz, int hasm)
 {
+	if (!geom)
+		return NULL;
 	switch(geom->type)
 	{
 		case POINTTYPE:

Modified: trunk/liblwgeom/lwin_geojson.c
===================================================================
--- trunk/liblwgeom/lwin_geojson.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/lwin_geojson.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -107,9 +107,8 @@
 {
 	POINT4D pt = {0, 0, 0, 0};
 
-	if (json_type_array == json_object_get_type(poObj))
+	if (json_object_get_type(poObj) == json_type_array)
 	{
-
 		json_object *poObjCoord = NULL;
 		const int nSize = json_object_array_length(poObj);
 		if (nSize < 2)
@@ -137,6 +136,7 @@
 	else
 	{
 		/* If it's not an array, just don't handle it */
+		lwerror("The 'coordinates' in GeoJSON are not sufficiently nested");
 		return LW_FAILURE;
 	}
 
@@ -147,6 +147,8 @@
 parse_geojson_point(json_object *geojson, int *hasz)
 {
 	json_object *coords = parse_coordinates(geojson);
+	if (!coords)
+		return NULL;
 	POINTARRAY *pa = ptarray_construct_empty(1, 0, 1);
 	parse_geojson_coord(coords, hasz, pa);
 	return (LWGEOM *)lwpoint_construct(0, NULL, pa);
@@ -156,6 +158,8 @@
 parse_geojson_linestring(json_object *geojson, int *hasz)
 {
 	json_object *points = parse_coordinates(geojson);
+	if (!points)
+		return NULL;
 	POINTARRAY *pa = ptarray_construct_empty(1, 0, 1);
 	const int nPoints = json_object_array_length(points);
 	for (int i = 0; i < nPoints; i++)
@@ -169,8 +173,9 @@
 static inline LWPOLY *
 parse_geojson_poly_rings(json_object *rings, int *hasz)
 {
-	if (!rings)
+	if (!rings || json_object_get_type(rings) != json_type_array)
 		return NULL;
+
 	int nRings = json_object_array_length(rings);
 
 	/* No rings => POLYGON EMPTY */
@@ -186,6 +191,9 @@
 		json_object *points = json_object_array_get_idx(rings, i);
 		if (!points || json_object_get_type(points) != json_type_array)
 		{
+			for (int k = 0; k < o; k++)
+				ptarray_free(ppa[k]);
+			lwfree(ppa);
 			lwerror("The 'coordinates' in GeoJSON ring are not an array");
 			return NULL;
 		}
@@ -201,15 +209,14 @@
 				continue;
 		}
 
-		ppa[o++] = ptarray_construct_empty(1, 0, 1);
+		ppa[o] = ptarray_construct_empty(1, 0, 1);
 		for (int j = 0; j < nPoints; j++)
 		{
 			json_object *coords = NULL;
 			coords = json_object_array_get_idx(points, j);
-			if (LW_FAILURE == parse_geojson_coord(coords, hasz, ppa[i]))
+			if (LW_FAILURE == parse_geojson_coord(coords, hasz, ppa[o]))
 			{
-				int k;
-				for (k = 0; k < o; k++)
+				for (int k = 0; k <= o; k++)
 					ptarray_free(ppa[k]);
 				lwfree(ppa);
 				lwerror("The 'coordinates' in GeoJSON are not sufficiently nested");
@@ -216,6 +223,7 @@
 				return NULL;
 			}
 		}
+		o++;
 	}
 
 	/* All the rings were empty! */
@@ -238,6 +246,8 @@
 parse_geojson_multipoint(json_object *geojson, int *hasz)
 {
 	json_object *points = parse_coordinates(geojson);
+	if (!points)
+		return NULL;
 	LWMPOINT *geom = (LWMPOINT *)lwcollection_construct_empty(MULTIPOINTTYPE, 0, 1, 0);
 
 	const int nPoints = json_object_array_length(points);
@@ -245,8 +255,14 @@
 	{
 		POINTARRAY *pa = ptarray_construct_empty(1, 0, 1);
 		json_object *coord = json_object_array_get_idx(points, i);
-		parse_geojson_coord(coord, hasz, pa);
-		geom = lwmpoint_add_lwpoint(geom, lwpoint_construct(0, NULL, pa));
+		if (parse_geojson_coord(coord, hasz, pa))
+			geom = lwmpoint_add_lwpoint(geom, lwpoint_construct(0, NULL, pa));
+		else
+		{
+			lwmpoint_free(geom);
+			ptarray_free(pa);
+			return NULL;
+		}
 	}
 
 	return (LWGEOM *)geom;
@@ -255,27 +271,38 @@
 static inline LWGEOM *
 parse_geojson_multilinestring(json_object *geojson, int *hasz)
 {
-	json_object *poObjLines = parse_coordinates(geojson);
+	json_object *mls = parse_coordinates(geojson);
+	if (!mls)
+		return NULL;
 	LWMLINE *geom = (LWMLINE *)lwcollection_construct_empty(MULTILINETYPE, 0, 1, 0);
-	const int nLines = json_object_array_length(poObjLines);
+	const int nLines = json_object_array_length(mls);
 	for (int i = 0; i < nLines; ++i)
 	{
 		POINTARRAY *pa = ptarray_construct_empty(1, 0, 1);
-		json_object *poObjLine = json_object_array_get_idx(poObjLines, i);
+		json_object *coords = json_object_array_get_idx(mls, i);
 
-		if (json_type_array == json_object_get_type(poObjLine))
+		if (json_type_array == json_object_get_type(coords))
 		{
-			const int nPoints = json_object_array_length(poObjLine);
+			const int nPoints = json_object_array_length(coords);
 			for (int j = 0; j < nPoints; ++j)
 			{
-				json_object *coords = json_object_array_get_idx(poObjLine, j);
-				parse_geojson_coord(coords, hasz, pa);
+				json_object *coord = json_object_array_get_idx(coords, j);
+				if (!parse_geojson_coord(coord, hasz, pa))
+				{
+					lwmline_free(geom);
+					ptarray_free(pa);
+					return NULL;
+				}
 			}
-
 			geom = lwmline_add_lwline(geom, lwline_construct(0, NULL, pa));
 		}
+		else
+		{
+			lwmline_free(geom);
+			ptarray_free(pa);
+			return NULL;
+		}
 	}
-
 	return (LWGEOM *)geom;
 }
 
@@ -282,8 +309,10 @@
 static inline LWGEOM *
 parse_geojson_multipolygon(json_object *geojson, int *hasz)
 {
+	json_object *polys = parse_coordinates(geojson);
+	if (!polys)
+		return NULL;
 	LWGEOM *geom = (LWGEOM *)lwcollection_construct_empty(MULTIPOLYGONTYPE, 0, 1, 0);
-	json_object *polys = parse_coordinates(geojson);
 	int nPolys = json_object_array_length(polys);
 
 	for (int i = 0; i < nPolys; ++i)
@@ -290,7 +319,8 @@
 	{
 		json_object *rings = json_object_array_get_idx(polys, i);
 		LWPOLY *poly = parse_geojson_poly_rings(rings, hasz);
-		geom = (LWGEOM *)lwmpoly_add_lwpoly((LWMPOLY *)geom, poly);
+		if (poly)
+			geom = (LWGEOM *)lwmpoly_add_lwpoly((LWMPOLY *)geom, poly);
 	}
 
 	return geom;
@@ -299,7 +329,6 @@
 static inline LWGEOM *
 parse_geojson_geometrycollection(json_object *geojson, int *hasz)
 {
-	LWGEOM *geom = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, 0, 1, 0);
 	json_object *poObjGeoms = findMemberByName(geojson, "geometries");
 	if (!poObjGeoms)
 	{
@@ -306,6 +335,7 @@
 		lwerror("Unable to find 'geometries' in GeoJSON string");
 		return NULL;
 	}
+	LWGEOM *geom = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, 0, 1, 0);
 
 	if (json_type_array == json_object_get_type(poObjGeoms))
 	{
@@ -313,8 +343,14 @@
 		for (int i = 0; i < nGeoms; ++i)
 		{
 			json_object *poObjGeom = json_object_array_get_idx(poObjGeoms, i);
-			geom = (LWGEOM *)lwcollection_add_lwgeom((LWCOLLECTION *)geom,
-								 parse_geojson(poObjGeom, hasz));
+			LWGEOM *t = parse_geojson(poObjGeom, hasz);
+			if (t)
+				geom = (LWGEOM *)lwcollection_add_lwgeom((LWCOLLECTION *)geom, t);
+			else
+			{
+				lwgeom_free(geom);
+				return NULL;
+			}
 		}
 	}
 
@@ -419,6 +455,8 @@
 	int hasz = LW_FALSE;
 	LWGEOM *lwgeom = parse_geojson(poObj, &hasz);
 	json_object_put(poObj);
+	if (!lwgeom)
+		return NULL;
 
 	if (!hasz)
 	{

Modified: trunk/liblwgeom/lwline.c
===================================================================
--- trunk/liblwgeom/lwline.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/lwline.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -41,22 +41,13 @@
 LWLINE *
 lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
 {
-	LWLINE *result;
-	result = (LWLINE*) lwalloc(sizeof(LWLINE));
-
-	LWDEBUG(2, "lwline_construct called.");
-
+	LWLINE *result = (LWLINE *)lwalloc(sizeof(LWLINE));
 	result->type = LINETYPE;
-
 	result->flags = points->flags;
 	FLAGS_SET_BBOX(result->flags, bbox?1:0);
-
-	LWDEBUGF(3, "lwline_construct type=%d", result->type);
-
 	result->srid = srid;
 	result->points = points;
 	result->bbox = bbox;
-
 	return result;
 }
 

Modified: trunk/liblwgeom/lwmline.c
===================================================================
--- trunk/liblwgeom/lwmline.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/lwmline.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -111,18 +111,19 @@
 
 void lwmline_free(LWMLINE *mline)
 {
-	uint32_t i;
-	if ( ! mline ) return;
+	if (!mline)
+		return;
 
-	if ( mline->bbox )
+	if (mline->bbox)
 		lwfree(mline->bbox);
 
-	for ( i = 0; i < mline->ngeoms; i++ )
-		if ( mline->geoms && mline->geoms[i] )
-			lwline_free(mline->geoms[i]);
-
-	if ( mline->geoms )
+	if (mline->geoms)
+	{
+		for (uint32_t i = 0; i < mline->ngeoms; i++)
+			if (mline->geoms[i])
+				lwline_free(mline->geoms[i]);
 		lwfree(mline->geoms);
+	}
 
 	lwfree(mline);
 }

Modified: trunk/liblwgeom/ptarray.c
===================================================================
--- trunk/liblwgeom/ptarray.c	2019-08-16 21:26:05 UTC (rev 17725)
+++ trunk/liblwgeom/ptarray.c	2019-08-18 11:27:31 UTC (rev 17726)
@@ -84,6 +84,8 @@
 int
 ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, uint32_t where)
 {
+	if (!pa || !p)
+		return LW_FAILURE;
 	size_t point_size = ptarray_point_size(pa);
 	LWDEBUGF(5,"pa = %p; p = %p; where = %d", pa, p, where);
 	LWDEBUGF(5,"pa->npoints = %d; pa->maxpoints = %d", pa->npoints, pa->maxpoints);
@@ -144,7 +146,6 @@
 int
 ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int repeated_points)
 {
-
 	/* Check for pathology */
 	if( ! pa || ! pt )
 	{
@@ -314,14 +315,14 @@
 	return pa;
 }
 
-void ptarray_free(POINTARRAY *pa)
+void
+ptarray_free(POINTARRAY *pa)
 {
-	if(pa)
+	if (pa)
 	{
-		if(pa->serialized_pointlist && ( ! FLAGS_GET_READONLY(pa->flags) ) )
+		if (pa->serialized_pointlist && (!FLAGS_GET_READONLY(pa->flags)))
 			lwfree(pa->serialized_pointlist);
 		lwfree(pa);
-		LWDEBUG(5,"Freeing a PointArray");
 	}
 }
 



More information about the postgis-tickets mailing list