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