• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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