1 /******************************************************************************
2 *
3 * Project: PostGIS
4 * Purpose: Fuzzer
5 * Author: Even Rouault, even.rouault at spatialys.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include <assert.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <setjmp.h>
35
36 #include <set>
37
38 extern "C"
39 {
40 #include "liblwgeom.h"
41
GEOSCoordSeq_destroy()42 void GEOSCoordSeq_destroy() { assert(0); }
GEOSClipByRect()43 void GEOSClipByRect() { assert(0); }
GEOSUnion()44 void GEOSUnion() { assert(0); }
GEOSCoordSeq_getDimensions()45 void GEOSCoordSeq_getDimensions() { assert(0); }
GEOSPreparedCovers()46 void GEOSPreparedCovers() { assert(0); }
GEOSPreparedContains()47 void GEOSPreparedContains() { assert(0); }
GEOSSymDifference()48 void GEOSSymDifference() { assert(0); }
GEOSUnionCascaded()49 void GEOSUnionCascaded() { assert(0); }
GEOSGetExteriorRing()50 void GEOSGetExteriorRing() { assert(0); }
GEOSCoordSeq_setX()51 void GEOSCoordSeq_setX() { assert(0); }
GEOSGeom_createLineString()52 void GEOSGeom_createLineString() { assert(0); }
GEOSCoordSeq_getY()53 void GEOSCoordSeq_getY() { assert(0); }
GEOSEquals()54 void GEOSEquals() { assert(0); }
GEOSRelatePatternMatch()55 void GEOSRelatePatternMatch() { assert(0); }
GEOSGeom_createCollection()56 void GEOSGeom_createCollection() { assert(0); }
GEOSGeom_extractUniquePoints()57 void GEOSGeom_extractUniquePoints() { assert(0); }
GEOSNormalize()58 void GEOSNormalize() { assert(0); }
GEOSVoronoiDiagram()59 void GEOSVoronoiDiagram() { assert(0); }
GEOSArea()60 void GEOSArea() { assert(0); }
GEOSLineMerge()61 void GEOSLineMerge() { assert(0); }
GEOSGeom_createPolygon()62 void GEOSGeom_createPolygon() { assert(0); }
GEOSGetCentroid()63 void GEOSGetCentroid() { assert(0); }
GEOSCoordSeq_create()64 void GEOSCoordSeq_create() { assert(0); }
GEOSFree()65 void GEOSFree() { assert(0); }
initGEOS()66 void initGEOS() { assert(0); }
GEOSIntersection()67 void GEOSIntersection() { assert(0); }
GEOSEnvelope()68 void GEOSEnvelope() { assert(0); }
GEOSGetGeometryN()69 void GEOSGetGeometryN() { assert(0); }
GEOSSTRtree_insert()70 void GEOSSTRtree_insert() { assert(0); }
GEOSGeomTypeId()71 void GEOSGeomTypeId() { assert(0); }
GEOSBoundary()72 void GEOSBoundary() { assert(0); }
GEOSversion()73 void GEOSversion() { assert(0); }
GEOSGetInteriorRingN()74 void GEOSGetInteriorRingN() { assert(0); }
GEOSCoordSeq_setY()75 void GEOSCoordSeq_setY() { assert(0); }
GEOSGetSRID()76 void GEOSGetSRID() { assert(0); }
GEOSGeom_destroy()77 void GEOSGeom_destroy() { assert(0); }
GEOSGeom_createEmptyPolygon()78 void GEOSGeom_createEmptyPolygon() { assert(0); }
GEOSPolygonize()79 void GEOSPolygonize() { assert(0); }
GEOSCoordSeq_getX()80 void GEOSCoordSeq_getX() { assert(0); }
GEOSSharedPaths()81 void GEOSSharedPaths() { assert(0); }
GEOSSTRtree_create()82 void GEOSSTRtree_create() { assert(0); }
GEOSGeom_clone()83 void GEOSGeom_clone() { assert(0); }
GEOSRelateBoundaryNodeRule()84 void GEOSRelateBoundaryNodeRule() { assert(0); }
GEOSSnap()85 void GEOSSnap() { assert(0); }
GEOSRelatePattern()86 void GEOSRelatePattern() { assert(0); }
GEOSSetSRID()87 void GEOSSetSRID() { assert(0); }
GEOSisValid()88 void GEOSisValid() { assert(0); }
GEOSContains()89 void GEOSContains() { assert(0); }
GEOSPreparedGeom_destroy()90 void GEOSPreparedGeom_destroy() { assert(0); }
GEOSCoordSeq_setZ()91 void GEOSCoordSeq_setZ() { assert(0); }
GEOSOffsetCurve()92 void GEOSOffsetCurve() { assert(0); }
GEOSUnaryUnion()93 void GEOSUnaryUnion() { assert(0); }
GEOSPrepare()94 void GEOSPrepare() { assert(0); }
GEOSCoordSeq_getSize()95 void GEOSCoordSeq_getSize() { assert(0); }
GEOSGetNumInteriorRings()96 void GEOSGetNumInteriorRings() { assert(0); }
GEOSGetNumGeometries()97 void GEOSGetNumGeometries() { assert(0); }
GEOSisSimple()98 void GEOSisSimple() { assert(0); }
GEOSDifference()99 void GEOSDifference() { assert(0); }
GEOSPreparedIntersects()100 void GEOSPreparedIntersects() { assert(0); }
GEOSisEmpty()101 void GEOSisEmpty() { assert(0); }
GEOSPointOnSurface()102 void GEOSPointOnSurface() { assert(0); }
GEOSSTRtree_query()103 void GEOSSTRtree_query() { assert(0); }
GEOSGeom_createPoint()104 void GEOSGeom_createPoint() { assert(0); }
GEOSSTRtree_destroy()105 void GEOSSTRtree_destroy() { assert(0); }
GEOSIntersects()106 void GEOSIntersects() { assert(0); }
GEOSHasZ()107 void GEOSHasZ() { assert(0); }
GEOSGeom_getCoordSeq()108 void GEOSGeom_getCoordSeq() { assert(0); }
GEOSCoordSeq_getZ()109 void GEOSCoordSeq_getZ() { assert(0); }
GEOSGeom_createLinearRing()110 void GEOSGeom_createLinearRing() { assert(0); }
GEOSGeomType()111 void GEOSGeomType() { assert(0); }
GEOSDelaunayTriangulation()112 void GEOSDelaunayTriangulation() { assert(0); }
GEOSNode()113 void GEOSNode() { assert(0); }
114
geod_init()115 void geod_init() { assert(0); }
geod_inverse()116 void geod_inverse() { assert(0); }
geod_direct()117 void geod_direct() { assert(0); }
geod_polygon_init()118 void geod_polygon_init() { assert(0); }
geod_polygon_addpoint()119 void geod_polygon_addpoint() { assert(0); }
geod_polygon_compute()120 void geod_polygon_compute() { assert(0); }
121
122 }
123
124 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv);
125
126 // Keep active heap allocated memory corresponding to returns of allocator()
127 // and reallocator()
128 std::set<void*> oSetPointers;
129 jmp_buf jmpBuf;
130
131 extern "C"
132 {
133 static void *
allocator(size_t size)134 allocator(size_t size)
135 {
136 void *mem = malloc(size);
137 oSetPointers.insert(mem);
138 return mem;
139 }
140
141 static void
freeor(void * mem)142 freeor(void *mem)
143 {
144 oSetPointers.erase(mem);
145 free(mem);
146 }
147
148 static void *
reallocator(void * mem,size_t size)149 reallocator(void *mem, size_t size)
150 {
151 oSetPointers.erase(mem);
152 void *ret = realloc(mem, size);
153 oSetPointers.insert(ret);
154 return ret;
155 }
156
157 static void
noticereporter(const char *,va_list)158 noticereporter(const char *, va_list )
159 {
160 }
161
162 static void
errorreporter(const char *,va_list)163 errorreporter(const char *, va_list )
164 {
165 // Cleanup any heap-allocated memory still active
166 for(std::set<void*>::iterator oIter = oSetPointers.begin();
167 oIter != oSetPointers.end(); ++oIter )
168 {
169 free(*oIter);
170 }
171 oSetPointers.clear();
172 // Abort everything to jump to setjmp() call
173 longjmp(jmpBuf, 1);
174 }
175
176 static void
debuglogger(int,const char *,va_list)177 debuglogger(int, const char *, va_list)
178 {
179 }
180
181 }
182
LLVMFuzzerInitialize(int *,char ***)183 int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/)
184 {
185 lwgeom_set_handlers(allocator, reallocator, freeor, errorreporter, noticereporter);
186 lwgeom_set_debuglogger(debuglogger);
187 return 0;
188 }
189
190 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
191
LLVMFuzzerTestOneInput(const uint8_t * buf,size_t len)192 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
193 {
194 if( setjmp(jmpBuf) )
195 return 0;
196 LWGEOM* lwgeom = lwgeom_from_wkb(buf, len, LW_PARSER_CHECK_NONE);
197 lwgeom_free(lwgeom);
198 //assert( oSetPointers.empty() );
199 return 0;
200 }
201