| diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt |
| index 14506516..2e236476 100644 |
| --- a/tests/CMakeLists.txt |
| +++ b/tests/CMakeLists.txt |
| @@ -11,4 +11,5 @@ |
| add_subdirectory(unit) |
| add_subdirectory(xmltester) |
| add_subdirectory(bigtest) |
| +add_subdirectory(fuzz) |
| |
| diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt |
| new file mode 100644 |
| index 00000000..d0bd7a02 |
| --- /dev/null |
| +++ b/tests/fuzz/CMakeLists.txt |
| @@ -0,0 +1,15 @@ |
| +################################################################################ |
| +# Part of CMake configuration for GEOS |
| +# |
| +# Copyright (C) 2018 Mateusz Loskot <mateusz@loskot.net> |
| +# |
| +# This is free software; you can redistribute and/or modify it under |
| +# the terms of the GNU Lesser General Public Licence as published |
| +# by the Free Software Foundation. |
| +# See the COPYING file for more information. |
| +################################################################################ |
| +if(DEFINED ENV{LIB_FUZZING_ENGINE}) |
| + add_executable(fuzz_geo2 fuzz_geo2.c) |
| + target_include_directories(fuzz_geo2 PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>) |
| + target_link_libraries(fuzz_geo2 geos_c $ENV{LIB_FUZZING_ENGINE}) |
| +endif() |
| diff --git a/tests/fuzz/fuzz_geo2.c b/tests/fuzz/fuzz_geo2.c |
| new file mode 100644 |
| index 00000000..ceee7ea6 |
| --- /dev/null |
| +++ b/tests/fuzz/fuzz_geo2.c |
| @@ -0,0 +1,69 @@ |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <stdint.h> |
| +#include <stdarg.h> |
| +#include <string.h> |
| + |
| +#include "geos_c.h" |
| + |
| +static int initialized = 0; |
| +FILE * flogOut; |
| + |
| +void |
| +notice(const char *fmt, ...) { |
| + va_list ap; |
| + fprintf( flogOut, "NOTICE: "); |
| + va_start (ap, fmt); |
| + vfprintf( flogOut, fmt, ap); |
| + va_end(ap); |
| + fprintf( flogOut, "\n" ); |
| +} |
| + |
| +void |
| +log_and_exit(const char *fmt, ...) { |
| + va_list ap; |
| + fprintf( flogOut, "ERROR: "); |
| + va_start (ap, fmt); |
| + vfprintf( flogOut, fmt, ap); |
| + va_end(ap); |
| + fprintf( flogOut, "\n" ); |
| +} |
| + |
| +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { |
| + if (initialized == 0) { |
| + flogOut = fopen("/dev/null", "wb"); |
| + initGEOS(notice, log_and_exit); |
| + initialized = 1; |
| + } |
| + size_t sep; |
| + for (sep = 0; sep < Size; sep ++) { |
| + if (Data[sep] == 0) { |
| + break; |
| + } |
| + } |
| + if (sep == Size) { |
| + return 0; |
| + } |
| + GEOSGeometry *g1 = GEOSGeomFromWKT(Data); |
| + |
| + if (g1 != NULL) { |
| + GEOSGeometry *g2 = GEOSGeomFromWKB_buf(Data+sep, Size-sep); |
| + if (g2 != NULL) { |
| + size_t usize; |
| + GEOSGeometry *g3 = GEOSIntersection(g1, g2); |
| + GEOSGeom_destroy(g3); |
| + g3 = GEOSDifference(g1, g2); |
| + GEOSGeom_destroy(g3); |
| + g3 = GEOSUnion(g1, g2); |
| + GEOSGeom_destroy(g3); |
| + unsigned char* uptr = GEOSGeomToWKB_buf(g1, &usize); |
| + free(uptr); |
| + GEOSGeom_destroy(g2); |
| + } |
| + char * r = GEOSGeomToWKT(g1); |
| + free(r); |
| + GEOSGeom_destroy(g1); |
| + } |
| + return 0; |
| +} |
| + |