/src/gdal/fuzzers/gdal_vector_translate_fuzzer.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL |
4 | | * Purpose: Fuzzer |
5 | | * Author: Even Rouault, even.rouault at spatialys.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2018, 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 "gdal.h" |
30 | | #include "cpl_conv.h" |
31 | | #include "cpl_string.h" |
32 | | #include "cpl_error.h" |
33 | | #include "cpl_vsi.h" |
34 | | #include "gdal_utils.h" |
35 | | |
36 | | #ifndef REGISTER_FUNC |
37 | 82 | #define REGISTER_FUNC OGRRegisterAll |
38 | | #endif |
39 | | |
40 | | extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv); |
41 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len); |
42 | | |
43 | | int LLVMFuzzerInitialize(int * /*argc*/, char ***argv) |
44 | 82 | { |
45 | 82 | const char *exe_path = (*argv)[0]; |
46 | 82 | if (CPLGetConfigOption("GDAL_DATA", nullptr) == nullptr) |
47 | 82 | { |
48 | 82 | CPLSetConfigOption("GDAL_DATA", CPLGetPathSafe(exe_path).c_str()); |
49 | 82 | } |
50 | 82 | CPLSetConfigOption("CPL_TMPDIR", "/tmp"); |
51 | 82 | CPLSetConfigOption("DISABLE_OPEN_REAL_NETCDF_FILES", "YES"); |
52 | 82 | CPLSetConfigOption("GDAL_HTTP_TIMEOUT", "1"); |
53 | 82 | CPLSetConfigOption("GDAL_HTTP_CONNECTTIMEOUT", "1"); |
54 | | #ifdef OGR_SKIP |
55 | | CPLSetConfigOption("OGR_SKIP", OGR_SKIP); |
56 | | #endif |
57 | 82 | REGISTER_FUNC(); |
58 | 82 | return 0; |
59 | 82 | } |
60 | | |
61 | | int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) |
62 | 2.17k | { |
63 | 2.17k | VSILFILE *fp = VSIFileFromMemBuffer( |
64 | 2.17k | "/vsimem/test.tar", |
65 | 2.17k | reinterpret_cast<GByte *>(const_cast<uint8_t *>(buf)), len, FALSE); |
66 | 2.17k | VSIFCloseL(fp); |
67 | | |
68 | 2.17k | CPLPushErrorHandler(CPLQuietErrorHandler); |
69 | | |
70 | 2.17k | char **papszArgv = nullptr; |
71 | | |
72 | 2.17k | CPLString osOutFilename("out"); |
73 | 2.17k | fp = VSIFOpenL("/vsitar//vsimem/test.tar/cmd.txt", "rb"); |
74 | 2.17k | if (fp != nullptr) |
75 | 2.14k | { |
76 | 2.14k | const char *pszLine = nullptr; |
77 | 2.14k | if ((pszLine = CPLReadLineL(fp)) != nullptr) |
78 | 2.14k | { |
79 | 2.14k | osOutFilename = pszLine; |
80 | 2.14k | osOutFilename = osOutFilename.replaceAll('/', '_'); |
81 | 2.14k | } |
82 | 2.14k | int nCandidateLayerNames = 0; |
83 | 7.93k | while ((pszLine = CPLReadLineL(fp)) != nullptr) |
84 | 5.90k | { |
85 | 5.90k | if (pszLine[0] != '-') |
86 | 2.61k | { |
87 | 2.61k | nCandidateLayerNames++; |
88 | 2.61k | if (nCandidateLayerNames == 10) |
89 | 114 | break; |
90 | 2.61k | } |
91 | 5.78k | papszArgv = CSLAddString(papszArgv, pszLine); |
92 | 5.78k | } |
93 | 2.14k | VSIFCloseL(fp); |
94 | 2.14k | } |
95 | | |
96 | 2.17k | char **papszDrivers = CSLAddString(nullptr, "CSV"); |
97 | 2.17k | GDALDatasetH hSrcDS = |
98 | 2.17k | GDALOpenEx("/vsitar//vsimem/test.tar/in", GDAL_OF_VECTOR, papszDrivers, |
99 | 2.17k | nullptr, nullptr); |
100 | 2.17k | CSLDestroy(papszDrivers); |
101 | | |
102 | 2.17k | if (papszArgv != nullptr && hSrcDS != nullptr) |
103 | 2.14k | { |
104 | 2.14k | const int nLayerCount = GDALDatasetGetLayerCount(hSrcDS); |
105 | 25.4k | for (int i = 0; i < nLayerCount; i++) |
106 | 23.4k | { |
107 | 23.4k | OGRLayerH hLayer = GDALDatasetGetLayer(hSrcDS, i); |
108 | 23.4k | if (hLayer) |
109 | 23.4k | { |
110 | 23.4k | int nFieldCount = |
111 | 23.4k | OGR_FD_GetFieldCount(OGR_L_GetLayerDefn(hLayer)); |
112 | 23.4k | if (nFieldCount > 100) |
113 | 65 | { |
114 | 65 | papszArgv = CSLAddString(papszArgv, "-limit"); |
115 | 65 | papszArgv = CSLAddString(papszArgv, "100"); |
116 | 65 | break; |
117 | 65 | } |
118 | 23.4k | } |
119 | 23.4k | } |
120 | | |
121 | 2.14k | GDALVectorTranslateOptions *psOptions = |
122 | 2.14k | GDALVectorTranslateOptionsNew(papszArgv, nullptr); |
123 | 2.14k | if (psOptions) |
124 | 2.13k | { |
125 | 2.13k | CPLString osFullOutFilename("/vsimem/" + osOutFilename); |
126 | 2.13k | GDALDatasetH hOutDS = |
127 | 2.13k | GDALVectorTranslate(osFullOutFilename.c_str(), nullptr, 1, |
128 | 2.13k | &hSrcDS, psOptions, nullptr); |
129 | 2.13k | if (hOutDS) |
130 | 1.80k | { |
131 | 1.80k | GDALDriverH hOutDrv = GDALGetDatasetDriver(hOutDS); |
132 | 1.80k | GDALClose(hOutDS); |
133 | | |
134 | | // Try re-opening generated file |
135 | 1.80k | GDALClose(GDALOpenEx(osFullOutFilename, GDAL_OF_VECTOR, nullptr, |
136 | 1.80k | nullptr, nullptr)); |
137 | | |
138 | 1.80k | if (hOutDrv) |
139 | 1.80k | GDALDeleteDataset(hOutDrv, osFullOutFilename); |
140 | 1.80k | } |
141 | 2.13k | GDALVectorTranslateOptionsFree(psOptions); |
142 | 2.13k | } |
143 | 2.14k | } |
144 | 2.17k | CSLDestroy(papszArgv); |
145 | 2.17k | GDALClose(hSrcDS); |
146 | | |
147 | 2.17k | VSIRmdirRecursive("/vsimem/"); |
148 | | |
149 | 2.17k | CPLPopErrorHandler(); |
150 | | |
151 | 2.17k | return 0; |
152 | 2.17k | } |