Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
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 <stddef.h>
30 : #include <stdint.h>
31 :
32 : #include "ogr_api.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_error.h"
35 : #include "cpl_vsi.h"
36 : #include "ogrsf_frmts.h"
37 :
38 : #ifndef REGISTER_FUNC
39 : #define REGISTER_FUNC OGRRegisterAll
40 : #ifndef OGR_SKIP
41 : #define OGR_SKIP "CAD,DXF"
42 : #endif
43 : #endif
44 :
45 : #ifndef EXTENSION
46 : #define EXTENSION "bin"
47 : #endif
48 :
49 : #ifndef MEM_FILENAME
50 : #define MEM_FILENAME "/vsimem/test"
51 : #endif
52 :
53 : #ifndef GDAL_FILENAME
54 : #define GDAL_FILENAME MEM_FILENAME
55 : #endif
56 :
57 : extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv);
58 : extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
59 :
60 0 : int LLVMFuzzerInitialize(int * /*argc*/, char ***argv)
61 : {
62 0 : const char *exe_path = (*argv)[0];
63 0 : if (CPLGetConfigOption("GDAL_DATA", nullptr) == nullptr)
64 : {
65 0 : CPLSetConfigOption("GDAL_DATA", CPLGetPath(exe_path));
66 : }
67 0 : CPLSetConfigOption("CPL_TMPDIR", "/tmp");
68 0 : CPLSetConfigOption("DISABLE_OPEN_REAL_NETCDF_FILES", "YES");
69 0 : CPLSetConfigOption("GDAL_HTTP_TIMEOUT", "1");
70 0 : CPLSetConfigOption("GDAL_HTTP_CONNECTTIMEOUT", "1");
71 : // To avoid timeouts. See https://github.com/OSGeo/gdal/issues/502
72 0 : CPLSetConfigOption("DXF_MAX_BSPLINE_CONTROL_POINTS", "100");
73 0 : CPLSetConfigOption("NAS_INDICATOR",
74 : "NAS-Operationen;AAA-Fachschema;aaa.xsd;aaa-suite");
75 0 : CPLSetConfigOption(
76 : "USERNAME",
77 : "unknown"); // see GMLASConfiguration::GetBaseCacheDirectory()
78 :
79 : #ifdef OGR_SKIP
80 0 : CPLSetConfigOption("OGR_SKIP", OGR_SKIP);
81 : #endif
82 0 : REGISTER_FUNC();
83 :
84 0 : return 0;
85 : }
86 :
87 1 : int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
88 : {
89 : #ifdef USE_FILESYSTEM
90 : char szTempFilename[64];
91 : snprintf(szTempFilename, sizeof(szTempFilename), "/tmp/gdal_fuzzer_%d.%s",
92 : (int)getpid(), EXTENSION);
93 : VSILFILE *fp = VSIFOpenL(szTempFilename, "wb");
94 : if (!fp)
95 : {
96 : fprintf(stderr, "Cannot create %s\n", szTempFilename);
97 : return 1;
98 : }
99 : VSIFWriteL(buf, 1, len, fp);
100 : #else
101 1 : VSILFILE *fp = VSIFileFromMemBuffer(
102 : MEM_FILENAME, reinterpret_cast<GByte *>(const_cast<uint8_t *>(buf)),
103 : len, FALSE);
104 : #endif
105 1 : VSIFCloseL(fp);
106 :
107 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
108 : #ifdef USE_FILESYSTEM
109 : OGRDataSourceH hDS = OGROpen(szTempFilename, FALSE, nullptr);
110 : #elif defined(FOR_OGR_MIRAMON)
111 : std::string osVsitarPrefix("/vsitar/");
112 : char **papszFiles =
113 : VSIReadDir(std::string(osVsitarPrefix).append(MEM_FILENAME).c_str());
114 : std::string osFileInTar;
115 : for (int i = 0; papszFiles && papszFiles[i]; ++i)
116 : {
117 : if (EQUAL(CPLGetExtension(papszFiles[i]), "pol") ||
118 : EQUAL(CPLGetExtension(papszFiles[i]), "arc") ||
119 : EQUAL(CPLGetExtension(papszFiles[i]), "pnt"))
120 : {
121 : osFileInTar = papszFiles[i];
122 : break;
123 : }
124 : }
125 : CSLDestroy(papszFiles);
126 : OGRDataSourceH hDS = nullptr;
127 : if (!osFileInTar.empty())
128 : {
129 : hDS = OGROpen(std::string(osVsitarPrefix)
130 : .append(MEM_FILENAME)
131 : .append("/")
132 : .append(osFileInTar)
133 : .c_str(),
134 : FALSE, nullptr);
135 : }
136 : #else
137 1 : OGRDataSourceH hDS = OGROpen(GDAL_FILENAME, FALSE, nullptr);
138 : #endif
139 1 : if (hDS)
140 : {
141 0 : const int nLayers = OGR_DS_GetLayerCount(hDS);
142 0 : time_t nStartTime = time(nullptr);
143 0 : bool bStop = false;
144 0 : for (int i = 0; !bStop && i < 10 && i < nLayers; i++)
145 : {
146 0 : OGRLayerH hLayer = OGR_DS_GetLayer(hDS, i);
147 0 : OGR_L_GetSpatialRef(hLayer);
148 0 : OGR_L_GetGeomType(hLayer);
149 0 : OGR_L_GetFIDColumn(hLayer);
150 0 : OGR_L_GetGeometryColumn(hLayer);
151 : OGRFeatureH hFeature;
152 0 : OGRFeatureH hFeaturePrev = nullptr;
153 0 : for (int j = 0;
154 0 : j < 1000 && !bStop &&
155 0 : (hFeature = OGR_L_GetNextFeature(hLayer)) != nullptr;
156 : j++)
157 : {
158 : // Limit runtime to 20 seconds if features returned are
159 : // different. Otherwise this may be a sign of a bug in the
160 : // reader and we want the infinite loop to be revealed.
161 0 : if (time(nullptr) - nStartTime > 20)
162 : {
163 : bool bIsSameAsPrevious =
164 0 : (hFeaturePrev != nullptr &&
165 0 : OGR_F_Equal(hFeature, hFeaturePrev));
166 0 : if (!bIsSameAsPrevious)
167 : {
168 0 : bStop = true;
169 : }
170 : }
171 0 : if (hFeaturePrev)
172 0 : OGR_F_Destroy(hFeaturePrev);
173 0 : hFeaturePrev = hFeature;
174 : }
175 0 : if (hFeaturePrev)
176 0 : OGR_F_Destroy(hFeaturePrev);
177 : }
178 0 : OGR_DS_Destroy(hDS);
179 : }
180 1 : CPLPopErrorHandler();
181 : #ifdef USE_FILESYSTEM
182 : VSIUnlink(szTempFilename);
183 : #else
184 1 : VSIUnlink(MEM_FILENAME);
185 : #endif
186 1 : return 0;
187 : }
|