1diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt 2index 14506516..2e236476 100644 3--- a/tests/CMakeLists.txt 4+++ b/tests/CMakeLists.txt 5@@ -11,4 +11,5 @@ 6 add_subdirectory(unit) 7 add_subdirectory(xmltester) 8 add_subdirectory(bigtest) 9+add_subdirectory(fuzz) 10 11diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt 12new file mode 100644 13index 00000000..d0bd7a02 14--- /dev/null 15+++ b/tests/fuzz/CMakeLists.txt 16@@ -0,0 +1,15 @@ 17+################################################################################ 18+# Part of CMake configuration for GEOS 19+# 20+# Copyright (C) 2018 Mateusz Loskot <mateusz@loskot.net> 21+# 22+# This is free software; you can redistribute and/or modify it under 23+# the terms of the GNU Lesser General Public Licence as published 24+# by the Free Software Foundation. 25+# See the COPYING file for more information. 26+################################################################################ 27+if(DEFINED ENV{LIB_FUZZING_ENGINE}) 28+ add_executable(fuzz_geo2 fuzz_geo2.c) 29+ target_include_directories(fuzz_geo2 PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>) 30+ target_link_libraries(fuzz_geo2 geos_c $ENV{LIB_FUZZING_ENGINE}) 31+endif() 32diff --git a/tests/fuzz/fuzz_geo2.c b/tests/fuzz/fuzz_geo2.c 33new file mode 100644 34index 00000000..ceee7ea6 35--- /dev/null 36+++ b/tests/fuzz/fuzz_geo2.c 37@@ -0,0 +1,69 @@ 38+#include <stdio.h> 39+#include <stdlib.h> 40+#include <stdint.h> 41+#include <stdarg.h> 42+#include <string.h> 43+ 44+#include "geos_c.h" 45+ 46+static int initialized = 0; 47+FILE * flogOut; 48+ 49+void 50+notice(const char *fmt, ...) { 51+ va_list ap; 52+ fprintf( flogOut, "NOTICE: "); 53+ va_start (ap, fmt); 54+ vfprintf( flogOut, fmt, ap); 55+ va_end(ap); 56+ fprintf( flogOut, "\n" ); 57+} 58+ 59+void 60+log_and_exit(const char *fmt, ...) { 61+ va_list ap; 62+ fprintf( flogOut, "ERROR: "); 63+ va_start (ap, fmt); 64+ vfprintf( flogOut, fmt, ap); 65+ va_end(ap); 66+ fprintf( flogOut, "\n" ); 67+} 68+ 69+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 70+ if (initialized == 0) { 71+ flogOut = fopen("/dev/null", "wb"); 72+ initGEOS(notice, log_and_exit); 73+ initialized = 1; 74+ } 75+ size_t sep; 76+ for (sep = 0; sep < Size; sep ++) { 77+ if (Data[sep] == 0) { 78+ break; 79+ } 80+ } 81+ if (sep == Size) { 82+ return 0; 83+ } 84+ GEOSGeometry *g1 = GEOSGeomFromWKT(Data); 85+ 86+ if (g1 != NULL) { 87+ GEOSGeometry *g2 = GEOSGeomFromWKB_buf(Data+sep, Size-sep); 88+ if (g2 != NULL) { 89+ size_t usize; 90+ GEOSGeometry *g3 = GEOSIntersection(g1, g2); 91+ GEOSGeom_destroy(g3); 92+ g3 = GEOSDifference(g1, g2); 93+ GEOSGeom_destroy(g3); 94+ g3 = GEOSUnion(g1, g2); 95+ GEOSGeom_destroy(g3); 96+ unsigned char* uptr = GEOSGeomToWKB_buf(g1, &usize); 97+ free(uptr); 98+ GEOSGeom_destroy(g2); 99+ } 100+ char * r = GEOSGeomToWKT(g1); 101+ free(r); 102+ GEOSGeom_destroy(g1); 103+ } 104+ return 0; 105+} 106+ 107