diff --git a/.gitignore b/.gitignore index 201a332d..567dc13b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ /sftp-config.json .tags .tags_sorted_by_file +/fuzzing/*_fuzzer +/fuzzing/*_fuzzer.options +/fuzzing/*_fuzzer_seed_corpus.zip diff --git a/fuzzing/Makefile b/fuzzing/Makefile new file mode 100644 index 00000000..2e90a475 --- /dev/null +++ b/fuzzing/Makefile @@ -0,0 +1,19 @@ +# CAUTION: this file is invoked by https://github.com/google/oss-fuzz + +CXXFLAGS += -I../include + +all: \ + $(OUT)/json_fuzzer \ + $(OUT)/json_fuzzer_seed_corpus.zip \ + $(OUT)/json_fuzzer.options + +$(OUT)/json_fuzzer: fuzzer.cpp + $(CXX) $(CXXFLAGS) $< -o$@ $(LIB_FUZZING_ENGINE) + +$(OUT)/json_fuzzer_seed_corpus.zip: seed_corpus/* + zip -j $@ $? + +$(OUT)/json_fuzzer.options: + @echo "[libfuzzer]" > $@ + @echo "max_len = 256" >> $@ + @echo "timeout = 10" >> $@ diff --git a/fuzzing/fuzz.sh b/fuzzing/fuzz.sh new file mode 100755 index 00000000..0a7399c5 --- /dev/null +++ b/fuzzing/fuzz.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# This script mimics an invocation from https://github.com/google/oss-fuzz + +export CXX='clang++' +export CXXFLAGS='-fsanitize-coverage=trace-pc-guard -fsanitize=address' +export LIB_FUZZING_ENGINE=-lFuzzer +make OUT=. +./json_fuzzer my_corpus seed_corpus diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp new file mode 100644 index 00000000..acc8a6a2 --- /dev/null +++ b/fuzzing/fuzzer.cpp @@ -0,0 +1,23 @@ +#include + +class memstream : public std::istream { + struct membuf : std::streambuf { + membuf(const uint8_t *p, size_t l) { + setg((char *)p, (char *)p, (char *)p + l); + } + }; + membuf _buffer; + + public: + memstream(const uint8_t *p, size_t l) + : std::istream(&_buffer), _buffer(p, l) { + rdbuf(&_buffer); + } +}; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + DynamicJsonBuffer jsonBuffer; + memstream json(data, size); + jsonBuffer.parse(json); + return 0; +} diff --git a/fuzzing/my_corpus/.gitignore b/fuzzing/my_corpus/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/fuzzing/my_corpus/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/fuzzing/seed_corpus/ArduinoJson.json b/fuzzing/seed_corpus/ArduinoJson.json new file mode 100644 index 00000000..0cd31670 --- /dev/null +++ b/fuzzing/seed_corpus/ArduinoJson.json @@ -0,0 +1,8 @@ +{ + "sensor": "gps", + "time": 1351824120, + "data": [ + 48.75608, + 2.302038 + ] +} diff --git a/fuzzing/seed_corpus/OpenWeatherMap.json b/fuzzing/seed_corpus/OpenWeatherMap.json new file mode 100644 index 00000000..27d6bafd --- /dev/null +++ b/fuzzing/seed_corpus/OpenWeatherMap.json @@ -0,0 +1,53 @@ +{ + "coord": { + "lon": -0.13, + "lat": 51.51 + }, + "weather": [ + { + "id": 301, + "main": "Drizzle", + "description": "drizzle", + "icon": "09n" + }, + { + "id": 701, + "main": "Mist", + "description": "mist", + "icon": "50n" + }, + { + "id": 741, + "main": "Fog", + "description": "fog", + "icon": "50n" + } + ], + "base": "stations", + "main": { + "temp": 281.87, + "pressure": 1032, + "humidity": 100, + "temp_min": 281.15, + "temp_max": 283.15 + }, + "visibility": 2900, + "wind": { + "speed": 1.5 + }, + "clouds": { + "all": 90 + }, + "dt": 1483820400, + "sys": { + "type": 1, + "id": 5091, + "message": 0.0226, + "country": "GB", + "sunrise": 1483776245, + "sunset": 1483805443 + }, + "id": 2643743, + "name": "London", + "cod": 200 +} diff --git a/fuzzing/seed_corpus/WeatherUnderground.json b/fuzzing/seed_corpus/WeatherUnderground.json new file mode 100644 index 00000000..d53ce006 --- /dev/null +++ b/fuzzing/seed_corpus/WeatherUnderground.json @@ -0,0 +1,90 @@ +{ + "response": { + "version": "0.1", + "termsofService": "http://www.wunderground.com/weather/api/d/terms.html", + "features": { + "conditions": 1 + } + }, + "current_observation": { + "image": { + "url": "http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png", + "title": "Weather Underground", + "link": "http://www.wunderground.com" + }, + "display_location": { + "full": "San Francisco, CA", + "city": "San Francisco", + "state": "CA", + "state_name": "California", + "country": "US", + "country_iso3166": "US", + "zip": "94101", + "latitude": "37.77500916", + "longitude": "-122.41825867", + "elevation": "47.00000000" + }, + "observation_location": { + "full": "SOMA - Near Van Ness, San Francisco, California", + "city": "SOMA - Near Van Ness, San Francisco", + "state": "California", + "country": "US", + "country_iso3166": "US", + "latitude": "37.773285", + "longitude": "-122.417725", + "elevation": "49 ft" + }, + "estimated": {}, + "station_id": "KCASANFR58", + "observation_time": "Last Updated on June 27, 5:27 PM PDT", + "observation_time_rfc822": "Wed, 27 Jun 2012 17:27:13 -0700", + "observation_epoch": "1340843233", + "local_time_rfc822": "Wed, 27 Jun 2012 17:27:14 -0700", + "local_epoch": "1340843234", + "local_tz_short": "PDT", + "local_tz_long": "America/Los_Angeles", + "local_tz_offset": "-0700", + "weather": "Partly Cloudy", + "temperature_string": "66.3 F (19.1 C)", + "temp_f": 66.3, + "temp_c": 19.1, + "relative_humidity": "65%", + "wind_string": "From the NNW at 22.0 MPH Gusting to 28.0 MPH", + "wind_dir": "NNW", + "wind_degrees": 346, + "wind_mph": 22, + "wind_gust_mph": "28.0", + "wind_kph": 35.4, + "wind_gust_kph": "45.1", + "pressure_mb": "1013", + "pressure_in": "29.93", + "pressure_trend": "+", + "dewpoint_string": "54 F (12 C)", + "dewpoint_f": 54, + "dewpoint_c": 12, + "heat_index_string": "NA", + "heat_index_f": "NA", + "heat_index_c": "NA", + "windchill_string": "NA", + "windchill_f": "NA", + "windchill_c": "NA", + "feelslike_string": "66.3 F (19.1 C)", + "feelslike_f": "66.3", + "feelslike_c": "19.1", + "visibility_mi": "10.0", + "visibility_km": "16.1", + "solarradiation": "", + "UV": "5", + "precip_1hr_string": "0.00 in ( 0 mm)", + "precip_1hr_in": "0.00", + "precip_1hr_metric": " 0", + "precip_today_string": "0.00 in (0 mm)", + "precip_today_in": "0.00", + "precip_today_metric": "0", + "icon": "partlycloudy", + "icon_url": "http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", + "forecast_url": "http://www.wunderground.com/US/CA/San_Francisco.html", + "history_url": "http://www.wunderground.com/history/airport/KCASANFR58/2012/6/27/DailyHistory.html", + "ob_url": "http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.773285,-122.417725" + } +} diff --git a/scripts/oss-fuzz/.gitignore b/scripts/oss-fuzz/.gitignore new file mode 100644 index 00000000..d50ee772 --- /dev/null +++ b/scripts/oss-fuzz/.gitignore @@ -0,0 +1,2 @@ +/.vagrant/ +*.log diff --git a/scripts/oss-fuzz/Vagrantfile b/scripts/oss-fuzz/Vagrantfile new file mode 100644 index 00000000..e06c9f1f --- /dev/null +++ b/scripts/oss-fuzz/Vagrantfile @@ -0,0 +1,30 @@ +# A virtual machine to run https://github.com/google/oss-fuzz +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/xenial64" + + config.vm.synced_folder "E:\\Git\\Arduino\\libraries\\ArduinoJson", "/host/ArduinoJson" + config.vm.synced_folder "E:\\Git\\oss-fuzz", "/host/oss-fuzz" + + config.vm.network "forwarded_port", guest: 8001, host: 8001 + + config.vm.provision "shell", privileged: false, inline: <<-SHELL + set -x + + sudo apt-get update + sudo apt-get install -y make git docker.io zip + sudo groupadd docker + sudo usermod -aG docker $USER + + git clone https://github.com/google/fuzzer-test-suite.git FTS + ./FTS/tutorial/install-deps.sh # Get deps + ./FTS/tutorial/install-clang.sh # Get fresh clang binaries + # Get libFuzzer sources and build it + svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer + Fuzzer/build.sh + sudo mv libFuzzer.a /usr/local/lib/ + + echo "export PROJECT_NAME='arduinojson'" >> $HOME/.profile + echo "export CC='clang'" >> $HOME/.profile + echo "export CXX='clang++'" >> $HOME/.profile + SHELL +end