diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2017-05-20 19:31:36 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2017-05-21 12:18:35 +0200 |
| commit | e1ed32922b718fa1a5b46a8fa6b5a42919e013a9 (patch) | |
| tree | 63f0bfb7fbcfab2bea06ffc84aafcb4407dcf8d5 /test/fuzzers | |
| parent | 2851ac9f7971f5a2c528d58338da42f71aec31cc (diff) | |
| download | PROJ-e1ed32922b718fa1a5b46a8fa6b5a42919e013a9.tar.gz PROJ-e1ed32922b718fa1a5b46a8fa6b5a42919e013a9.zip | |
Add fuzzer for Google OSS Fuzz
Diffstat (limited to 'test/fuzzers')
| -rwxr-xr-x | test/fuzzers/build_google_oss_fuzzers.sh | 34 | ||||
| -rwxr-xr-x | test/fuzzers/build_seed_corpus.sh | 12 | ||||
| -rw-r--r-- | test/fuzzers/standard_fuzzer.cpp | 160 |
3 files changed, 206 insertions, 0 deletions
diff --git a/test/fuzzers/build_google_oss_fuzzers.sh b/test/fuzzers/build_google_oss_fuzzers.sh new file mode 100755 index 00000000..625b8c1d --- /dev/null +++ b/test/fuzzers/build_google_oss_fuzzers.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -e + +if [ "$SRC" == "" ]; then + echo "SRC env var not defined" + exit 1 +fi + +if [ "$OUT" == "" ]; then + echo "OUT env var not defined" + exit 1 +fi + +if [ "$CXX" == "" ]; then + echo "CXX env var not defined" + exit 1 +fi + +SRC_DIR=$(dirname $0)/../.. + +build_fuzzer() +{ + fuzzerName=$1 + sourceFilename=$2 + shift + shift + echo "Building fuzzer $fuzzerName" + $CXX $CXXFLAGS -std=c++11 -I$SRC_DIR/src \ + $sourceFilename $* -o $OUT/$fuzzerName \ + -lFuzzingEngine $SRC_DIR/src/.libs/libproj.a -lpthread $EXTRA_LIBS +} + +build_fuzzer standard_fuzzer $(dirname $0)/standard_fuzzer.cpp diff --git a/test/fuzzers/build_seed_corpus.sh b/test/fuzzers/build_seed_corpus.sh new file mode 100755 index 00000000..d85465d3 --- /dev/null +++ b/test/fuzzers/build_seed_corpus.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +if [ "$OUT" == "" ]; then + echo "OUT env var not defined" + exit 1 +fi + +SRC_DIR=$(dirname $0)/../.. + +cp -r $SRC_DIR/nad/* $OUT diff --git a/test/fuzzers/standard_fuzzer.cpp b/test/fuzzers/standard_fuzzer.cpp new file mode 100644 index 00000000..470d1b1a --- /dev/null +++ b/test/fuzzers/standard_fuzzer.cpp @@ -0,0 +1,160 @@ +/****************************************************************************** + * + * Project: proj.4 + * Purpose: Fuzzer + * Author: Even Rouault, even.rouault at spatialys.com + * + ****************************************************************************** + * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +#include "proj_api.h" + +/* Standalone build: +g++ -g -std=c++11 standard_fuzzer.cpp -o standard_fuzzer -DSTANDALONE ../src/.libs/libproj.a -lpthread +*/ + +extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len); + +int LLVMFuzzerInitialize(int* /*argc*/, char*** argv) +{ + const char* argv0 = (*argv)[0]; + char* path = strdup(argv0); + char* lastslash = strrchr(path, '/'); + if( lastslash ) + { + *lastslash = '\0'; + setenv("PROJ_LIB", path, 1); + } + else + { + setenv("PROJ_LIB", ".", 1); + } + free(path); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + /* We expect the blob to be 3 lines: */ + /* source proj string\ndestination proj string\nx y */ + char* buf_dup = (char*)malloc(len+1); + memcpy(buf_dup, buf, len); + buf_dup[len] = 0; + char* first_line = buf_dup; + char* first_newline = strchr(first_line, '\n'); + if( !first_newline ) + { + free(buf_dup); + return 0; + } + first_newline[0] = 0; + char* second_line = first_newline + 1; + char* second_newline = strchr(second_line, '\n'); + if( !second_newline ) + { + free(buf_dup); + return 0; + } + second_newline[0] = 0; + char* third_line = second_newline + 1; + projPJ pj_src = pj_init_plus(first_line); + if( !pj_src ) + { + free(buf_dup); + return 0; + } + projPJ pj_dst = pj_init_plus(second_line); + if( !pj_dst ) + { + free(buf_dup); + pj_free(pj_src); + return 0; + } + double x = 0, y = 0; + if( sscanf(third_line, "%lf %lf", &x, &y) != 2 ) + { + free(buf_dup); + pj_free(pj_src); + pj_free(pj_dst); + return 0; + } +#ifdef STANDALONE + fprintf(stderr, "src=%s\n", first_line); + fprintf(stderr, "dst=%s\n", second_line); + fprintf(stderr, "coord=%s\n", third_line); +#endif + pj_transform( pj_src, pj_dst, 1, 0, &x, &y, NULL ); + free(buf_dup); + pj_free(pj_src); + pj_free(pj_dst); + return 0; +} + +#ifdef STANDALONE + +int main(int argc, char* argv[]) +{ + if( argc < 2 ) + { + const char str[] = + "+proj=longlat +datum=WGS84 +nodefs\n+proj=longlat +datum=WGS84 +nodefs\n2 49"; + return LLVMFuzzerTestOneInput((const uint8_t*)(str), sizeof(str)); + } + else + { + int nRet = 0; + void* buf = NULL; + int nLen = 0; + FILE* f = fopen(argv[1], "rb"); + if( !f ) + { + fprintf(stderr, "%s does not exist.\n", argv[1]); + exit(1); + } + fseek(f, 0, SEEK_END); + nLen = (int)ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(nLen); + if( !buf ) + { + fprintf(stderr, "malloc failed.\n"); + fclose(f); + exit(1); + } + fread(buf, nLen, 1, f); + fclose(f); + nRet = LLVMFuzzerTestOneInput((const uint8_t*)(buf), nLen); + free(buf); + return nRet; + } +} + +#endif // STANDALONE |
