Upgrade oss-fuzz to 4e241e814080eac62a106931214cbd17275182cc am: 61804fe0f0

Original change: undetermined

Change-Id: I25fe767c1eceac0514f8210a44d0f8ecf3f273f3
diff --git a/.travis.yml b/.travis.yml
index 879dbb6..3cf7704 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,8 +14,6 @@
 matrix:
   include:
     - name: "presubmit"
-      install:
-        - pip install -r infra/dev-requirements.txt
       script: ./infra/presubmit.py
     - name: "libfuzzer address x86_64"
       env:
@@ -58,7 +56,7 @@
         - TRAVIS_SANITIZER=dataflow
         - TRAVIS_ARCHITECTURE=x86_64
     - name: "infra-tests"
-      script: sudo ./infra/presubmit.py infra-tests
+      script: sudo /bin/bash -c 'source $HOME/virtualenv/python3.6/bin/activate && ./infra/presubmit.py infra-tests'
 
 script: ./infra/travis/travis_build.py
 
diff --git a/METADATA b/METADATA
index 2c2ef4d..9a352cb 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/google/oss-fuzz.git"
   }
-  version: "982ddca0351851891e55093717dbe8b76404b382"
+  version: "4e241e814080eac62a106931214cbd17275182cc"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 5
+    month: 6
     day: 1
   }
 }
diff --git a/docs/getting-started/continuous_integration.md b/docs/getting-started/continuous_integration.md
index 2dbc2ad..cc461a5 100644
--- a/docs/getting-started/continuous_integration.md
+++ b/docs/getting-started/continuous_integration.md
@@ -90,6 +90,10 @@
 This requires the user to manually check the logs for detected bugs. If dry run mode is desired,
 make sure to set the dry-run parameters in both the `Build Fuzzers` and `Run Fuzzers` action step.
 
+`allowed-broken-targets-percentage`: Can be set if you want to set a stricter
+limit for broken fuzz targets than OSS-Fuzz's check_build. Most users should
+not set this.
+
 ## Understanding results
 
 The results of CIFuzz can be found in two different places.
diff --git a/docs/getting-started/new_project_guide.md b/docs/getting-started/new_project_guide.md
index ea6b372..7ea668f 100644
--- a/docs/getting-started/new_project_guide.md
+++ b/docs/getting-started/new_project_guide.md
@@ -39,6 +39,9 @@
   [docker-cleanup](https://gist.github.com/mikea/d23a839cba68778d94e0302e8a2c200f)
   periodically to garbage-collect unused images.
 
+- (optional) [Install gsutil](https://cloud.google.com/storage/docs/gsutil_install) for local code coverage sanity check.
+  For Google internal (gLinux) machines, please refer [here](https://cloud.google.com/storage/docs/gsutil_install#deb) instead.
+
 ## Creating the file structure
 
 Each OSS-Fuzz project has a subdirectory
@@ -306,12 +309,7 @@
     ```
 
 4. We recommend taking a look at your code coverage as a sanity check to make sure that your
-fuzz targets get to the code you expect:
-
-    ```bash
-    $ python infra/helper.py build_fuzzers --sanitizer coverage $PROJECT_NAME
-    $ python infra/helper.py coverage $PROJECT_NAME <fuzz_target>
-    ```
+fuzz targets get to the code you expect. Please refer to [code coverage]({{ site.baseurl }}/advanced-topics/code-coverage/).
 
 **Note:** Currently, we only support AddressSanitizer (address) and UndefinedBehaviorSanitizer (undefined) 
 configurations. MemorySanitizer is recommended, but needs to be enabled manually once you verify
diff --git a/infra/base-images/base-builder/Dockerfile b/infra/base-images/base-builder/Dockerfile
index 578de9e..7e85009 100644
--- a/infra/base-images/base-builder/Dockerfile
+++ b/infra/base-images/base-builder/Dockerfile
@@ -15,14 +15,44 @@
 ################################################################################
 
 FROM gcr.io/oss-fuzz-base/base-clang
-RUN apt-get install -y git \
-    subversion \
-    jq \
-    python3 \
-    zip \
-    make \
-    binutils-dev \
-    libc6-dev-i386
+
+RUN apt-get update && \
+    apt-get install -y software-properties-common && \
+    add-apt-repository ppa:git-core/ppa && \
+    apt-get update && \
+    apt-get install -y \
+        binutils-dev \
+        build-essential \
+        curl \
+        git \
+        jq \
+        libc6-dev-i386 \
+        subversion \
+        zip
+
+# Build and install latest Python 3 (3.8.3).
+ENV PYTHON_VERSION 3.8.3
+RUN export PYTHON_DEPS="\
+        zlib1g-dev \
+        libncurses5-dev \
+        libgdbm-dev \
+        libnss3-dev \
+        libssl-dev \
+        libsqlite3-dev \
+        libreadline-dev \
+        libffi-dev \
+        libbz2-dev \
+        liblzma-dev" && \
+    apt-get install -y $PYTHON_DEPS && \
+    cd /tmp/ && \
+    curl -O https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.xz && \
+    tar -xvf Python-$PYTHON_VERSION.tar.xz && \
+    cd Python-$PYTHON_VERSION && \
+    ./configure --enable-optimizations && \
+    make -j install && \
+    cd .. && \
+    rm -r /tmp/Python-$PYTHON_VERSION.tar.xz /tmp/Python-$PYTHON_VERSION && \
+    apt-get remove -y $PYTHON_DEPS  # https://github.com/google/oss-fuzz/issues/3888
 
 # Download and install the latest stable Go.
 ADD https://storage.googleapis.com/golang/getgo/installer_linux $SRC/
@@ -41,10 +71,12 @@
 RUN go get -u github.com/mdempsky/go114-fuzz-build && \
     ln -s $GOPATH/bin/go114-fuzz-build $GOPATH/bin/go-fuzz
 
-# DEPRECATED go-fuzz implementation - github.com/dvyukov/go-fuzz-build based on
-# source-to-source transformation.
-RUN go get golang.org/x/tools/go/packages
-RUN go get github.com/dvyukov/go-fuzz/go-fuzz-build
+# Install Rust and cargo-fuzz for libFuzzer instrumentation.
+ENV CARGO_HOME=/rust
+ENV RUSTUP_HOME=/rust/rustup
+ENV PATH=$PATH:/rust/bin
+RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly
+RUN cargo install cargo-fuzz
 
 # Default build flags for various sanitizers.
 ENV SANITIZER_FLAGS_address "-fsanitize=address -fsanitize-address-use-after-scope"
diff --git a/infra/base-images/base-builder/compile b/infra/base-images/base-builder/compile
index 1a3d4f5..2a9876a 100755
--- a/infra/base-images/base-builder/compile
+++ b/infra/base-images/base-builder/compile
@@ -63,14 +63,29 @@
   export COVERAGE_FLAGS=
 fi
 
+# Rust does not support sanitizers and coverage flags via CFLAGS/CXXFLAGS, so
+# use RUSTFLAGS.
+# FIXME: Support code coverage once support is in.
+# See https://github.com/rust-lang/rust/issues/34701.
+if [ "$SANITIZER" != "undefined" ] && [ "$SANITIZER" != "coverage" ] && [ "$ARCHITECTURE" != 'i386' ]; then
+  export RUSTFLAGS="--cfg fuzzing -Zsanitizer=${SANITIZER} -Cdebuginfo=1 -Cforce-frame-pointers"
+else
+  export RUSTFLAGS="--cfg fuzzing -Cdebuginfo=1 -Cforce-frame-pointers"
+fi
+
+# Add Rust libfuzzer flags.
+# See https://github.com/rust-fuzz/libfuzzer/blob/master/build.rs#L12.
+export CUSTOM_LIBFUZZER_PATH="$LIB_FUZZING_ENGINE_DEPRECATED"
+export CUSTOM_LIBFUZZER_STD_CXX=c++
+
 export CFLAGS="$CFLAGS $SANITIZER_FLAGS $COVERAGE_FLAGS"
 export CXXFLAGS="$CFLAGS $CXXFLAGS_EXTRA"
 
+echo "---------------------------------------------------------------"
 echo "CC=$CC"
 echo "CXX=$CXX"
 echo "CFLAGS=$CFLAGS"
 echo "CXXFLAGS=$CXXFLAGS"
-
 echo "---------------------------------------------------------------"
 
 BUILD_CMD="bash -eux $SRC/build.sh"
diff --git a/infra/base-images/base-clang/checkout_build_install_llvm.sh b/infra/base-images/base-clang/checkout_build_install_llvm.sh
index 4a1963e..44e512b 100755
--- a/infra/base-images/base-clang/checkout_build_install_llvm.sh
+++ b/infra/base-images/base-clang/checkout_build_install_llvm.sh
@@ -48,19 +48,25 @@
 cd clang
 
 LLVM_SRC=$SRC/llvm-project
-OUR_LLVM_REVISION=e84b7a5fe230e42b8e6fe451369874a773bf1867  # For manual bumping.
-FORCE_OUR_REVISION=0  # To allow for manual downgrades.
+
+# For manual bumping.
+OUR_LLVM_REVISION=e84b7a5fe230e42b8e6fe451369874a773bf1867
+
+# To allow for manual downgrades. Set to 0 to use Chrome's clang version (i.e.
+# *not* force a manual downgrade). Set to 1 to force a manual downgrade.
+FORCE_OUR_REVISION=0
 LLVM_REVISION=$(grep -Po "CLANG_REVISION = '\K[a-f0-9]+(?=')" scripts/update.py)
 
 clone_with_retries https://github.com/llvm/llvm-project.git $LLVM_SRC
 
 set +e
-IS_OUR_REVISION_ANCESTOR=$(git -C $LLVM_SRC merge-base --is-ancestor $OUR_LLVM_REVISION $LLVM_REVISION)
+git -C $LLVM_SRC merge-base --is-ancestor $OUR_LLVM_REVISION $LLVM_REVISION
+IS_OUR_REVISION_ANCESTOR_RETCODE=$?
 set -e
 
-# Use our revision if specified or if our revision is a later revision than
-# Chrome's.
-if [ ! $IS_OUR_REVISION_ANCESTOR  ] || [ $FORCE_OUR_REVISION ] ; then
+# Use our revision if specified by FORCE_OUR_REVISION or if our revision is a
+# later revision than Chrome's (i.e. not an ancestor of Chrome's).
+if [ $IS_OUR_REVISION_ANCESTOR_RETCODE -ne 0 ] || [ $FORCE_OUR_REVISION -eq 1 ] ; then
   LLVM_REVISION=$OUR_LLVM_REVISION
 fi
 
diff --git a/infra/base-images/base-runner/Dockerfile b/infra/base-images/base-runner/Dockerfile
index ea29e1f..b35e567 100644
--- a/infra/base-images/base-runner/Dockerfile
+++ b/infra/base-images/base-runner/Dockerfile
@@ -58,8 +58,8 @@
 # Note that these match the settings used in ClusterFuzz and
 # shouldn't be changed unless a corresponding change is made on
 # ClusterFuzz side as well.
-ENV ASAN_OPTIONS="alloc_dealloc_mismatch=0:allocator_may_return_null=1:allocator_release_to_os_interval_ms=500:check_malloc_usable_size=0:detect_container_overflow=1:detect_odr_violation=0:detect_leaks=1:detect_stack_use_after_return=1:fast_unwind_on_fatal=0:handle_abort=1:handle_segv=1:handle_sigill=1:max_uar_stack_size_log=16:print_scariness=1:quarantine_size_mb=10:strict_memcmp=1:strip_path_prefix=/workspace/:symbolize=1:use_sigaltstack=1"
-ENV MSAN_OPTIONS="print_stats=1:strip_path_prefix=/workspace/:symbolize=1"
-ENV UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:silence_unsigned_overflow=1:strip_path_prefix=/workspace/:symbolize=1"
+ENV ASAN_OPTIONS="alloc_dealloc_mismatch=0:allocator_may_return_null=1:allocator_release_to_os_interval_ms=500:check_malloc_usable_size=0:detect_container_overflow=1:detect_odr_violation=0:detect_leaks=1:detect_stack_use_after_return=1:fast_unwind_on_fatal=0:handle_abort=1:handle_segv=1:handle_sigill=1:max_uar_stack_size_log=16:print_scariness=1:quarantine_size_mb=10:strict_memcmp=1:strip_path_prefix=/workspace/:symbolize=1:use_sigaltstack=1:dedup_token_length=3"
+ENV MSAN_OPTIONS="print_stats=1:strip_path_prefix=/workspace/:symbolize=1:dedup_token_length=3"
+ENV UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:silence_unsigned_overflow=1:strip_path_prefix=/workspace/:symbolize=1:dedup_token_length=3"
 ENV FUZZER_ARGS="-rss_limit_mb=2560 -timeout=25"
 ENV AFL_FUZZER_ARGS="-m none"
diff --git a/infra/base-images/base-runner/coverage b/infra/base-images/base-runner/coverage
index d2bd4dd..79dba62 100755
--- a/infra/base-images/base-runner/coverage
+++ b/infra/base-images/base-runner/coverage
@@ -63,6 +63,7 @@
   local profraw_file_mask="$DUMPS_DIR/$target.*.profraw"
   local profdata_file="$DUMPS_DIR/$target.profdata"
   local corpus_real="/corpus/${target}"
+  mkdir -p $corpus_real
 
   # -merge=1 requires an output directory, create a dummy dir for that.
   local corpus_dummy="$OUT/dummy_corpus_dir_for_${target}"
diff --git a/infra/base-images/base-runner/download_corpus b/infra/base-images/base-runner/download_corpus
index 1b7ebe8..05ea63a 100755
--- a/infra/base-images/base-runner/download_corpus
+++ b/infra/base-images/base-runner/download_corpus
@@ -22,7 +22,7 @@
 
 for pair in "$@"; do
   read path url <<< "$pair"
-  wget -q -O $path $url
+  wget -q -O $path $url || rm $path
 done
 
 # Always exit with 0 as we do not track wget return codes and should not rely
diff --git a/infra/bisector.py b/infra/bisector.py
index 7255384..ff8366d 100644
--- a/infra/bisector.py
+++ b/infra/bisector.py
@@ -37,6 +37,7 @@
 import json
 import logging
 import os
+import sys
 import tempfile
 
 import build_specified_commit
@@ -46,6 +47,25 @@
 
 Result = collections.namedtuple('Result', ['repo_url', 'commit'])
 
+START_MARKERS = [
+    '==ERROR',
+    '==WARNING',
+]
+
+END_MARKERS = [
+    'SUMMARY:',
+]
+
+DEDUP_TOKEN_MARKER = 'DEDUP_TOKEN:'
+
+
+class BisectError(Exception):
+  """Bisection error."""
+
+  def __init__(self, message, repo_url):
+    super().__init__(message)
+    self.repo_url = repo_url
+
 
 def main():
   """Finds the commit SHA where an error was initally introduced."""
@@ -74,6 +94,10 @@
   parser.add_argument('--sanitizer',
                       default='address',
                       help='The default is "address".')
+  parser.add_argument('--type',
+                      choices=['regressed', 'fixed'],
+                      help='The bisection type.',
+                      required=True)
   parser.add_argument('--architecture', default='x86_64')
   args = parser.parse_args()
 
@@ -82,8 +106,8 @@
                                                 sanitizer=args.sanitizer,
                                                 architecture=args.architecture)
 
-  result = bisect(args.old_commit, args.new_commit, args.test_case_path,
-                  args.fuzz_target, build_data)
+  result = bisect(args.type, args.old_commit, args.new_commit,
+                  args.test_case_path, args.fuzz_target, build_data)
   if not result.commit:
     logging.error('No error was found in commit range %s:%s', args.old_commit,
                   args.new_commit)
@@ -125,8 +149,57 @@
   return repo
 
 
-def _bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data):  # pylint: disable=too-many-locals
+def _get_dedup_token(output):
+  """Get dedup token."""
+  for line in output.splitlines():
+    token_location = line.find(DEDUP_TOKEN_MARKER)
+    if token_location == -1:
+      continue
+
+    return line[token_location + len(DEDUP_TOKEN_MARKER):].strip()
+
+  return None
+
+
+def _check_for_crash(project_name, fuzz_target, test_case_path):
+  """Check for crash."""
+
+  def docker_run(args):
+    command = ['docker', 'run', '--rm', '--privileged']
+    if sys.stdin.isatty():
+      command.append('-i')
+
+    return utils.execute(command + args)
+
+  logging.info('Checking for crash')
+  out, err, return_code = helper.reproduce_impl(project_name,
+                                                fuzz_target,
+                                                False, [], [],
+                                                test_case_path,
+                                                runner=docker_run,
+                                                err_result=(None, None, None))
+  if return_code is None:
+    return None
+
+  logging.info('stdout =\n%s', out)
+  logging.info('stderr =\n%s', err)
+
+  # pylint: disable=unsupported-membership-test
+  has_start_marker = any(
+      marker in out or marker in err for marker in START_MARKERS)
+  has_end_marker = any(marker in out or marker in err for marker in END_MARKERS)
+  if not has_start_marker or not has_end_marker:
+    return None
+
+  return _get_dedup_token(out + err)
+
+
+# pylint: disable=too-many-locals
+# pylint: disable=too-many-arguments
+def _bisect(bisect_type, old_commit, new_commit, test_case_path, fuzz_target,
+            build_data):
   """Perform the bisect."""
+  # pylint: disable=too-many-branches
   base_builder_repo = _load_base_builder_repo()
 
   with tempfile.TemporaryDirectory() as tmp_dir:
@@ -153,11 +226,22 @@
         host_src_dir,
         build_data,
         base_builder_repo=base_builder_repo):
-      raise RuntimeError('Failed to build new_commit')
+      raise BisectError('Failed to build new_commit', repo_url)
 
-    expected_error_code = helper.reproduce_impl(build_data.project_name,
-                                                fuzz_target, False, [], [],
-                                                test_case_path)
+    if bisect_type == 'fixed':
+      should_crash = False
+    elif bisect_type == 'regressed':
+      should_crash = True
+    else:
+      raise BisectError('Invalid bisect type ' + bisect_type, repo_url)
+
+    expected_error = _check_for_crash(build_data.project_name, fuzz_target,
+                                      test_case_path)
+    logging.info('new_commit result = %s', expected_error)
+
+    if not should_crash and expected_error:
+      logging.warning('new_commit crashed but not shouldn\'t. '
+                      'Continuing to see if stack changes.')
 
     # Check if the error is persistent through the commit range
     if old_commit:
@@ -168,12 +252,11 @@
           host_src_dir,
           build_data,
           base_builder_repo=base_builder_repo):
-        raise RuntimeError('Failed to build old_commit')
+        raise BisectError('Failed to build old_commit', repo_url)
 
-      if expected_error_code == helper.reproduce_impl(build_data.project_name,
-                                                      fuzz_target, False, [],
-                                                      [], test_case_path):
-        raise RuntimeError('old_commit had same result as new_commit')
+      if _check_for_crash(build_data.project_name, fuzz_target,
+                          test_case_path) == expected_error:
+        raise BisectError('old_commit had same result as new_commit', repo_url)
 
     while old_idx - new_idx > 1:
       curr_idx = (old_idx + new_idx) // 2
@@ -190,20 +273,25 @@
         old_idx = curr_idx
         continue
 
-      error_code = helper.reproduce_impl(build_data.project_name, fuzz_target,
-                                         False, [], [], test_case_path)
-      if expected_error_code == error_code:
+      current_error = _check_for_crash(build_data.project_name, fuzz_target,
+                                       test_case_path)
+      logging.info('Current result = %s', current_error)
+      if expected_error == current_error:
         new_idx = curr_idx
       else:
         old_idx = curr_idx
     return Result(repo_url, commit_list[new_idx])
 
 
-def bisect(old_commit, new_commit, test_case_path, fuzz_target, build_data):  # pylint: disable=too-many-locals
+# pylint: disable=too-many-locals
+# pylint: disable=too-many-arguments
+def bisect(bisect_type, old_commit, new_commit, test_case_path, fuzz_target,
+           build_data):
   """From a commit range, this function caluclates which introduced a
   specific error from a fuzz test_case_path.
 
   Args:
+    bisect_type: The type of the bisect ('regressed' or 'fixed').
     old_commit: The oldest commit in the error regression range.
     new_commit: The newest commit in the error regression range.
     test_case_path: The file path of the test case that triggers the error
@@ -216,16 +304,15 @@
   Raises:
     ValueError: when a repo url can't be determine from the project.
   """
-  result = _bisect(old_commit, new_commit, test_case_path, fuzz_target,
-                   build_data)
-
-  # Clean up projects/ as _bisect may have modified it.
-  oss_fuzz_repo_manager = repo_manager.BaseRepoManager(helper.OSS_FUZZ_DIR)
-  oss_fuzz_repo_manager.git(['reset', 'projects'])
-  oss_fuzz_repo_manager.git(['checkout', 'projects'])
-  oss_fuzz_repo_manager.git(['clean', '-fxd', 'projects'])
-
-  return result
+  try:
+    return _bisect(bisect_type, old_commit, new_commit, test_case_path,
+                   fuzz_target, build_data)
+  finally:
+    # Clean up projects/ as _bisect may have modified it.
+    oss_fuzz_repo_manager = repo_manager.BaseRepoManager(helper.OSS_FUZZ_DIR)
+    oss_fuzz_repo_manager.git(['reset', 'projects'])
+    oss_fuzz_repo_manager.git(['checkout', 'projects'])
+    oss_fuzz_repo_manager.git(['clean', '-fxd', 'projects'])
 
 
 if __name__ == '__main__':
diff --git a/infra/build_specified_commit.py b/infra/build_specified_commit.py
index 9a1605a..72c3bad 100644
--- a/infra/build_specified_commit.py
+++ b/infra/build_specified_commit.py
@@ -22,6 +22,8 @@
 import collections
 import logging
 import re
+import shutil
+import time
 
 import helper
 import repo_manager
@@ -31,6 +33,8 @@
     'BuildData', ['project_name', 'engine', 'sanitizer', 'architecture'])
 
 _GIT_DIR_MARKER = 'gitdir: '
+_IMAGE_BUILD_TRIES = 3
+_IMAGE_BUILD_RETRY_SLEEP = 30.0
 
 
 class BaseBuilderRepo:
@@ -54,6 +58,34 @@
     raise ValueError('Failed to find suitable base-builder.')
 
 
+def _replace_gitdir(src_dir, file_path):
+  """Replace gitdir with a relative path."""
+  with open(file_path) as handle:
+    lines = handle.readlines()
+
+  new_lines = []
+  for line in lines:
+    if line.startswith(_GIT_DIR_MARKER):
+      absolute_path = line[len(_GIT_DIR_MARKER):].strip()
+      if not os.path.isabs(absolute_path):
+        # Already relative.
+        return
+
+      current_dir = os.path.dirname(file_path)
+      # Rebase to /src rather than the host src dir.
+      base_dir = current_dir.replace(src_dir, '/src')
+      relative_path = os.path.relpath(absolute_path, base_dir)
+      logging.info('Replacing absolute submodule gitdir from %s to %s',
+                   absolute_path, relative_path)
+
+      line = _GIT_DIR_MARKER + relative_path
+
+    new_lines.append(line)
+
+  with open(file_path, 'w') as handle:
+    handle.write(''.join(new_lines))
+
+
 def _make_gitdirs_relative(src_dir):
   """Make gitdirs relative."""
   for root_dir, _, files in os.walk(src_dir):
@@ -62,26 +94,7 @@
         continue
 
       file_path = os.path.join(root_dir, filename)
-      with open(file_path) as handle:
-        lines = handle.readlines()
-
-      new_lines = []
-      for line in lines:
-        if line.startswith(_GIT_DIR_MARKER):
-          absolute_path = line[len(_GIT_DIR_MARKER):].strip()
-          current_dir = os.path.dirname(file_path)
-          # Rebase to /src rather than the host src dir.
-          base_dir = current_dir.replace(src_dir, '/src')
-          relative_path = os.path.relpath(absolute_path, base_dir)
-          logging.info('Replacing absolute submodule gitdir from %s to %s',
-                       absolute_path, relative_path)
-
-          line = _GIT_DIR_MARKER + relative_path
-
-        new_lines.append(line)
-
-      with open(file_path, 'w') as handle:
-        handle.write(''.join(new_lines))
+      _replace_gitdir(src_dir, file_path)
 
 
 def _replace_base_builder_digest(dockerfile_path, digest):
@@ -104,13 +117,17 @@
   """Copy /src from docker to the host."""
   # Copy /src to host.
   image_name = 'gcr.io/oss-fuzz/' + project_name
+  src_dir = os.path.join(host_dir, 'src')
+  if os.path.exists(src_dir):
+    shutil.rmtree(src_dir, ignore_errors=True)
+
   docker_args = [
       '-v',
       host_dir + ':/out',
       image_name,
-      'rsync',
-      '-az',
-      '--delete',
+      'cp',
+      '-r',
+      '-p',
       '/src',
       '/out',
   ]
@@ -118,12 +135,23 @@
 
   # Submodules can have gitdir entries which point to absolute paths. Make them
   # relative, as otherwise we can't do operations on the checkout on the host.
-  src_dir = os.path.join(host_dir, 'src')
   _make_gitdirs_relative(src_dir)
-
   return src_dir
 
 
+def _build_image_with_retries(project_name):
+  """Build image with retries."""
+
+  for _ in range(_IMAGE_BUILD_TRIES):
+    result = helper.build_image_impl(project_name)
+    if result:
+      return result
+
+    time.sleep(_IMAGE_BUILD_RETRY_SLEEP)
+
+  return result
+
+
 def build_fuzzers_from_commit(commit,
                               build_repo_manager,
                               host_src_path,
@@ -192,7 +220,7 @@
                                    base_builder_digest)
 
     # Rebuild image and re-copy src dir since things in /src could have changed.
-    if not helper.build_image_impl(build_data.project_name):
+    if not _build_image_with_retries(build_data.project_name):
       raise RuntimeError('Failed to rebuild image.')
 
     cleanup()
@@ -226,7 +254,7 @@
 
   # Change to oss-fuzz main directory so helper.py runs correctly.
   utils.chdir_to_root()
-  if not helper.build_image_impl(project_name):
+  if not _build_image_with_retries(project_name):
     logging.error('Error: building %s image failed.', project_name)
     return None, None
   docker_image_name = 'gcr.io/oss-fuzz/' + project_name
diff --git a/infra/cifuzz/actions/build_fuzzers/action.yml b/infra/cifuzz/actions/build_fuzzers/action.yml
index e9fb31e..4c19018 100644
--- a/infra/cifuzz/actions/build_fuzzers/action.yml
+++ b/infra/cifuzz/actions/build_fuzzers/action.yml
@@ -8,9 +8,13 @@
   dry-run:
     description: 'If set, run the action without actually reporting a failure.'
     default: false
+  allowed-broken-targets-percentage:
+    description: 'The percentage of broken targets allowed in bad_build_check.'
+    required: false
 runs:
   using: 'docker'
   image: 'Dockerfile'
   env:
     OSS_FUZZ_PROJECT_NAME: ${{ inputs.oss-fuzz-project-name }}
     DRY_RUN: ${{ inputs.dry-run}}
+    ALLOWED_BROKEN_TARGETS_PERCENTAGE: ${{ inputs.allowed-broken-targets-percentage}}
diff --git a/infra/cifuzz/actions/build_fuzzers/build_fuzzers_entrypoint.py b/infra/cifuzz/actions/build_fuzzers/build_fuzzers_entrypoint.py
index 3c84e64..c203068 100644
--- a/infra/cifuzz/actions/build_fuzzers/build_fuzzers_entrypoint.py
+++ b/infra/cifuzz/actions/build_fuzzers/build_fuzzers_entrypoint.py
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 """Builds and runs specific OSS-Fuzz project's fuzzers for CI tools."""
+import json
 import logging
 import os
 import sys
@@ -40,8 +41,10 @@
     OSS_FUZZ_PROJECT_NAME: The name of OSS-Fuzz project.
     GITHUB_REPOSITORY: The name of the Github repo that called this script.
     GITHUB_SHA: The commit SHA that triggered this script.
-    GITHUB_REF: The pull request reference that triggered this script.
     GITHUB_EVENT_NAME: The name of the hook event that triggered this script.
+    GITHUB_EVENT_PATH:
+      The path to the file containing the POST payload of the webhook:
+      https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners
     GITHUB_WORKSPACE: The shared volume directory where input artifacts are.
 
   Returns:
@@ -49,7 +52,6 @@
   """
   oss_fuzz_project_name = os.environ.get('OSS_FUZZ_PROJECT_NAME')
   github_repo_name = os.path.basename(os.environ.get('GITHUB_REPOSITORY'))
-  pr_ref = os.environ.get('GITHUB_REF')
   commit_sha = os.environ.get('GITHUB_SHA')
   event = os.environ.get('GITHUB_EVENT_NAME')
   workspace = os.environ.get('GITHUB_WORKSPACE')
@@ -73,11 +75,16 @@
     logging.error('Error building fuzzers for project %s with commit %s.',
                   oss_fuzz_project_name, commit_sha)
     return returncode
-  if event == 'pull_request' and not cifuzz.build_fuzzers(
-      oss_fuzz_project_name, github_repo_name, workspace, pr_ref=pr_ref):
-    logging.error('Error building fuzzers for project %s with pull request %s.',
-                  oss_fuzz_project_name, pr_ref)
-    return returncode
+  if event == 'pull_request':
+    with open(os.environ.get('GITHUB_EVENT_PATH'), encoding='utf-8') as file:
+      event = json.load(file)
+      pr_ref = 'refs/pull/{0}/merge'.format(event['pull_request']['number'])
+      if not cifuzz.build_fuzzers(
+          oss_fuzz_project_name, github_repo_name, workspace, pr_ref=pr_ref):
+        logging.error(
+            'Error building fuzzers for project %s with pull request %s.',
+            oss_fuzz_project_name, pr_ref)
+        return returncode
   out_dir = os.path.join(workspace, 'out')
   if cifuzz.check_fuzzer_build(out_dir):
     return 0
diff --git a/infra/cifuzz/cifuzz.py b/infra/cifuzz/cifuzz.py
index b10660d..2733dd1 100644
--- a/infra/cifuzz/cifuzz.py
+++ b/infra/cifuzz/cifuzz.py
@@ -136,9 +136,16 @@
 
   # Build Fuzzers using docker run.
   command = [
-      '--cap-add', 'SYS_PTRACE', '-e', 'FUZZING_ENGINE=' + DEFAULT_ENGINE, '-e',
-      'SANITIZER=' + DEFAULT_SANITIZER, '-e',
-      'ARCHITECTURE=' + DEFAULT_ARCHITECTURE
+      '--cap-add',
+      'SYS_PTRACE',
+      '-e',
+      'FUZZING_ENGINE=' + DEFAULT_ENGINE,
+      '-e',
+      'SANITIZER=' + DEFAULT_SANITIZER,
+      '-e',
+      'ARCHITECTURE=' + DEFAULT_ARCHITECTURE,
+      '-e',
+      'FUZZING_LANGUAGE=c++',  # FIXME: Add proper support.
   ]
   container = utils.get_container_name()
   if container:
@@ -244,10 +251,26 @@
     return False
 
   command = [
-      '--cap-add', 'SYS_PTRACE', '-e', 'FUZZING_ENGINE=' + DEFAULT_ENGINE, '-e',
-      'SANITIZER=' + DEFAULT_SANITIZER, '-e',
-      'ARCHITECTURE=' + DEFAULT_ARCHITECTURE
+      '--cap-add',
+      'SYS_PTRACE',
+      '-e',
+      'FUZZING_ENGINE=' + DEFAULT_ENGINE,
+      '-e',
+      'SANITIZER=' + DEFAULT_SANITIZER,
+      '-e',
+      'ARCHITECTURE=' + DEFAULT_ARCHITECTURE,
   ]
+
+  # Set ALLOWED_BROKEN_TARGETS_PERCENTAGE in docker if specified by user.
+  allowed_broken_targets_percentage = os.getenv(
+      'ALLOWED_BROKEN_TARGETS_PERCENTAGE')
+  if allowed_broken_targets_percentage is not None:
+    command += [
+        '-e',
+        ('ALLOWED_BROKEN_TARGETS_PERCENTAGE=' +
+         allowed_broken_targets_percentage)
+    ]
+
   container = utils.get_container_name()
   if container:
     command += ['-e', 'OUT=' + out_dir, '--volumes-from', container]
diff --git a/infra/cifuzz/cifuzz_test.py b/infra/cifuzz/cifuzz_test.py
index 8a792ff..d76756f 100644
--- a/infra/cifuzz/cifuzz_test.py
+++ b/infra/cifuzz/cifuzz_test.py
@@ -22,7 +22,7 @@
 import sys
 import tempfile
 import unittest
-import unittest.mock
+from unittest import mock
 
 # pylint: disable=wrong-import-position
 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -50,6 +50,8 @@
 # A fuzzer to be built in build_fuzzers integration tests.
 EXAMPLE_BUILD_FUZZER = 'do_stuff_fuzzer'
 
+# pylint: disable=no-self-use
+
 
 class BuildFuzzersIntegrationTest(unittest.TestCase):
   """Test build_fuzzers function in the utils module."""
@@ -153,9 +155,9 @@
     # Set the first return value to True, then the second to False to
     # emulate a bug existing in the current PR but not on the downloaded
     # OSS-Fuzz build.
-    with unittest.mock.patch.object(fuzz_target.FuzzTarget,
-                                    'is_reproducible',
-                                    side_effect=[True, False]):
+    with mock.patch.object(fuzz_target.FuzzTarget,
+                           'is_reproducible',
+                           side_effect=[True, False]):
       run_success, bug_found = cifuzz.run_fuzzers(10, TEST_FILES_PATH,
                                                   EXAMPLE_PROJECT)
       build_dir = os.path.join(TEST_FILES_PATH, 'out', 'oss_fuzz_latest')
@@ -166,9 +168,9 @@
 
   def test_old_bug_found(self):
     """Test run_fuzzers with a bug found in OSS-Fuzz before."""
-    with unittest.mock.patch.object(fuzz_target.FuzzTarget,
-                                    'is_reproducible',
-                                    side_effect=[True, True]):
+    with mock.patch.object(fuzz_target.FuzzTarget,
+                           'is_reproducible',
+                           side_effect=[True, True]):
       run_success, bug_found = cifuzz.run_fuzzers(10, TEST_FILES_PATH,
                                                   EXAMPLE_PROJECT)
       build_dir = os.path.join(TEST_FILES_PATH, 'out', 'oss_fuzz_latest')
@@ -247,6 +249,17 @@
     """Checks a directory that exists but does not have fuzzers is False."""
     self.assertFalse(cifuzz.check_fuzzer_build(TEST_FILES_PATH))
 
+  @mock.patch.dict(os.environ, {'ALLOWED_BROKEN_TARGETS_PERCENTAGE': '0'})
+  @mock.patch('helper.docker_run')
+  def test_allow_broken_fuzz_targets_percentage(self, mocked_docker_run):
+    """Tests that ALLOWED_BROKEN_TARGETS_PERCENTAGE is set when running
+    docker if it is set in the environment."""
+    test_fuzzer_dir = os.path.join(TEST_FILES_PATH, 'out')
+    mocked_docker_run.return_value = 0
+    cifuzz.check_fuzzer_build(test_fuzzer_dir)
+    self.assertIn('-e ALLOWED_BROKEN_TARGETS_PERCENTAGE=0',
+                  ' '.join(mocked_docker_run.call_args[0][0]))
+
 
 class GetFilesCoveredByTargetUnitTest(unittest.TestCase):
   """Test to get the files covered by a fuzz target in the cifuzz module."""
@@ -267,10 +280,9 @@
   def test_valid_target(self):
     """Tests that covered files can be retrieved from a coverage report."""
 
-    with unittest.mock.patch.object(
-        cifuzz,
-        'get_target_coverage_report',
-        return_value=self.fuzzer_cov_report_example):
+    with mock.patch.object(cifuzz,
+                           'get_target_coverage_report',
+                           return_value=self.fuzzer_cov_report_example):
       file_list = cifuzz.get_files_covered_by_target(
           self.proj_cov_report_example, self.example_fuzzer, '/src/curl')
 
@@ -311,9 +323,8 @@
 
   def test_valid_target(self):
     """Test a target's coverage report can be downloaded and parsed."""
-    with unittest.mock.patch.object(cifuzz,
-                                    'get_json_from_url',
-                                    return_value='{}') as mock_get_json:
+    with mock.patch.object(cifuzz, 'get_json_from_url',
+                           return_value='{}') as mock_get_json:
       cifuzz.get_target_coverage_report(self.cov_exmp, self.example_fuzzer)
       (url,), _ = mock_get_json.call_args
       self.assertEqual(
@@ -345,9 +356,8 @@
     NOTE: This test relies on the test_project repo's coverage report.
     Example was not used because it has no coverage reports.
     """
-    with unittest.mock.patch.object(cifuzz,
-                                    'get_json_from_url',
-                                    return_value='{}') as mock_fun:
+    with mock.patch.object(cifuzz, 'get_json_from_url',
+                           return_value='{}') as mock_fun:
 
       cifuzz.get_latest_cov_report_info(self.test_project)
       (url,), _ = mock_fun.call_args
@@ -370,52 +380,51 @@
 
   def test_keeping_fuzzer_w_no_coverage(self):
     """Tests that a specific fuzzer is kept if it is deemed affected."""
-    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
+    with tempfile.TemporaryDirectory() as tmp_dir, mock.patch.object(
         cifuzz, 'get_latest_cov_report_info', return_value=1):
       shutil.copy(self.test_fuzzer_1, tmp_dir)
       shutil.copy(self.test_fuzzer_2, tmp_dir)
-      with unittest.mock.patch.object(cifuzz,
-                                      'get_files_covered_by_target',
-                                      side_effect=[[self.example_file_changed],
-                                                   None]):
+      with mock.patch.object(cifuzz,
+                             'get_files_covered_by_target',
+                             side_effect=[[self.example_file_changed], None]):
         cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
                                          [self.example_file_changed], '')
         self.assertEqual(2, len(os.listdir(tmp_dir)))
 
   def test_keeping_specific_fuzzer(self):
     """Tests that a specific fuzzer is kept if it is deemed affected."""
-    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
+    with tempfile.TemporaryDirectory() as tmp_dir, mock.patch.object(
         cifuzz, 'get_latest_cov_report_info', return_value=1):
       shutil.copy(self.test_fuzzer_1, tmp_dir)
       shutil.copy(self.test_fuzzer_2, tmp_dir)
-      with unittest.mock.patch.object(cifuzz,
-                                      'get_files_covered_by_target',
-                                      side_effect=[[self.example_file_changed],
-                                                   ['not/a/real/file']]):
+      with mock.patch.object(cifuzz,
+                             'get_files_covered_by_target',
+                             side_effect=[[self.example_file_changed],
+                                          ['not/a/real/file']]):
         cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
                                          [self.example_file_changed], '')
         self.assertEqual(1, len(os.listdir(tmp_dir)))
 
   def test_no_fuzzers_kept_fuzzer(self):
     """Tests that if there is no affected then all fuzzers are kept."""
-    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
+    with tempfile.TemporaryDirectory() as tmp_dir, mock.patch.object(
         cifuzz, 'get_latest_cov_report_info', return_value=1):
       shutil.copy(self.test_fuzzer_1, tmp_dir)
       shutil.copy(self.test_fuzzer_2, tmp_dir)
-      with unittest.mock.patch.object(cifuzz,
-                                      'get_files_covered_by_target',
-                                      side_effect=[None, None]):
+      with mock.patch.object(cifuzz,
+                             'get_files_covered_by_target',
+                             side_effect=[None, None]):
         cifuzz.remove_unaffected_fuzzers(EXAMPLE_PROJECT, tmp_dir,
                                          [self.example_file_changed], '')
         self.assertEqual(2, len(os.listdir(tmp_dir)))
 
   def test_both_fuzzers_kept_fuzzer(self):
     """Tests that if both fuzzers are affected then both fuzzers are kept."""
-    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
+    with tempfile.TemporaryDirectory() as tmp_dir, mock.patch.object(
         cifuzz, 'get_latest_cov_report_info', return_value=1):
       shutil.copy(self.test_fuzzer_1, tmp_dir)
       shutil.copy(self.test_fuzzer_2, tmp_dir)
-      with unittest.mock.patch.object(
+      with mock.patch.object(
           cifuzz,
           'get_files_covered_by_target',
           side_effect=[self.example_file_changed, self.example_file_changed]):
diff --git a/infra/cifuzz/fuzz_target.py b/infra/cifuzz/fuzz_target.py
index 85fdbdc..d32322a 100644
--- a/infra/cifuzz/fuzz_target.py
+++ b/infra/cifuzz/fuzz_target.py
@@ -57,9 +57,20 @@
 # The number of reproduce attempts for a crash.
 REPRODUCE_ATTEMPTS = 10
 
-# Seconds on top of duration till a timeout error is raised.
+# Seconds on top of duration until a timeout error is raised.
 BUFFER_TIME = 10
 
+# Log message for is_crash_reportable if it can't check if crash repros
+# on OSS-Fuzz build.
+COULD_NOT_TEST_ON_OSS_FUZZ_MESSAGE = (
+    'Crash is reproducible. Could not run OSS-Fuzz build of '
+    'target to determine if this pull request introduced crash. '
+    'Assuming this pull request introduced crash.')
+
+
+class ReproduceError(Exception):
+  """Error for when we can't attempt to reproduce a crash."""
+
 
 class FuzzTarget:
   """A class to manage a single fuzz target.
@@ -134,20 +145,20 @@
       logging.error('Fuzzer %s timed out, ending fuzzing.', self.target_name)
       return None, None
 
-    # Libfuzzer timeout has been reached.
+    # Libfuzzer timeout was reached.
     if not process.returncode:
       logging.info('Fuzzer %s finished with no crashes discovered.',
                    self.target_name)
       return None, None
 
-    # Crash has been discovered.
+    # Crash was discovered.
     logging.info('Fuzzer %s, ended before timeout.', self.target_name)
     err_str = err.decode('ascii')
     test_case = self.get_test_case(err_str)
     if not test_case:
       logging.error('No test case found in stack trace: %s.', err_str)
       return None, None
-    if self.check_reproducibility_and_regression(test_case):
+    if self.is_crash_reportable(test_case):
       return test_case, err_str
     return None, None
 
@@ -159,24 +170,30 @@
         target_path: The path to the fuzz target to be tested
 
       Returns:
-        True if crash is reproducible.
-    """
-    if not os.path.exists(test_case):
-      logging.error('Test case %s is not found.', test_case)
-      return False
-    if os.path.exists(target_path):
-      os.chmod(os.path.join(target_path, self.target_name), stat.S_IRWXO)
+        True if crash is reproducible and we were able to run the
+        binary.
 
+      Raises:
+        ReproduceError if we can't attempt to reproduce the crash.
+    """
+
+    if not os.path.exists(target_path):
+      raise ReproduceError('Target %s not found.' % target_path)
+
+    os.chmod(target_path, stat.S_IRWXO)
+
+    target_dirname = os.path.dirname(target_path)
     command = ['docker', 'run', '--rm', '--privileged']
     container = utils.get_container_name()
     if container:
       command += [
-          '--volumes-from', container, '-e', 'OUT=' + target_path, '-e',
+          '--volumes-from', container, '-e', 'OUT=' + target_dirname, '-e',
           'TESTCASE=' + test_case
       ]
     else:
       command += [
-          '-v', '%s:/out' % target_path, '-v',
+          '-v',
+          '%s:/out' % target_dirname, '-v',
           '%s:/testcase' % test_case
       ]
 
@@ -187,14 +204,21 @@
 
     logging.info('Running reproduce command: %s.', ' '.join(command))
     for _ in range(REPRODUCE_ATTEMPTS):
-      _, _, err_code = utils.execute(command)
-      if err_code:
+      _, _, returncode = utils.execute(command)
+      if returncode != 0:
+        logging.info('Reproduce command returned: %s. Reproducible on %s.',
+                     returncode, target_path)
+
         return True
+
+    logging.info('Reproduce command returned 0. Not reproducible on %s.',
+                 target_path)
     return False
 
-  def check_reproducibility_and_regression(self, test_case):
-    """Checks if a crash is reproducible, and if it is, whether it's a new
-    regression that cannot be reproduced with the latest OSS-Fuzz build.
+  def is_crash_reportable(self, test_case):
+    """Returns True if a crash is reportable. This means the crash is
+    reproducible but not reproducible on a build from OSS-Fuzz (meaning the
+    crash was introduced by this PR).
 
     NOTE: If no project is specified the crash is assumed introduced
     by the pull request if it is reproducible.
@@ -204,28 +228,52 @@
 
     Returns:
       True if the crash was introduced by the current pull request.
-    """
-    reproducible_in_pr = self.is_reproducible(test_case,
-                                              os.path.dirname(self.target_path))
-    if not self.project_name:
-      return reproducible_in_pr
 
-    if not reproducible_in_pr:
+    Raises:
+      ReproduceError if we can't attempt to reproduce the crash on the PR build.
+    """
+    if not os.path.exists(test_case):
+      raise ReproduceError('Test case %s not found.' % test_case)
+
+    try:
+      reproducible_on_pr_build = self.is_reproducible(test_case,
+                                                      self.target_path)
+    except ReproduceError as error:
+      logging.error('Could not run target when checking for reproducibility.'
+                    'Please file an issue:'
+                    'https://github.com/google/oss-fuzz/issues/new.')
+      raise error
+
+    if not self.project_name:
+      return reproducible_on_pr_build
+
+    if not reproducible_on_pr_build:
       logging.info(
           'Failed to reproduce the crash using the obtained test case.')
       return False
 
     oss_fuzz_build_dir = self.download_oss_fuzz_build()
     if not oss_fuzz_build_dir:
-      return False
-
-    reproducible_in_oss_fuzz = self.is_reproducible(test_case,
-                                                    oss_fuzz_build_dir)
-
-    if reproducible_in_pr and not reproducible_in_oss_fuzz:
-      logging.info('The crash is reproducible. The crash doesn\'t reproduce ' \
-      'on old builds. This pull request probably introduced the crash.')
+      # Crash is reproducible on PR build and we can't test on OSS-Fuzz build.
+      logging.info(COULD_NOT_TEST_ON_OSS_FUZZ_MESSAGE)
       return True
+
+    oss_fuzz_target_path = os.path.join(oss_fuzz_build_dir, self.target_name)
+    try:
+      reproducible_on_oss_fuzz_build = self.is_reproducible(
+          test_case, oss_fuzz_target_path)
+    except ReproduceError:
+      # This happens if the project has OSS-Fuzz builds, but the fuzz target
+      # is not in it (e.g. because the fuzz target is new).
+      logging.info(COULD_NOT_TEST_ON_OSS_FUZZ_MESSAGE)
+      return True
+
+    if not reproducible_on_oss_fuzz_build:
+      logging.info('The crash is reproducible. The crash doesn\'t reproduce '
+                   'on old builds. This pull request probably introduced the '
+                   'crash.')
+      return True
+
     logging.info('The crash is reproducible without the current pull request.')
     return False
 
@@ -347,13 +395,13 @@
   return out_dir
 
 
-def url_join(*argv):
+def url_join(*url_parts):
   """Joins URLs together using the posix join method.
 
   Args:
-    argv: Sections of a URL to be joined.
+    url_parts: Sections of a URL to be joined.
 
   Returns:
     Joined URL.
   """
-  return posixpath.join(*argv)
+  return posixpath.join(*url_parts)
diff --git a/infra/cifuzz/fuzz_target_test.py b/infra/cifuzz/fuzz_target_test.py
index 6805274..04aac4c 100644
--- a/infra/cifuzz/fuzz_target_test.py
+++ b/infra/cifuzz/fuzz_target_test.py
@@ -18,7 +18,9 @@
 import tempfile
 import unittest
 import unittest.mock
-import urllib
+
+import parameterized
+from pyfakefs import fake_filesystem_unittest
 
 # Pylint has issue importing utils which is why error suppression is required.
 # pylint: disable=wrong-import-position
@@ -26,8 +28,6 @@
 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 import fuzz_target
 
-import utils
-
 # NOTE: This integration test relies on
 # https://github.com/google/oss-fuzz/tree/master/projects/example project.
 EXAMPLE_PROJECT = 'example'
@@ -35,45 +35,80 @@
 # An example fuzzer that triggers an error.
 EXAMPLE_FUZZER = 'example_crash_fuzzer'
 
-# Location of files used for testing.
-TEST_FILES_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),
-                               'test_files')
+# The return value of a successful call to utils.execute.
+EXECUTE_SUCCESS_RETVAL = ('', '', 0)
+
+# The return value of a failed call to utils.execute.
+EXECUTE_FAILURE_RETVAL = ('', '', 1)
 
 
-class IsReproducibleUnitTest(unittest.TestCase):
-  """Test is_reproducible function in the fuzz_target module."""
+# TODO(metzman): Use patch from test_libs/helpers.py in clusterfuzz so that we
+# don't need to accept this as an argument in every test method.
+@unittest.mock.patch('utils.get_container_name', return_value='container')
+class IsReproducibleUnitTest(fake_filesystem_unittest.TestCase):
+  """Tests the is_reproducible method in the fuzz_target.FuzzTarget class."""
 
   def setUp(self):
     """Sets up dummy fuzz target to test is_reproducible method."""
-    self.test_target = fuzz_target.FuzzTarget('/example/path', 10,
+    self.fuzz_target_path = '/example/path'
+    self.testcase_path = '/testcase'
+    self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path,
+                                              fuzz_target.REPRODUCE_ATTEMPTS,
                                               '/example/outdir')
 
-  def test_with_reproducible(self):
-    """Tests that a is_reproducible will return true if crash is detected."""
-    test_all_success = [(0, 0, 1)] * 10
-    with unittest.mock.patch.object(utils,
-                                    'execute',
-                                    side_effect=test_all_success) as patch:
-      self.assertTrue(
-          self.test_target.is_reproducible(TEST_FILES_PATH, '/not/exist'))
-      self.assertEqual(1, patch.call_count)
+  def test_reproducible(self, _):
+    """Tests that is_reproducible returns True if crash is detected and that
+    is_reproducible uses the correct command to reproduce a crash."""
+    self._set_up_fakefs()
+    all_repro = [EXECUTE_FAILURE_RETVAL] * fuzz_target.REPRODUCE_ATTEMPTS
+    with unittest.mock.patch('utils.execute',
+                             side_effect=all_repro) as mocked_execute:
+      result = self.test_target.is_reproducible(self.testcase_path,
+                                                self.fuzz_target_path)
+      mocked_execute.assert_called_once_with([
+          'docker', 'run', '--rm', '--privileged', '--volumes-from',
+          'container', '-e', 'OUT=/example', '-e',
+          'TESTCASE=' + self.testcase_path, '-t',
+          'gcr.io/oss-fuzz-base/base-runner', 'reproduce', 'path', '-runs=100'
+      ])
+      self.assertTrue(result)
+      self.assertEqual(1, mocked_execute.call_count)
 
-    test_one_success = [(0, 0, 0)] * 9 + [(0, 0, 1)]
-    with unittest.mock.patch.object(utils,
-                                    'execute',
-                                    side_effect=test_one_success) as patch:
-      self.assertTrue(
-          self.test_target.is_reproducible(TEST_FILES_PATH, '/not/exist'))
-      self.assertEqual(10, patch.call_count)
+  def _set_up_fakefs(self):
+    """Helper to setup pyfakefs and add important files to the fake
+    filesystem."""
+    self.setUpPyfakefs()
+    self.fs.create_file(self.fuzz_target_path)
+    self.fs.create_file(self.testcase_path)
 
-  def test_with_not_reproducible(self):
-    """Tests that a is_reproducible will return False if crash not detected."""
-    test_all_fail = [(0, 0, 0)] * 10
-    with unittest.mock.patch.object(utils, 'execute',
-                                    side_effect=test_all_fail) as patch:
-      self.assertFalse(
-          self.test_target.is_reproducible(TEST_FILES_PATH, '/not/exist'))
-      self.assertEqual(10, patch.call_count)
+  def test_flaky(self, _):
+    """Tests that is_reproducible returns True if crash is detected on the last
+    attempt."""
+    self._set_up_fakefs()
+    last_time_repro = [EXECUTE_SUCCESS_RETVAL] * 9 + [EXECUTE_FAILURE_RETVAL]
+    with unittest.mock.patch('utils.execute',
+                             side_effect=last_time_repro) as mocked_execute:
+      self.assertTrue(
+          self.test_target.is_reproducible(self.testcase_path,
+                                           self.fuzz_target_path))
+      self.assertEqual(fuzz_target.REPRODUCE_ATTEMPTS,
+                       mocked_execute.call_count)
+
+  def test_nonexistent_fuzzer(self, _):
+    """Tests that is_reproducible raises an error if it could not attempt
+    reproduction because the fuzzer doesn't exist."""
+    with self.assertRaises(fuzz_target.ReproduceError):
+      self.test_target.is_reproducible(self.testcase_path, '/non-existent-path')
+
+  def test_unreproducible(self, _):
+    """Tests that is_reproducible returns False for a crash that did not
+    reproduce."""
+    all_unrepro = [EXECUTE_SUCCESS_RETVAL] * fuzz_target.REPRODUCE_ATTEMPTS
+    self._set_up_fakefs()
+    with unittest.mock.patch('utils.execute', side_effect=all_unrepro):
+      result = self.test_target.is_reproducible(self.testcase_path,
+                                                self.fuzz_target_path)
+      self.assertFalse(result)
 
 
 class GetTestCaseUnitTest(unittest.TestCase):
@@ -84,7 +119,7 @@
     self.test_target = fuzz_target.FuzzTarget('/example/path', 10,
                                               '/example/outdir')
 
-  def test_with_valid_error_string(self):
+  def test_valid_error_string(self):
     """Tests that get_test_case returns the correct test case give an error."""
     test_case_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                   'test_files',
@@ -95,8 +130,8 @@
         parsed_test_case,
         '/example/outdir/crash-ad6700613693ef977ff3a8c8f4dae239c3dde6f5')
 
-  def test_with_invalid_error_string(self):
-    """Tests that get_test_case will return None with a bad error string."""
+  def test_invalid_error_string(self):
+    """Tests that get_test_case returns None with a bad error string."""
     self.assertIsNone(self.test_target.get_test_case(''))
     self.assertIsNone(self.test_target.get_test_case(' Example crash string.'))
 
@@ -105,28 +140,26 @@
   """Test parse_fuzzer_output function in the cifuzz module."""
 
   def test_download_valid_projects_corpus(self):
-    """Tests that a vaild fuzz target will return a corpus directory."""
+    """Tests that a vaild fuzz target returns a corpus directory."""
     with tempfile.TemporaryDirectory() as tmp_dir:
       test_target = fuzz_target.FuzzTarget('testfuzzer', 3, 'test_out')
       test_target.project_name = EXAMPLE_PROJECT
       test_target.target_name = EXAMPLE_FUZZER
       test_target.out_dir = tmp_dir
-      with unittest.mock.patch.object(fuzz_target,
-                                      'download_and_unpack_zip',
-                                      return_value=tmp_dir) as mock:
+      with unittest.mock.patch(
+          'fuzz_target.download_and_unpack_zip',
+          return_value=tmp_dir) as mocked_download_and_unpack_zip:
         test_target.download_latest_corpus()
-        (url, out_dir), _ = mock.call_args
+        (url, out_dir), _ = mocked_download_and_unpack_zip.call_args
         self.assertEqual(
-            url,
-            'https://storage.googleapis.com/example-backup.' \
-            'clusterfuzz-external.appspot.com/corpus/libFuzzer/' \
-            'example_crash_fuzzer/public.zip'
-        )
+            url, 'https://storage.googleapis.com/example-backup.'
+            'clusterfuzz-external.appspot.com/corpus/libFuzzer/'
+            'example_crash_fuzzer/public.zip')
         self.assertEqual(out_dir,
                          os.path.join(tmp_dir, 'backup_corpus', EXAMPLE_FUZZER))
 
   def test_download_invalid_projects_corpus(self):
-    """Tests that a invaild fuzz target will not return None."""
+    """Tests that a invaild fuzz target does not return None."""
     with tempfile.TemporaryDirectory() as tmp_dir:
       test_target = fuzz_target.FuzzTarget('testfuzzer', 3, tmp_dir)
       corpus_path = test_target.download_latest_corpus()
@@ -137,53 +170,95 @@
       self.assertIsNone(corpus_path)
 
 
-class CheckReproducibilityAndRegressionUnitTest(unittest.TestCase):
-  """Test check_reproducibility_and_regression function fuzz_target module."""
+class IsCrashReportableUnitTest(fake_filesystem_unittest.TestCase):
+  """Test is_crash_reportable method of fuzz_target.FuzzTarget."""
 
   def setUp(self):
-    """Sets up dummy fuzz target to test is_reproducible method."""
-    self.test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 100,
+    """Sets up dummy fuzz target to test is_crash_reportable method."""
+    self.fuzz_target_path = '/example/do_stuff_fuzzer'
+    self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path, 100,
                                               '/example/outdir', 'example')
+    self.oss_fuzz_build_path = '/oss-fuzz-build'
+    self.setUpPyfakefs()
+    self.fs.create_file(self.fuzz_target_path)
+    self.oss_fuzz_target_path = os.path.join(
+        self.oss_fuzz_build_path, os.path.basename(self.fuzz_target_path))
+    self.fs.create_file(self.oss_fuzz_target_path)
+    self.testcase_path = '/testcase'
+    self.fs.create_file(self.testcase_path, contents='')
 
-  def test_with_valid_crash(self):
-    """Checks to make sure a valid crash returns true."""
-    with unittest.mock.patch.object(
-        fuzz_target.FuzzTarget, 'is_reproducible',
-        side_effect=[True, False]), tempfile.TemporaryDirectory() as tmp_dir:
-      self.test_target.out_dir = tmp_dir
-      self.assertTrue(
-          self.test_target.check_reproducibility_and_regression(
-              '/example/crash/testcase'))
+  @unittest.mock.patch('logging.info')
+  def test_new_reproducible_crash(self, mocked_info):
+    """Tests that a new reproducible crash returns True."""
 
-  def test_with_invalid_crash(self):
-    """Checks to make sure an invalid crash returns false."""
-    with unittest.mock.patch.object(fuzz_target.FuzzTarget,
-                                    'is_reproducible',
-                                    side_effect=[True, True]):
-      self.assertFalse(
-          self.test_target.check_reproducibility_and_regression(
-              '/example/crash/testcase'))
+    with unittest.mock.patch('fuzz_target.FuzzTarget.is_reproducible',
+                             side_effect=[True, False]):
+      with tempfile.TemporaryDirectory() as tmp_dir:
+        self.test_target.out_dir = tmp_dir
+        self.assertTrue(self.test_target.is_crash_reportable(
+            self.testcase_path))
+    mocked_info.assert_called_with(
+        'The crash is reproducible. The crash doesn\'t reproduce '
+        'on old builds. This pull request probably introduced the '
+        'crash.')
 
-    with unittest.mock.patch.object(fuzz_target.FuzzTarget,
-                                    'is_reproducible',
-                                    side_effect=[False, True]):
-      self.assertFalse(
-          self.test_target.check_reproducibility_and_regression(
-              '/example/crash/testcase'))
+  # yapf: disable
+  @parameterized.parameterized.expand([
+      # Reproducible on PR build, but also reproducible on OSS-Fuzz.
+      ([True, True],),
 
-    with unittest.mock.patch.object(fuzz_target.FuzzTarget,
-                                    'is_reproducible',
-                                    side_effect=[False, False]):
-      self.assertFalse(
-          self.test_target.check_reproducibility_and_regression(
-              '/example/crash/testcase'))
+      # Not reproducible on PR build, but somehow reproducible on OSS-Fuzz.
+      # Unlikely to happen in real world except if test is flaky.
+      ([False, True],),
+
+      # Not reproducible on PR build, and not reproducible on OSS-Fuzz.
+      ([False, False],),
+  ])
+  # yapf: enable
+  def test_invalid_crash(self, is_reproducible_retvals):
+    """Tests that a nonreportable crash causes the method to return False."""
+    with unittest.mock.patch('fuzz_target.FuzzTarget.is_reproducible',
+                             side_effect=is_reproducible_retvals):
+
+      with unittest.mock.patch('fuzz_target.FuzzTarget.download_oss_fuzz_build',
+                               return_value=self.oss_fuzz_build_path):
+        self.assertFalse(
+            self.test_target.is_crash_reportable(self.testcase_path))
+
+  @unittest.mock.patch('logging.info')
+  @unittest.mock.patch('fuzz_target.FuzzTarget.is_reproducible',
+                       return_value=[True])
+  def test_reproducible_no_oss_fuzz_target(self, _, mocked_info):
+    """Tests that is_crash_reportable returns True when a crash repros on the
+    PR build but the target is not in the OSS-Fuzz build (usually because it
+    is new)."""
+    os.remove(self.oss_fuzz_target_path)
+
+    def is_reproducible_side_effect(_, target_path):
+      if os.path.dirname(target_path) == self.oss_fuzz_build_path:
+        raise fuzz_target.ReproduceError()
+      return True
+
+    with unittest.mock.patch(
+        'fuzz_target.FuzzTarget.is_reproducible',
+        side_effect=is_reproducible_side_effect) as mocked_is_reproducible:
+      with unittest.mock.patch('fuzz_target.FuzzTarget.download_oss_fuzz_build',
+                               return_value=self.oss_fuzz_build_path):
+        self.assertTrue(self.test_target.is_crash_reportable(
+            self.testcase_path))
+    mocked_is_reproducible.assert_any_call(self.testcase_path,
+                                           self.oss_fuzz_target_path)
+    mocked_info.assert_called_with(
+        'Crash is reproducible. Could not run OSS-Fuzz build of '
+        'target to determine if this pull request introduced crash. '
+        'Assuming this pull request introduced crash.')
 
 
 class GetLatestBuildVersionUnitTest(unittest.TestCase):
   """Test the get_latest_build_version function in the fuzz_target module."""
 
   def test_get_valid_project(self):
-    """Checks the latest build can be retrieved from gcs."""
+    """Tests that the latest build can be retrieved from GCS."""
     test_target = fuzz_target.FuzzTarget('/example/path', 10, '/example/outdir',
                                          'example')
     latest_build = test_target.get_lastest_build_version()
@@ -192,7 +267,7 @@
     self.assertTrue('address' in latest_build)
 
   def test_get_invalid_project(self):
-    """Checks the latest build will return None when project doesn't exist."""
+    """Tests that the latest build returns None when project doesn't exist."""
     test_target = fuzz_target.FuzzTarget('/example/path', 10, '/example/outdir',
                                          'not-a-proj')
     self.assertIsNone(test_target.get_lastest_build_version())
@@ -204,23 +279,22 @@
   """Test the download_oss_fuzz_build in function in the fuzz_target module."""
 
   def test_single_download(self):
-    """Checks that the build directory was only downloaded once."""
+    """Tests that the build directory was only downloaded once."""
     with tempfile.TemporaryDirectory() as tmp_dir:
       test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                            tmp_dir, 'example')
       latest_version = test_target.get_lastest_build_version()
-      with unittest.mock.patch.object(
-          fuzz_target.FuzzTarget,
-          'get_lastest_build_version',
-          return_value=latest_version) as mock_build_version:
+      with unittest.mock.patch(
+          'fuzz_target.FuzzTarget.get_lastest_build_version',
+          return_value=latest_version) as mocked_get_latest_build_version:
         for _ in range(5):
           oss_fuzz_build_path = test_target.download_oss_fuzz_build()
-        self.assertEqual(1, mock_build_version.call_count)
+        self.assertEqual(1, mocked_get_latest_build_version.call_count)
         self.assertIsNotNone(oss_fuzz_build_path)
         self.assertTrue(os.listdir(oss_fuzz_build_path))
 
   def test_get_valid_project(self):
-    """Checks the latest build can be retrieved from gcs."""
+    """Tests the latest build can be retrieved from GCS."""
     with tempfile.TemporaryDirectory() as tmp_dir:
       test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                            tmp_dir, 'example')
@@ -229,7 +303,7 @@
       self.assertTrue(os.listdir(oss_fuzz_build_path))
 
   def test_get_invalid_project(self):
-    """Checks the latest build will return None when project doesn't exist."""
+    """Tests the latest build returns None when project doesn't exist."""
     with tempfile.TemporaryDirectory() as tmp_dir:
       test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                            tmp_dir)
@@ -239,7 +313,7 @@
       self.assertIsNone(test_target.download_oss_fuzz_build())
 
   def test_invalid_build_dir(self):
-    """Checks the download will return None when out_dir doesn't exist."""
+    """Tests the download returns None when out_dir doesn't exist."""
     test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                          'not/a/dir', 'example')
     self.assertIsNone(test_target.download_oss_fuzz_build())
@@ -250,8 +324,8 @@
 
   def test_bad_zip_download(self):
     """Tests download_and_unpack_zip returns none when a bad zip is passed."""
-    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch.object(
-        urllib.request, 'urlretrieve', return_value=True):
+    with tempfile.TemporaryDirectory() as tmp_dir, unittest.mock.patch(
+        'urllib.request.urlretrieve', return_value=True):
       file_handle = open(os.path.join(tmp_dir, 'url_tmp.zip'), 'w')
       file_handle.write('Test file.')
       file_handle.close()
diff --git a/infra/dev-requirements.txt b/infra/dev-requirements.txt
deleted file mode 100644
index 55e3b50..0000000
--- a/infra/dev-requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# Requirements for submitting code changes to infra/ (needed by presubmit.py).
-pylint==2.4.4
-yapf==0.28.0
-PyYAML==5.1
-
diff --git a/infra/gcb/build_and_run_coverage.py b/infra/gcb/build_and_run_coverage.py
index a22d35f..6357192 100644
--- a/infra/gcb/build_and_run_coverage.py
+++ b/infra/gcb/build_and_run_coverage.py
@@ -44,7 +44,7 @@
   sys.stderr.write('%s\n' % message)
 
   # Since the script should print build_id, print '0' as a special value.
-  print '0'
+  print('0')
   exit(0)
 
 
@@ -79,6 +79,7 @@
   env = CONFIGURATION[:]
   out = '/workspace/out/' + SANITIZER
   env.append('OUT=' + out)
+  env.append('FUZZING_LANGUAGE=' + language)
 
   workdir = build_project.workdir_from_dockerfile(dockerfile_path)
   if not workdir:
diff --git a/infra/gcb/build_project.py b/infra/gcb/build_project.py
index 16a62ef..e9d0480 100644
--- a/infra/gcb/build_project.py
+++ b/infra/gcb/build_project.py
@@ -161,6 +161,7 @@
         env.append('OUT=' + out)
         env.append('MSAN_LIBS_PATH=/workspace/msan')
         env.append('ARCHITECTURE=' + architecture)
+        env.append('FUZZING_LANGUAGE=' + language)
 
         workdir = workdir_from_dockerfile(dockerfile_path)
         if not workdir:
diff --git a/infra/gcb/builds_status.py b/infra/gcb/builds_status.py
index 5352d36..087df6f 100755
--- a/infra/gcb/builds_status.py
+++ b/infra/gcb/builds_status.py
@@ -96,10 +96,13 @@
           build_project.GCB_LOGS_BUCKET)
       log_name = 'log-{0}.txt'.format(build['id'])
       log = gcb_bucket.blob(log_name)
-      dest_log = status_bucket.blob(log_name)
+      if not log.exists():
+        print >> sys.stderr, 'Failed to find build log', log_name
+        continue
 
       with tempfile.NamedTemporaryFile() as f:
         log.download_to_filename(f.name)
+        dest_log = status_bucket.blob(log_name)
         dest_log.upload_from_filename(f.name, content_type='text/plain')
 
       return build
diff --git a/infra/gcb/requirements.txt b/infra/gcb/requirements.txt
index af53d16..584c701 100644
--- a/infra/gcb/requirements.txt
+++ b/infra/gcb/requirements.txt
@@ -15,7 +15,7 @@
 googleapis-common-protos==1.5.3
 grpc-google-iam-v1==0.11.4
 grpcio==1.12.0
-httplib2==0.11.3
+httplib2==0.18.0
 idna==2.6
 Jinja2==2.10.1
 MarkupSafe==1.0
diff --git a/infra/helper.py b/infra/helper.py
index 1c0610b..668f31d 100755
--- a/infra/helper.py
+++ b/infra/helper.py
@@ -56,6 +56,8 @@
     'gs://{project_name}-backup.clusterfuzz-external.appspot.com/corpus/'
     'libFuzzer/{fuzz_target}/')
 
+PROJECT_LANGUAGE_REGEX = re.compile(r'\s*language\s*:\s*([^\s]+)')
+
 
 def main():  # pylint: disable=too-many-branches,too-many-return-statements,too-many-statements
   """Get subcommand from program arguments and do it."""
@@ -284,6 +286,20 @@
   return os.path.join(BUILD_DIR, 'work', project_name)
 
 
+def _get_project_language(project_name):
+  """Returns project language."""
+  project_yaml_path = os.path.join(OSS_FUZZ_DIR, 'projects', project_name,
+                                   'project.yaml')
+  with open(project_yaml_path) as file_handle:
+    content = file_handle.read()
+    for line in content.splitlines():
+      match = PROJECT_LANGUAGE_REGEX.match(line)
+      if match:
+        return match.group(1)
+
+  return None
+
+
 def _add_architecture_args(parser, choices=('x86_64', 'i386')):
   """Add common architecture args."""
   parser.add_argument('--architecture', default='x86_64', choices=choices)
@@ -449,7 +465,7 @@
   return 1
 
 
-def build_fuzzers_impl(  # pylint: disable=too-many-arguments
+def build_fuzzers_impl(  # pylint: disable=too-many-arguments,too-many-locals,too-many-branches
     project_name,
     clean,
     engine,
@@ -465,6 +481,9 @@
 
   project_out_dir = _get_output_dir(project_name)
   project_work_dir = _get_work_dir(project_name)
+  project_language = _get_project_language(project_name)
+  if not project_language:
+    print('WARNING: language not specified in project.yaml. Build may fail.')
 
   if clean:
     print('Cleaning existing build artifacts.')
@@ -489,6 +508,10 @@
       'SANITIZER=' + sanitizer,
       'ARCHITECTURE=' + architecture,
   ]
+
+  if project_language:
+    env.append('FUZZING_LANGUAGE=' + project_language)
+
   if env_to_add:
     env += env_to_add
 
@@ -778,14 +801,20 @@
 
 
 def reproduce_impl(  # pylint: disable=too-many-arguments
-    project_name, fuzzer_name, valgrind, env_to_add, fuzzer_args,
-    testcase_path):
+    project_name,
+    fuzzer_name,
+    valgrind,
+    env_to_add,
+    fuzzer_args,
+    testcase_path,
+    runner=docker_run,
+    err_result=1):
   """Reproduces a testcase in the container."""
   if not check_project_exists(project_name):
-    return 1
+    return err_result
 
   if not _check_fuzzer_exists(project_name, fuzzer_name):
-    return 1
+    return err_result
 
   debugger = ''
   env = []
@@ -813,7 +842,7 @@
       '-runs=100',
   ] + fuzzer_args
 
-  return docker_run(run_args)
+  return runner(run_args)
 
 
 def generate(args):
diff --git a/infra/presubmit.py b/infra/presubmit.py
index cbcbc0b..a4d61bd 100755
--- a/infra/presubmit.py
+++ b/infra/presubmit.py
@@ -334,13 +334,16 @@
   for file in get_changed_files():
     changed_dirs.add(os.path.dirname(file))
 
+  # TODO(metzman): This approach for running tests is flawed since tests can
+  # fail even if their directory isn't changed. Figure out if it is needed (to
+  # save time) and remove it if it isn't.
   suite_list = []
   for change_dir in changed_dirs:
     suite_list.append(unittest.TestLoader().discover(change_dir,
                                                      pattern='*_test.py'))
-  full_suite = unittest.TestSuite(suite_list)
-  result = unittest.TextTestRunner().run(full_suite)
-  return not result.failures
+  suite = unittest.TestSuite(suite_list)
+  result = unittest.TextTestRunner().run(suite)
+  return not result.failures and not result.errors
 
 
 def main():
diff --git a/infra/travis/requirements.txt b/infra/travis/requirements.txt
index 37917bb..2ddcb47 100644
--- a/infra/travis/requirements.txt
+++ b/infra/travis/requirements.txt
@@ -1 +1,6 @@
+# Requirements for submitting code changes to infra/ (needed by presubmit.py).
+pylint==2.4.4
+yapf==0.28.0
 PyYAML==5.1
+pyfakefs==3.7.1
+parameterized==0.7.4
diff --git a/infra/utils.py b/infra/utils.py
index fa5aed2..17cc237 100644
--- a/infra/utils.py
+++ b/infra/utils.py
@@ -55,8 +55,8 @@
                              stderr=subprocess.PIPE,
                              cwd=location)
   out, err = process.communicate()
-  out = out.decode('ascii')
-  err = err.decode('ascii')
+  out = out.decode('utf-8', errors='ignore')
+  err = err.decode('utf-8', errors='ignore')
   if err:
     logging.debug('Stderr of command \'%s\' is %s.', ' '.join(command), err)
   if check_result and process.returncode:
diff --git a/projects/cascadia/Dockerfile b/projects/cascadia/Dockerfile
new file mode 100644
index 0000000..c1b7c93
--- /dev/null
+++ b/projects/cascadia/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER cascadia@balholm.com
+RUN go get github.com/andybalholm/cascadia
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/cascadia/build.sh b/projects/cascadia/build.sh
new file mode 100755
index 0000000..a7f68b9
--- /dev/null
+++ b/projects/cascadia/build.sh
@@ -0,0 +1,27 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_fuzzer github.com/andybalholm/cascadia/fuzz Fuzz fuzz
diff --git a/projects/cascadia/project.yaml b/projects/cascadia/project.yaml
new file mode 100644
index 0000000..6c6605a
--- /dev/null
+++ b/projects/cascadia/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/andybalholm/cascadia"
+primary_contact: "cascadia@balholm.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/clamav/Dockerfile b/projects/clamav/Dockerfile
index f91236d..0b97bc3 100644
--- a/projects/clamav/Dockerfile
+++ b/projects/clamav/Dockerfile
@@ -16,7 +16,10 @@
 
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER clamav.fuzz@gmail.com
-RUN apt-get update && apt-get install -y libssl-dev libcurl4-openssl-dev
+RUN apt-get update && apt-get install -y \
+    flex bison \
+    libssl-dev \
+    libcurl4-openssl-dev
 RUN git clone --depth 1 https://github.com/Cisco-Talos/clamav-devel.git
 RUN git clone --depth 1 https://github.com/Cisco-Talos/clamav-fuzz-corpus.git
 
diff --git a/projects/clamav/build.sh b/projects/clamav/build.sh
index 716bc8a..4b54632 100755
--- a/projects/clamav/build.sh
+++ b/projects/clamav/build.sh
@@ -15,13 +15,30 @@
 #
 ################################################################################
 
+set -ex
+
 #
 # Build the library.
 #
 rm -rf ${WORK}/build
 mkdir -p ${WORK}/build
 cd ${WORK}/build
-ac_cv_c_mmap_anonymous=no ${SRC}/clamav-devel/configure --disable-mempool --enable-fuzz=yes --with-libjson=no --with-pcre=no --enable-static=yes --enable-shared=no --disable-llvm --host=x86_64-unknown-linux-gnu
+
+#
+# Run ./configure
+#
+ac_cv_c_mmap_anonymous=no \
+    ${SRC}/clamav-devel/configure \
+        --disable-mempool \
+        --enable-fuzz=yes \
+        --with-libjson=no \
+        --with-pcre=no \
+        --enable-static=yes \
+        --enable-shared=no \
+        --disable-llvm \
+        --host=x86_64-unknown-linux-gnu
+
+# Build libclamav
 make clean
 make -j"$(nproc)"
 
@@ -40,16 +57,16 @@
 mkdir ${WORK}/all-scantype-seeds
 
 for type in ARCHIVE MAIL OLE2 PDF HTML PE ELF SWF XMLDOCS HWP3; do
-	# Prepare seed corpus for the type-specific fuzz targets.
-	zip ${OUT}/clamav_scanfile_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/scantype/${type}/*
-	zip ${OUT}/clamav_scanmap_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/scantype/${type}/*
+    # Prepare seed corpus for the type-specific fuzz targets.
+    zip ${OUT}/clamav_scanfile_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/scantype/${type}/*
+    zip ${OUT}/clamav_scanmap_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/scantype/${type}/*
 
-	# Prepare dictionary for the type-specific fuzz targets (may not exist for all types).
-	cp ${SRC}/clamav-fuzz-corpus/scantype/${type}.dict ${OUT}/clamav_scanfile_${type}_fuzzer.dict 2>/dev/null || :
-	cp ${SRC}/clamav-fuzz-corpus/scantype/${type}.dict ${OUT}/clamav_scanmap_${type}_fuzzer.dict 2>/dev/null || :
+    # Prepare dictionary for the type-specific fuzz targets (may not exist for all types).
+    cp ${SRC}/clamav-fuzz-corpus/scantype/${type}.dict ${OUT}/clamav_scanfile_${type}_fuzzer.dict 2>/dev/null || :
+    cp ${SRC}/clamav-fuzz-corpus/scantype/${type}.dict ${OUT}/clamav_scanmap_${type}_fuzzer.dict 2>/dev/null || :
 
-	# Copy seeds for the generic fuzz target.
-	cp ${SRC}/clamav-fuzz-corpus/scantype/${type}/* ${WORK}/all-scantype-seeds/
+    # Copy seeds for the generic fuzz target.
+    cp ${SRC}/clamav-fuzz-corpus/scantype/${type}/* ${WORK}/all-scantype-seeds/
 done
 
 # Prepare seed corpus for the generic fuzz target.
@@ -61,9 +78,9 @@
 # `dbload`
 # --------
 for type in CDB CFG CRB FP FTM HDB HSB IDB IGN IGN2 LDB MDB MSB NDB PDB WDB YARA; do
-	# Prepare seed corpus for the type-specific fuzz targets.
-	zip ${OUT}/clamav_dbload_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/database/${type}/*
+    # Prepare seed corpus for the type-specific fuzz targets.
+    zip ${OUT}/clamav_dbload_${type}_fuzzer_seed_corpus.zip ${SRC}/clamav-fuzz-corpus/database/${type}/*
 
-	# Prepare dictionary for the type-specific fuzz targets (may not exist for all types).
-	cp ${SRC}/clamav-fuzz-corpus/database/${type}.dict ${OUT}/clamav_dbload_${type}_fuzzer.dict 2>/dev/null || :
+    # Prepare dictionary for the type-specific fuzz targets (may not exist for all types).
+    cp ${SRC}/clamav-fuzz-corpus/database/${type}.dict ${OUT}/clamav_dbload_${type}_fuzzer.dict 2>/dev/null || :
 done
diff --git a/projects/cras/Dockerfile b/projects/cras/Dockerfile
index e6cce9a..0b77c63 100644
--- a/projects/cras/Dockerfile
+++ b/projects/cras/Dockerfile
@@ -11,7 +11,6 @@
       apt-get install -y \
       automake \
       build-essential \
-      cargo \
       cmake \
       g++ \
       git \
diff --git a/projects/cryptofuzz/Dockerfile b/projects/cryptofuzz/Dockerfile
index a77ada7..85411e5 100644
--- a/projects/cryptofuzz/Dockerfile
+++ b/projects/cryptofuzz/Dockerfile
@@ -17,7 +17,12 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER guidovranken@gmail.com
 
-RUN apt-get update && apt-get install -y software-properties-common python-software-properties make autoconf automake libtool build-essential cmake libboost-all-dev wget mercurial gyp ninja-build zlib1g-dev libsqlite3-dev
+RUN apt-get update && \
+    apt-get install -y apt-transport-https ca-certificates gnupg software-properties-common wget && \
+    wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | apt-key add - && \
+    apt-add-repository 'deb https://apt.kitware.com/ubuntu/ xenial main' && \
+    apt-get update && \
+    apt-get install -y software-properties-common python-software-properties make autoconf automake libtool build-essential cmake libboost-all-dev mercurial gyp ninja-build zlib1g-dev libsqlite3-dev
 
 # BoringSSL needs Go to build
 RUN add-apt-repository -y ppa:gophers/archive && apt-get update && apt-get install -y golang-1.9-go
@@ -43,6 +48,7 @@
 RUN hg clone https://hg.mozilla.org/projects/nss
 RUN git clone --depth 1 https://github.com/jedisct1/libsodium.git
 RUN git clone --depth 1 https://github.com/libtom/libtomcrypt.git
+RUN git clone --depth 1 https://github.com/microsoft/SymCrypt.git
 RUN apt-get remove -y libunwind8
 RUN apt-get install -y libssl-dev
 
diff --git a/projects/cryptofuzz/build.sh b/projects/cryptofuzz/build.sh
index a7f394a..04a8987 100755
--- a/projects/cryptofuzz/build.sh
+++ b/projects/cryptofuzz/build.sh
@@ -94,6 +94,28 @@
     make -B
 fi
 
+# Compile SymCrypt
+cd $SRC/SymCrypt/
+if [[ $CFLAGS != *sanitize=undefined* ]]
+then
+    # Unittests don't build with clang and are not needed anyway
+    sed -i "s/^add_subdirectory(unittest)$//g" CMakeLists.txt
+
+    mkdir b/
+    cd b/
+    cmake ../
+    make -j$(nproc)
+
+    export CXXFLAGS="$CXXFLAGS -DCRYPTOFUZZ_SYMCRYPT"
+    export SYMCRYPT_INCLUDE_PATH=$(realpath ../inc/)
+    export LIBSYMCRYPT_COMMON_A_PATH=$(realpath lib/x86_64/Generic/libsymcrypt_common.a)
+    export SYMCRYPT_GENERIC_A_PATH=$(realpath lib/x86_64/Generic/symcrypt_generic.a)
+
+    # Compile Cryptofuzz SymCrypt module
+    cd $SRC/cryptofuzz/modules/symcrypt
+    make -B
+fi
+
 # Compile Cityhash
 cd $SRC/cityhash
 if [[ $CFLAGS != *-m32* ]]
@@ -289,12 +311,22 @@
     LINK_FLAGS=${LINK_FLAGS//"-lsqlite3"/}
 fi
 
+if [[ $CFLAGS != *sanitize=memory* ]]
+then
+    # libtomcrypt can only be compiled with NSS, because OpenSSL, LibreSSL and
+    # BoringSSL have symbol collisions with libtomcrypt.
+    #
+    # So, now that NSS-based Cryptofuzz has been compiled, remove libtomcrypt
+    export CXXFLAGS=${CXXFLAGS/-DCRYPTOFUZZ_LIBTOMCRYPT/}
+    rm -rf "$LIBTOMCRYPT_A_PATH"
+fi
+
 ##############################################################################
 # Compile wolfCrypt
 cd $SRC/wolfssl
 autoreconf -ivf
 
-export WOLFCRYPT_CONFIGURE_PARAMS="--enable-static --enable-md2 --enable-md4 --enable-ripemd --enable-blake2 --enable-blake2s --enable-pwdbased --enable-scrypt --enable-hkdf --enable-cmac --enable-arc4 --enable-camellia --enable-rabbit --enable-aesccm --enable-aesctr --enable-hc128 --enable-xts --enable-des3 --enable-idea --enable-x963kdf --enable-harden"
+export WOLFCRYPT_CONFIGURE_PARAMS="--enable-static --enable-md2 --enable-md4 --enable-ripemd --enable-blake2 --enable-blake2s --enable-pwdbased --enable-scrypt --enable-hkdf --enable-cmac --enable-arc4 --enable-camellia --enable-rabbit --enable-aesccm --enable-aesctr --enable-hc128 --enable-xts --enable-des3 --enable-idea --enable-x963kdf --enable-harden --enable-aescfb --enable-aesofb"
 
 if [[ $CFLAGS = *sanitize=memory* ]]
 then
diff --git a/projects/cryptofuzz/project.yaml b/projects/cryptofuzz/project.yaml
index 825ecf9..91b002b 100644
--- a/projects/cryptofuzz/project.yaml
+++ b/projects/cryptofuzz/project.yaml
@@ -26,6 +26,8 @@
     - "jjones@mozilla.com"
     - "sledru@mozilla.com"
     - "kjacobs@mozilla.com"
+    - "bbeurdouche@mozilla.com"
+    - "tvandermerwe@mozilla.com"
     - "matthias.st.pierre@gmail.com"
     - "kaleb.himes@gmail.com"
 sanitizers:
diff --git a/projects/dav1d/project.yaml b/projects/dav1d/project.yaml
index 3a40f6a..72386e4 100644
--- a/projects/dav1d/project.yaml
+++ b/projects/dav1d/project.yaml
@@ -7,6 +7,7 @@
   - "b@rr-dav.id.au"
   - "dav1d-fuzz@videolan.org"
 vendor_ccs:
+  - "negge@mozilla.com"
   - "twsmith@mozilla.com"
 sanitizers:
   - address
diff --git a/projects/dragonfly/Dockerfile b/projects/dragonfly/Dockerfile
new file mode 100644
index 0000000..932c86f
--- /dev/null
+++ b/projects/dragonfly/Dockerfile
@@ -0,0 +1,34 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER zj3142063@gmail.com
+RUN go get	github.com/go-openapi/swag \
+		github.com/go-openapi/validate \
+		gopkg.in/warnings.v0 \
+		github.com/gorilla/mux \
+		github.com/prometheus/client_golang/prometheus \ 
+		github.com/pkg/errors \
+		github.com/sirupsen/logrus \
+		gopkg.in/gcfg.v1 \
+		github.com/valyala/fasthttp \
+		gopkg.in/natefinch/lumberjack.v2 \
+		github.com/emirpasic/gods/maps/treemap \
+		github.com/emirpasic/gods/utils \
+		github.com/willf/bitset
+RUN git clone https://github.com/dragonflyoss/Dragonfly
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/dragonfly/build.sh b/projects/dragonfly/build.sh
new file mode 100755
index 0000000..432d765
--- /dev/null
+++ b/projects/dragonfly/build.sh
@@ -0,0 +1,30 @@
+#/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+mkdir $GOPATH/src/github.com/dragonflyoss
+cp -r $SRC/Dragonfly $GOPATH/src/github.com/dragonflyoss/
+
+compile_fuzzer github.com/dragonflyoss/Dragonfly/dfget/core/uploader FuzzParseParams uploader_fuzz
+compile_fuzzer github.com/dragonflyoss/Dragonfly/supernode/daemon/mgr/cdn Fuzz cdn_fuzz
diff --git a/projects/dragonfly/project.yaml b/projects/dragonfly/project.yaml
new file mode 100644
index 0000000..1b297eb
--- /dev/null
+++ b/projects/dragonfly/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/dragonflyoss/Dragonfly"
+primary_contact: "zj3142063@gmail.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/ecc-diff-fuzzer/Dockerfile b/projects/ecc-diff-fuzzer/Dockerfile
index 988c637..40b519e 100644
--- a/projects/ecc-diff-fuzzer/Dockerfile
+++ b/projects/ecc-diff-fuzzer/Dockerfile
@@ -17,8 +17,6 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER p.antoine@catenacyber.fr
 RUN apt-get update && apt-get install -y make cmake bzip2 autoconf automake gettext libtool python nodejs npm
-ENV CARGO_HOME=/rust RUSTUP_HOME=/rust/rustup PATH=$PATH:/rust/bin
-RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
 RUN rustup target add i686-unknown-linux-gnu
 RUN npm install -g browserify
 RUN npm install elliptic
diff --git a/projects/envoy/project.yaml b/projects/envoy/project.yaml
index 13b957a..41b1057 100644
--- a/projects/envoy/project.yaml
+++ b/projects/envoy/project.yaml
@@ -11,6 +11,11 @@
   - "envoy-security@googlegroups.com"
   - "yavlasov@google.com"
   - "asraa@google.com"
+  - "adip@google.com"
   - "avd@google.com"
+  - "akonradi@google.com"
+  - "liebchen@google.com"
+  - "samflattery@google.com"
+  - "jianwendong@google.com"
   - "skerner@google.com"
 coverage_extra_args: -ignore-filename-regex=.*\.cache.*envoy_deps_cache.*
diff --git a/projects/fasthttp/Dockerfile b/projects/fasthttp/Dockerfile
new file mode 100644
index 0000000..87cca72
--- /dev/null
+++ b/projects/fasthttp/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get github.com/valyala/fasthttp
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/fasthttp/build.sh b/projects/fasthttp/build.sh
new file mode 100755
index 0000000..3d2b31b
--- /dev/null
+++ b/projects/fasthttp/build.sh
@@ -0,0 +1,32 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+
+ls $GOPATH/src/github.com/valyala/fasthttp/fuzzit | while read target
+do
+    compile_fuzzer github.com/valyala/fasthttp/fuzzit/$target Fuzz fuzz_$target
+done
diff --git a/projects/fasthttp/project.yaml b/projects/fasthttp/project.yaml
new file mode 100644
index 0000000..2f4a3ec
--- /dev/null
+++ b/projects/fasthttp/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/valyala/fasthttp"
+primary_contact: "erik@dubbelboer.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/fastjson/Dockerfile b/projects/fastjson/Dockerfile
new file mode 100644
index 0000000..3d0ba3d
--- /dev/null
+++ b/projects/fastjson/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get github.com/valyala/fastjson
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/fastjson/build.sh b/projects/fastjson/build.sh
new file mode 100755
index 0000000..b3e45f2
--- /dev/null
+++ b/projects/fastjson/build.sh
@@ -0,0 +1,27 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_fuzzer github.com/valyala/fastjson Fuzz fuzz
diff --git a/projects/fastjson/project.yaml b/projects/fastjson/project.yaml
new file mode 100644
index 0000000..2a04abc
--- /dev/null
+++ b/projects/fastjson/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/valyala/fastjson"
+primary_contact: "valyala@gmail.com"
+auto_ccs :
+- "adam@adalogics.com"
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/ffmpeg/Dockerfile b/projects/ffmpeg/Dockerfile
index 5226dd7..6b9e9c1 100644
--- a/projects/ffmpeg/Dockerfile
+++ b/projects/ffmpeg/Dockerfile
@@ -22,7 +22,7 @@
     libass-dev libfreetype6-dev libsdl1.2-dev \
     libvdpau-dev libxcb1-dev libxcb-shm0-dev \
     pkg-config texinfo libbz2-dev zlib1g-dev yasm cmake mercurial wget \
-    xutils-dev libpciaccess-dev nasm
+    xutils-dev libpciaccess-dev nasm rsync
 
 RUN git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
 
@@ -33,9 +33,9 @@
 RUN git clone --depth 1 https://github.com/01org/libva
 RUN git clone --depth 1 -b libvdpau-1.2 git://people.freedesktop.org/~aplattner/libvdpau
 RUN git clone --depth 1 https://chromium.googlesource.com/webm/libvpx
-RUN git clone --depth 1 git://git.xiph.org/ogg.git
-RUN git clone --depth 1 git://git.xiph.org/opus.git
-RUN git clone --depth 1 git://git.xiph.org/theora.git
-RUN git clone --depth 1 git://git.xiph.org/vorbis.git
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/ogg.git
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/opus.git
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/theora.git
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/vorbis.git
 
 COPY build.sh group_seed_corpus.py $SRC/
diff --git a/projects/firefox/build.sh b/projects/firefox/build.sh
index b001a42..b864d59 100755
--- a/projects/firefox/build.sh
+++ b/projects/firefox/build.sh
@@ -41,13 +41,13 @@
 export MOZ_OBJDIR=$WORK/obj-fuzz
 export MOZCONFIG=$SRC/mozconfig.$SANITIZER
 
-# Install dependencies. Note that bootstrap installs cargo, which must be added
-# to PATH via source. In a successive run (for a different sanitizer), the
-# cargo installation carries over, but bootstrap fails if cargo is not in PATH.
+# Install dependencies.
 export SHELL=/bin/bash
-[[ -f "$HOME/.cargo/env" ]] && source $HOME/.cargo/env
 ./mach bootstrap --no-interactive --application-choice browser
-source $HOME/.cargo/env
+
+# Skip patches for now
+rm tools/fuzzing/libfuzzer/patches/*.patch
+touch tools/fuzzing/libfuzzer/patches/dummy.patch
 
 # Update internal libFuzzer.
 (cd tools/fuzzing/libfuzzer && ./clone_libfuzzer.sh HEAD)
diff --git a/projects/fluent-bit/build.sh b/projects/fluent-bit/build.sh
index e9c5eeb..7e14af2 100755
--- a/projects/fluent-bit/build.sh
+++ b/projects/fluent-bit/build.sh
@@ -16,10 +16,13 @@
 ################################################################################
 cd fluent-bit/build
 
+export CFLAGS="$CFLAGS -fcommon"
+export CXXFLAGS="$CXXFLAGS -fcommon"
+
 # Commandline arguments to turn off a lot of plugins.
 INPUT_PLUGINS="-DFLB_IN_COLLECTD=OFF -DFLB_IN_CPU=OFF -DFLB_IN_DISK=OFF -DFLB_IN_DOCKER=OFF -DFLB_IN_EXEC=OFF -DFLB_IN_FORWARD=OFF -DFLB_IN_HEAD=OFF -DFLB_IN_HEALTH=OFF -DFLB_IN_KMSG=OFF -DFLB_IN_MEM=OFF -DFLB_IN_MQTT=OFF -DFLB_IN_NETIF=OFF -DFLB_IN_PROC=OFF -DFLB_IN_RANDOM=OFF -DFLB_IN_SERIAL=OFF -DFLB_IN_STDIN=OFF -DFLB_IN_SYSLOG=OFF -DFLB_IN_SYSTEMD=OFF -DFLB_IN_TAIL=OFF -DFLB_IN_TCP=OFF -DFLB_IN_THERMAL=OFF -DFLB_IN_WINLOG=OFF"
-OUTPUT_PLUGINS="-DFLB_RECORD_ACCESSOR=Off -DFLB_STREAM_PROCESSOR=Off -DFLB_LUAJIT=OFF -DFLB_FILTER_GREP=OFF -DFLB_FILTER_REWRITE_TAG=OFF -DFLB_OUT_AZURE=OFF -DFLB_OUT_BIGQUERY=OFF -DFLB_OUT_COUNTER=OFF -DFLB_OUT_DATADOG=OFF -DFLB_OUT_ES=OFF -DFLB_OUT_FILE=OFF -DFLB_OUT_FLOWCOUNTER=OFF -DFLB_OUT_FORWARD=OFF -DFLB_OUT_GELF=OFF -DFLB_OUT_HTTP=OFF -DFLB_OUT_INFLUXDB=OFF -DFLB_OUT_KAFKA=OFF -DFLB_OUT_KAFKA_REST=OFF -DFLB_OUT_NATS=OFF -DFLB_OUT_NULL=OFF -DFLB_OUT_PGSQL=OFF -DFLB_OUT_PLOT=OFF -DFLB_OUT_SLACK=OFF -DFLB_OUT_SPLUNK=OFF -DFLB_OUT_STACKDRIVER=OFF -DFLB_OUT_STDOUT=OFF -DFLB_OUT_TCP=OFF"
-FILTER_PLUGINS="-DFLB_FILTER_RECORD_MODIFIER=OFF -DFLB_FILTER_MODIFY=OFF -DFLB_FILTER_THROTTLE=OFF -DFLB_FILTER_KUBERNETES=OFF -DFLB_FILTER_NEST=OFF -DFLB_FILTER_PARSER=OFF -DFLB_FILTER_AWS=OFF"
+OUTPUT_PLUGINS="-DFLB_RECORD_ACCESSOR=Off -DFLB_STREAM_PROCESSOR=Off -DFLB_LUAJIT=OFF -DFLB_FILTER_GREP=OFF -DFLB_FILTER_REWRITE_TAG=OFF -DFLB_OUT_AZURE=OFF -DFLB_OUT_BIGQUERY=OFF -DFLB_OUT_COUNTER=OFF -DFLB_OUT_DATADOG=OFF -DFLB_OUT_ES=OFF -DFLB_OUT_FILE=OFF -DFLB_OUT_FLOWCOUNTER=OFF -DFLB_OUT_FORWARD=OFF -DFLB_OUT_GELF=OFF -DFLB_OUT_HTTP=OFF -DFLB_OUT_INFLUXDB=OFF -DFLB_OUT_KAFKA=OFF -DFLB_OUT_KAFKA_REST=OFF -DFLB_OUT_NATS=OFF -DFLB_OUT_NULL=OFF -DFLB_OUT_PGSQL=OFF -DFLB_OUT_PLOT=OFF -DFLB_OUT_SLACK=OFF -DFLB_OUT_SPLUNK=OFF -DFLB_OUT_STACKDRIVER=OFF -DFLB_OUT_STDOUT=OFF -DFLB_OUT_TCP=OFF -DFLB_OUT_SYSLOG=OFF"
+FILTER_PLUGINS="-DFLB_FILTER_RECORD_MODIFIER=OFF -DFLB_FILTER_MODIFY=OFF -DFLB_FILTER_THROTTLE=OFF -DFLB_FILTER_KUBERNETES=OFF -DFLB_FILTER_NEST=OFF -DFLB_FILTER_PARSER=OFF -DFLB_FILTER_AWS=OFF -DFLB_FILTER_ALTER_SIZE=OFF"
 
 cmake ${INPUT_PLUGINS} ${FILTER_PLUGINS} ${OUTPUT_PLUGINS} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ..
 make
@@ -34,5 +37,6 @@
 for fuzzer_name in parse_json parse_ltsv parse_logfmt
 do
     $CC $CFLAGS -c ${fuzzer_name}_fuzzer.c -o ${fuzzer_name}_fuzzer.o -I/src/fluent-bit/include -I/src/fluent-bit/lib -I/src/fluent-bit/lib/flb_libco -I/src/fluent-bit/lib/rbtree -I/src/fluent-bit/lib/msgpack-3.2.0/include -I/src/fluent-bit/lib/chunkio/include -I/src/fluent-bit/lib/LuaJIT-2.1.0-beta3/src -I/src/fluent-bit/lib/monkey/include -I/src/fluent-bit/lib/mbedtls-2.16.5/include -I/src/fluent-bit/lib/sqlite-amalgamation-3310000 -I/src/fluent-bit/lib/mpack-amalgamation-1.0/src -I/src/fluent-bit/lib/miniz -I/src/fluent-bit/lib/onigmo -I/src/fluent-bit/build/include -I/src/fluent-bit/lib/tutf8e/include -I/src/fluent-bit/build/backtrace-prefix/include -I/src/fluent-bit/build/lib/msgpack-3.2.0/include
+
     $CXX ${fuzzer_name}_fuzzer.o -o $OUT/${fuzzer_name}_fuzzer $CXXFLAGS $LIB_FUZZING_ENGINE library/libfluent-bit.a library/libflb-plugin-in_emitter.a library/libflb-plugin-in_dummy.a library/libflb-plugin-in_statsd.a library/libflb-plugin-in_storage_backlog.a library/libflb-plugin-in_lib.a library/libflb-plugin-out_exit.a library/libflb-plugin-out_logdna.a library/libflb-plugin-out_newrelic.a library/libflb-plugin-out_td.a library/libflb-plugin-out_lib.a library/libflb-plugin-filter_stdout.a library/libfluent-bit.a -lm -lrt library/libmk_core.a library/libjsmn.a library/libmsgpackc.a library/libmpack-static.a library/libchunkio-static.a library/libcio-crc32.a library/libminiz.a library/libflb-plugin-proxy-go.a library/libmbedtls.a library/libmbedx509.a library/libmbedcrypto.a library/libco.a library/librbtree.a lib/libonigmo.a library/libsqlite3.a -ldl library/libtutf8e.a
 done
diff --git a/projects/gdal/Dockerfile b/projects/gdal/Dockerfile
index 17b57f9..f3004c2 100644
--- a/projects/gdal/Dockerfile
+++ b/projects/gdal/Dockerfile
@@ -22,24 +22,6 @@
 
 RUN git clone --depth 1 https://github.com/OSGeo/gdal gdal
 
-RUN git clone --depth 1 https://github.com/OSGeo/proj.4 gdal/proj
-
-RUN git clone --depth 1 https://github.com/curl/curl.git gdal/curl
-
-COPY NC4_put_propattr_leak_fix.patch libnetcdf_fix_undefined_left_shift_in_ncx_get_size_t.patch $SRC/
-
-RUN curl https://src.fedoraproject.org/lookaside/pkgs/netcdf/netcdf-4.4.1.1.tar.gz/9210fd5355bee868684d9b8f83064aa6/netcdf-4.4.1.1.tar.gz > gdal/netcdf-4.4.1.1.tar.gz && \
-    cd gdal && \
-    tar xzf netcdf-4.4.1.1.tar.gz && \
-    rm -f netcdf-4.4.1.1.tar.gz && \
-    mv netcdf-c-4.4.1.1 netcdf-4.4.1.1 && \
-    cd netcdf-4.4.1.1 && \
-    patch -p0 < $SRC/NC4_put_propattr_leak_fix.patch && \
-    patch -p0 < $SRC/libnetcdf_fix_undefined_left_shift_in_ncx_get_size_t.patch && \
-    cd ../..
-
-RUN git clone --depth 1 https://anongit.freedesktop.org/git/poppler/poppler.git gdal/poppler
-
 RUN cp gdal/gdal/fuzzers/build.sh $SRC/
 
 WORKDIR gdal
diff --git a/projects/gdal/NC4_put_propattr_leak_fix.patch b/projects/gdal/NC4_put_propattr_leak_fix.patch
deleted file mode 100644
index 55908aa..0000000
--- a/projects/gdal/NC4_put_propattr_leak_fix.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- libsrc4/nc4info.c.ori	2017-06-07 10:28:11.478130590 +0200
-+++ libsrc4/nc4info.c	2017-06-07 10:28:29.670268763 +0200
-@@ -174,11 +174,8 @@
-       herr = 0;
-     }
-  done:
--    if(ncstat != NC_NOERR) {
--      if(text != NULL) {
--        free(text);
--        text = NULL;
--      }
-+    if(text != NULL) {
-+      free(text);
-     }
- 
-     if(attid >= 0) HCHECK((H5Aclose(attid)));
diff --git a/projects/gdal/libnetcdf_fix_undefined_left_shift_in_ncx_get_size_t.patch b/projects/gdal/libnetcdf_fix_undefined_left_shift_in_ncx_get_size_t.patch
deleted file mode 100644
index e0b886d..0000000
--- a/projects/gdal/libnetcdf_fix_undefined_left_shift_in_ncx_get_size_t.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- libsrc/ncx.m4.ori	2017-06-15 12:45:29.461345214 +0200
-+++ libsrc/ncx.m4	2017-06-23 12:14:29.263652717 +0200
-@@ -726,7 +726,11 @@
- {
- 	const uchar *cp = (const uchar *) xp;
- 
-+#if INT_MAX  >= X_INT_MAX
-+	*ip = (ix_int)((unsigned)(*cp++) << 24);
-+#else
- 	*ip = *cp++ << 24;
-+#endif
- #if SIZEOF_IX_INT > X_SIZEOF_INT
- 	if(*ip & 0x80000000)
- 	{
-@@ -1883,7 +1887,7 @@
- 	/* similar to get_ix_int */
- 	const uchar *cp = (const uchar *) *xpp;
- 
--	*ulp = (unsigned)(*cp++ << 24);
-+	*ulp = (unsigned)(*cp++) << 24;
- 	*ulp |= (*cp++ << 16);
- 	*ulp |= (*cp++ << 8);
- 	*ulp |= *cp;
---- libsrc/ncx.c.ori	2017-06-15 12:38:29.769770935 +0200
-+++ libsrc/ncx.c	2017-06-23 12:10:38.359973119 +0200
-@@ -1031,7 +1031,11 @@
- {
- 	const uchar *cp = (const uchar *) xp;
- 
-+#if INT_MAX  >= X_INT_MAX
-+	*ip = (ix_int)((unsigned)(*cp++) << 24);
-+#else
- 	*ip = *cp++ << 24;
-+#endif
- #if SIZEOF_IX_INT > X_SIZEOF_INT
- 	if(*ip & 0x80000000)
- 	{
-@@ -3451,7 +3455,7 @@
- 	/* similar to get_ix_int */
- 	const uchar *cp = (const uchar *) *xpp;
- 
--	*ulp = (unsigned)(*cp++ << 24);
-+	*ulp = (unsigned)(*cp++) << 24;
- 	*ulp |= (*cp++ << 16);
- 	*ulp |= (*cp++ << 8);
- 	*ulp |= *cp;
diff --git a/projects/go-coredns/Dockerfile b/projects/go-coredns/Dockerfile
new file mode 100644
index 0000000..e8cb195
--- /dev/null
+++ b/projects/go-coredns/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER miek@miek.nl
+RUN git clone --depth 1 https://github.com/coredns/coredns coredns
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/go-coredns/build.sh b/projects/go-coredns/build.sh
new file mode 100755
index 0000000..47958f8
--- /dev/null
+++ b/projects/go-coredns/build.sh
@@ -0,0 +1,39 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Same as usual except for added -tags gofuzz.
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  # Compile and instrument all Go files relevant to this fuzz target.
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  # Link Go code ($fuzzer.a) with fuzzing engine to produce fuzz target binary.
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+cd coredns
+#make
+ls plugin/*/fuzz.go | while read target
+do
+    fuzzed_plugin=`echo $target | cut -d'/' -f 2`
+    compile_fuzzer github.com/coredns/coredns/plugin/$fuzzed_plugin Fuzz fuzz_plugin_$fuzzed_plugin
+done
+
+compile_fuzzer github.com/coredns/coredns/test Fuzz fuzz_core
diff --git a/projects/go-coredns/project.yaml b/projects/go-coredns/project.yaml
new file mode 100644
index 0000000..da4504b
--- /dev/null
+++ b/projects/go-coredns/project.yaml
@@ -0,0 +1,10 @@
+homepage: "https://coredns.io"
+primary_contact: "security@coredns.io"
+auto_ccs :
+- "miek@miek.nl"
+- "p.antoine@catenacyber.fr"
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/gopacket/Dockerfile b/projects/gopacket/Dockerfile
new file mode 100644
index 0000000..f8816e5
--- /dev/null
+++ b/projects/gopacket/Dockerfile
@@ -0,0 +1,21 @@
+# Copyright 2019 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+RUN go get github.com/google/gopacket
+
+COPY build.sh $SRC/
+WORKDIR $SRC
diff --git a/projects/gopacket/build.sh b/projects/gopacket/build.sh
new file mode 100755
index 0000000..f19f85e
--- /dev/null
+++ b/projects/gopacket/build.sh
@@ -0,0 +1,30 @@
+#!/bin/bash -eu
+# Copyright 2019 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  # Compile and instrument all Go files relevant to this fuzz target.
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  # Link Go code ($fuzzer.a) with fuzzing engine to produce fuzz target binary.
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_fuzzer github.com/google/gopacket/layers FuzzLayer fuzz_layers
diff --git a/projects/gopacket/project.yaml b/projects/gopacket/project.yaml
new file mode 100644
index 0000000..04135b6
--- /dev/null
+++ b/projects/gopacket/project.yaml
@@ -0,0 +1,10 @@
+homepage: "https://github.com/google/gopacket"
+primary_contact: "gconnell@google.com"
+auto_ccs :
+- "p.antoine@catenacyber.fr"
+
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/grpc-gateway/Dockerfile b/projects/grpc-gateway/Dockerfile
new file mode 100644
index 0000000..deeaa22
--- /dev/null
+++ b/projects/grpc-gateway/Dockerfile
@@ -0,0 +1,21 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/grpc-gateway/build.sh b/projects/grpc-gateway/build.sh
new file mode 100755
index 0000000..c775de1
--- /dev/null
+++ b/projects/grpc-gateway/build.sh
@@ -0,0 +1,27 @@
+#/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_fuzzer github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule Fuzz fuzz
diff --git a/projects/grpc-gateway/project.yaml b/projects/grpc-gateway/project.yaml
new file mode 100644
index 0000000..a8ae95b
--- /dev/null
+++ b/projects/grpc-gateway/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/grpc-ecosystem/grpc-gateway"
+primary_contact: "grpc-gateway-maintainers@googlegroups.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/haproxy/build.sh b/projects/haproxy/build.sh
index 7dc4d4e..7b41b81 100755
--- a/projects/haproxy/build.sh
+++ b/projects/haproxy/build.sh
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-################################################################################
 export ORIG_CFLAGS=${CFLAGS}
 cd haproxy
 
@@ -24,20 +23,23 @@
 sed 's/LDFLAGS = $(ARCH_FLAGS) -g/LDFLAGS = $(ARCH_FLAGS) -g ${CXXFLAGS}/g' -i Makefile
 make TARGET=generic
 
-cd contrib/hpack
-cp /src/fuzz_hpack_decode.c .
-$CC $CFLAGS -g -I../../include -I../../ebtree -fwrapv -fno-strict-aliasing -c fuzz_hpack_decode.c  -o fuzz_hpack_decode.o
-$CXX $CXXFLAGS $LIB_FUZZING_ENGINE ./fuzz_hpack_decode.o -o $OUT/fuzz_hpack_decode
-
 # Make a copy of the main file since it has many global functions we need to declare
 # We dont want the main function but we need the rest of the stuff in haproxy.c
 cd /src/haproxy
 sed 's/int main(int argc/int main2(int argc/g' -i ./src/haproxy.c
+sed 's/dladdr(main,/dladdr(main2,/g' -i ./src/standard.c
+sed 's/(void*)main/(void*)main2/g' -i ./src/standard.c
+
 $CC $CFLAGS -Iinclude -Iebtree  -g -DUSE_POLL -DUSE_TPROXY -DCONFIG_HAPROXY_VERSION=\"\" -DCONFIG_HAPROXY_DATE=\"\" -c -o ./src/haproxy.o ./src/haproxy.c
 ar cr libetree.a ./ebtree/*.o
 ar cr libhaproxy.a ./src/*.o
 
+cp $SRC/fuzz_hpack_decode.c .
+$CC $CFLAGS -Iinclude -Iebtree  -g  -DUSE_POLL -DUSE_TPROXY -DCONFIG_HAPROXY_VERSION=\"\" -DCONFIG_HAPROXY_DATE=\"\" -c fuzz_hpack_decode.c  -o fuzz_hpack_decode.o
+$CXX -g $CXXFLAGS $LIB_FUZZING_ENGINE  fuzz_hpack_decode.o libhaproxy.a libetree.a -o $OUT/fuzz_hpack_decode
+
 # Now compile more fuzzers
 cp $SRC/fuzz_cfg_parser.c .
 $CC $CFLAGS -Iinclude -Iebtree  -g  -DUSE_POLL -DUSE_TPROXY -DCONFIG_HAPROXY_VERSION=\"\" -DCONFIG_HAPROXY_DATE=\"\" -c -o fuzz_cfg_parser.o fuzz_cfg_parser.c
 $CXX -g $CXXFLAGS $LIB_FUZZING_ENGINE  fuzz_cfg_parser.o libhaproxy.a libetree.a -o $OUT/fuzz_cfg_parser
+################################################################################
diff --git a/projects/haproxy/fuzz_hpack_decode.c b/projects/haproxy/fuzz_hpack_decode.c
index 563f91b..32c0b3e 100644
--- a/projects/haproxy/fuzz_hpack_decode.c
+++ b/projects/haproxy/fuzz_hpack_decode.c
@@ -23,9 +23,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+
 #include <common/chunk.h>
 #include <common/hpack-dec.h>
 #include <common/mini-clist.h>
+#define HPACK_STANDALONE
 
 #define MAX_RQ_SIZE 65536
 #define MAX_HDR_NUM 1000
@@ -36,10 +38,8 @@
 char trash_buf[MAX_RQ_SIZE];
 char tmp_buf[MAX_RQ_SIZE];
 
-struct buffer trash = { .area = trash_buf, .data = 0, .size = sizeof(trash_buf) };
 struct buffer tmp   = { .area = tmp_buf,   .data = 0, .size = sizeof(tmp_buf)   };
 
-
 /* Empty function we dont need - we just need a callback */
 void debug_hexdump(FILE *out, const char *pfx, const char *buf,
                    unsigned int baseaddr, int len)
@@ -54,21 +54,27 @@
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size){
         char *new_str = (char *)malloc(size+1);
         struct hpack_dht *dht;
+        struct pool_head pool;
         int dht_size = 4096;
         if (new_str == NULL){
                 return 0;
         }
         memcpy(new_str, data, size);
         new_str[size] = '\0';
-        struct http_hdr list[MAX_HDR_NUM];      
+        struct http_hdr list[MAX_HDR_NUM];
 
-        dht = hpack_dht_alloc(dht_size);
-        hpack_decode_frame(dht, new_str, size, list,sizeof(list)/sizeof(list[0]), &tmp);
+        pool.size = dht_size;
+        pool_head_hpack_tbl = &pool;
+        dht = hpack_dht_alloc();
+
         if (dht != NULL)
         {
-            free(dht);
+            hpack_decode_frame(dht, new_str, size, list,sizeof(list)/sizeof(list[0]), &tmp);
+            if (dht != NULL)
+            {
+                free(dht);
+            }
         }
-
         free(new_str);
         return 0;
 }
diff --git a/projects/haproxy/project.yaml b/projects/haproxy/project.yaml
index 2b66c59..f1400c2 100755
--- a/projects/haproxy/project.yaml
+++ b/projects/haproxy/project.yaml
@@ -1,9 +1,9 @@
 homepage: "https://github.com/haproxy/haproxy"
-primary_contact: "fuzzing@haproxy.org"
+primary_contact: "adam@adalogics.com"
 language: c++
 auto_ccs:
   - "david@adalogics.com"
-  - "adam@adalogics.com"
+  - "timwolla@googlemail.com"
+  - "willy@1wt.eu"
 sanitizers:
   - address
-  - memory
diff --git a/projects/hermes/Dockerfile b/projects/hermes/Dockerfile
new file mode 100644
index 0000000..d88b2cd
--- /dev/null
+++ b/projects/hermes/Dockerfile
@@ -0,0 +1,28 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER neildhar@fb.com
+RUN apt-get update && \
+    apt-get install -y make autoconf automake libtool wget libicu-dev \
+    ninja-build python zip libreadline-dev libatomic-ops-dev
+# Install cmake
+RUN wget https://github.com/Kitware/CMake/releases/download/v3.16.6/cmake-3.16.6-Linux-x86_64.sh; \
+    chmod +x cmake-3.16.6-Linux-x86_64.sh; \
+    ./cmake-3.16.6-Linux-x86_64.sh --skip-license --prefix="/usr/local"
+RUN git clone https://github.com/facebook/hermes.git
+WORKDIR hermes
+COPY build.sh $SRC/
diff --git a/projects/hermes/build.sh b/projects/hermes/build.sh
new file mode 100755
index 0000000..abc0909
--- /dev/null
+++ b/projects/hermes/build.sh
@@ -0,0 +1,31 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+if [ "${SANITIZER}" = address ]
+then
+    CONFIGURE_FLAGS="--enable-asan"
+elif [ "${SANITIZER}" = undefined ]
+then
+    CONFIGURE_FLAGS="--enable-ubsan"
+else
+    CONFIGURE_FLAGS=""
+fi
+
+./utils/build/configure.py "${OUT}/build" --build-system "Ninja" ${CONFIGURE_FLAGS} \
+                           --cmake-flags="-DHERMES_USE_STATIC_ICU=ON -DHERMES_FUZZING_FLAG=${LIB_FUZZING_ENGINE}"
+cmake --build "$OUT/build"  --parallel --target fuzzer-jsi-entry
+cp "${OUT}/build/bin/fuzzer-jsi-entry" "${OUT}"
diff --git a/projects/hermes/project.yaml b/projects/hermes/project.yaml
new file mode 100644
index 0000000..642e994
--- /dev/null
+++ b/projects/hermes/project.yaml
@@ -0,0 +1,14 @@
+homepage: "https://github.com/facebook/hermes"
+language: c++
+primary_contact: "neildhar@fb.com"
+auto_ccs:
+  - "dulinr@fb.com"
+  - "mhl@fb.com"
+vendor_ccs:
+  - "oss-fuzz@fb.com"
+fuzzing_engines:
+  - libfuzzer
+  - afl
+sanitizers:
+  - address
+  - undefined
diff --git a/projects/ipfs/Dockerfile b/projects/ipfs/Dockerfile
new file mode 100644
index 0000000..cd3eb78
--- /dev/null
+++ b/projects/ipfs/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER will.scott@protocol.io
+RUN go get -t github.com/ipfs/go-datastore
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/ipfs/build.sh b/projects/ipfs/build.sh
new file mode 100755
index 0000000..65c2d25
--- /dev/null
+++ b/projects/ipfs/build.sh
@@ -0,0 +1,46 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+cd $GOPATH/src/github.com/ipfs/go-datastore/fuzz
+
+function compile_ds_fuzzer {
+  fuzzer=$1
+
+  if [ $# == 2 ]; then
+    rm provider* || true
+    DS_PROVIDERS="$2" go generate
+  fi
+
+  # vendor dependencies since go-fuzz doesn't play nicely with go mod.
+  rm -rf vendor .gopath || true
+  go mod vendor
+  mkdir .gopath
+  cd .gopath
+  ln -s ../vendor src
+  cd ..
+
+  # Compile and instrument all Go files relevant to this fuzz target.
+  GO111MODULE=off GOPATH=$PWD/.gopath go-fuzz -o $fuzzer.a .
+
+  # Link Go code ($fuzzer.a) with fuzzing engine to produce fuzz target binary.
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_ds_fuzzer ipfs_ds_flatfs
+compile_ds_fuzzer ipfs_ds_badger "github.com/ipfs/go-ds-badger"
+compile_ds_fuzzer ipfs_ds_badger2 "github.com/ipfs/go-ds-badger2"
+
diff --git a/projects/ipfs/project.yaml b/projects/ipfs/project.yaml
new file mode 100644
index 0000000..dadaae6
--- /dev/null
+++ b/projects/ipfs/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/ipfs/go-datastore"
+primary_contact: "will.scott@protocol.ai"
+auto_ccs :
+- "stebalien@protocol.ai"
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/jsoncpp/build.sh b/projects/jsoncpp/build.sh
index 8bb8f00..6c55653 100644
--- a/projects/jsoncpp/build.sh
+++ b/projects/jsoncpp/build.sh
@@ -24,7 +24,7 @@
 # Compile fuzzer.
 $CXX $CXXFLAGS -I../include $LIB_FUZZING_ENGINE \
     ../src/test_lib_json/fuzz.cpp -o $OUT/jsoncpp_fuzzer \
-    src/lib_json/libjsoncpp.a
+    lib/libjsoncpp.a
 
 # Add dictionary.
 cp $SRC/jsoncpp/src/test_lib_json/fuzz.dict $OUT/jsoncpp_fuzzer.dict
diff --git a/projects/jsoncpp/project.yaml b/projects/jsoncpp/project.yaml
index bfc26c2..97c2844 100644
--- a/projects/jsoncpp/project.yaml
+++ b/projects/jsoncpp/project.yaml
@@ -1,6 +1,6 @@
 homepage: "https://github.com/open-source-parsers/jsoncpp/"
 language: c++
-primary_contact: "cdunn2001@gmail.com"
+primary_contact: "chenguopingdota@163.com"
 auto_ccs:
  - "jophba@chromium.org"
 sanitizers:
diff --git a/projects/jsonparser/Dockerfile b/projects/jsonparser/Dockerfile
new file mode 100644
index 0000000..59f56a6
--- /dev/null
+++ b/projects/jsonparser/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get github.com/buger/jsonparser
+
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/jsonparser/build.sh b/projects/jsonparser/build.sh
new file mode 100755
index 0000000..92a0c90
--- /dev/null
+++ b/projects/jsonparser/build.sh
@@ -0,0 +1,28 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+
+compile_fuzzer github.com/buger/jsonparser FuzzParseString fuzz
diff --git a/projects/jsonparser/project.yaml b/projects/jsonparser/project.yaml
new file mode 100644
index 0000000..3141924
--- /dev/null
+++ b/projects/jsonparser/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/buger/jsonparser"
+primary_contact: "leonsbox@gmail.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+- libfuzzer
+sanitizers:
+- address
diff --git a/projects/knot-dns/Dockerfile b/projects/knot-dns/Dockerfile
index 4977181..7583895 100644
--- a/projects/knot-dns/Dockerfile
+++ b/projects/knot-dns/Dockerfile
@@ -37,6 +37,7 @@
 RUN git clone --depth=1 --recursive https://git.savannah.gnu.org/git/libunistring.git
 RUN git clone --depth=1 https://git.lysator.liu.se/nettle/nettle.git
 RUN git clone --depth=1 https://gitlab.com/gnutls/gnutls.git
+RUN git clone --depth=1 https://github.com/LMDB/lmdb.git
 RUN git clone --depth=1 https://gitlab.labs.nic.cz/knot/knot-dns
 
 WORKDIR knot-dns
diff --git a/projects/knot-dns/build.sh b/projects/knot-dns/build.sh
index 05fe836..e451813 100755
--- a/projects/knot-dns/build.sh
+++ b/projects/knot-dns/build.sh
@@ -56,20 +56,22 @@
 make -j$(nproc)
 make install
 
+cd $SRC/lmdb/libraries/liblmdb
+make -j$(nproc)
+make install
 
 # Compile knot, install fuzzers to $OUT
 
 cd $SRC/knot-dns
+sed -i 's/-llmdb/-Wl,-Bstatic,-llmdb,-Bdynamic/' configure.ac
 autoreconf -if
-
-./configure --with-oss-fuzz=yes --disable-shared --enable-static --disable-daemon --disable-utilities --disable-documentation --disable-fastparser --disable-modules
-
+./configure --with-oss-fuzz=yes --disable-shared --enable-static --disable-daemon --disable-utilities --disable-documentation \
+    --disable-fastparser --disable-modules
 make -j$(nproc)
 cd $SRC/knot-dns/tests-fuzz
 make check
 /bin/bash ../libtool   --mode=install /usr/bin/install -c fuzz_packet fuzz_zscanner fuzz_dname_to_str fuzz_dname_from_str "$OUT"
 
-
 # Set up fuzzing seeds
 
 git submodule update --init -- ./fuzz_packet.in
diff --git a/projects/leptonica/build.sh b/projects/leptonica/build.sh
index 4e37800..ee51bdc 100755
--- a/projects/leptonica/build.sh
+++ b/projects/leptonica/build.sh
@@ -15,139 +15,5 @@
 #
 ################################################################################
 
-# libz
-pushd $SRC/zlib
-./configure --static --prefix="$WORK"
-make -j$(nproc) all
-make install
-popd
+$SRC/leptonica/prog/fuzzing/oss-fuzz-build.sh
 
-# libzstd
-pushd $SRC/zstd
-make -j$(nproc) install PREFIX="$WORK"
-popd
-
-# libjbig
-pushd "$SRC/jbigkit"
-make clean
-make -j$(nproc) lib
-cp "$SRC"/jbigkit/libjbig/*.a "$WORK/lib/"
-cp "$SRC"/jbigkit/libjbig/*.h "$WORK/include/"
-popd
-
-# libjpeg-turbo
-pushd $SRC/libjpeg-turbo
-cmake . -DCMAKE_INSTALL_PREFIX="$WORK" -DENABLE_STATIC:bool=on
-make -j$(nproc)
-make install
-popd
-
-# libpng
-pushd $SRC/libpng
-cat scripts/pnglibconf.dfa | \
-  sed -e "s/option WARNING /option WARNING disabled/" \
-> scripts/pnglibconf.dfa.temp
-mv scripts/pnglibconf.dfa.temp scripts/pnglibconf.dfa
-autoreconf -f -i
-./configure \
-  --prefix="$WORK" \
-  --disable-shared \
-  --enable-static \
-  LDFLAGS="-L$WORK/lib" \
-  CPPFLAGS="-I$WORK/include"
-make -j$(nproc)
-make install
-popd
-
-# libwebp
-pushd $SRC/libwebp
-export WEBP_CFLAGS="$CFLAGS -DWEBP_MAX_IMAGE_SIZE=838860800" # 800MiB
-./autogen.sh
-./configure \
-  --enable-libwebpdemux \
-  --enable-libwebpmux \
-  --disable-shared \
-  --disable-jpeg \
-  --disable-tiff \
-  --disable-gif \
-  --disable-wic \
-  --disable-threading \
-  --prefix="$WORK" \
-  CFLAGS="$WEBP_CFLAGS"
-make clean
-make -j$(nproc)
-make install
-popd
-
-# libtiff
-pushd "$SRC/libtiff"
-cmake . -DCMAKE_INSTALL_PREFIX="$WORK" -DBUILD_SHARED_LIBS=off
-make clean
-make -j$(nproc)
-make install
-popd
-
-# leptonica
-export LEPTONICA_LIBS="$WORK/lib/libjbig.a $WORK/lib/libzstd.a $WORK/lib/libwebp.a $WORK/lib/libpng.a"
-./autogen.sh
-./configure \
-  --enable-static \
-  --disable-shared \
-  --with-libpng \
-  --with-zlib \
-  --with-jpeg \
-  --with-libwebp \
-  --with-libtiff \
-  --prefix="$WORK" \
-  LIBS="$LEPTONICA_LIBS" \
-  LDFLAGS="-L$WORK/lib" \
-  CPPFLAGS="-I$WORK/include"
-make -j$(nproc)
-make install
-
-$CXX $CXXFLAGS -std=c++11 -I"$WORK/include" \
-  "$SRC/leptonica/prog/fuzzing/pix_rotate_shear_fuzzer.cc"\
-  -o "$OUT/pix_rotate_shear_fuzzer" \
-  "$WORK/lib/liblept.a" \
-  "$WORK/lib/libtiff.a" \
-  "$WORK/lib/libwebp.a" \
-  "$WORK/lib/libpng.a" \
-  "$WORK/lib/libjpeg.a" \
-  "$WORK/lib/libjbig.a" \
-  "$WORK/lib/libzstd.a" \
-  "$WORK/lib/libz.a" \
-  $LIB_FUZZING_ENGINE
-
-$CXX $CXXFLAGS -std=c++11 -I"$WORK/include" \
-  "$SRC/leptonica/prog/fuzzing/pixa_recog_fuzzer.cc"\
-  -o "$OUT/pixa_recog_fuzzer" \
-  -Isrc/ \
-  "$WORK/lib/liblept.a" \
-  "$WORK/lib/libtiff.a" \
-  "$WORK/lib/libwebp.a" \
-  "$WORK/lib/libpng.a" \
-  "$WORK/lib/libjpeg.a" \
-  "$WORK/lib/libjbig.a" \
-  "$WORK/lib/libzstd.a" \
-  "$WORK/lib/libz.a" \
-  $LIB_FUZZING_ENGINE
-
-$CXX $CXXFLAGS -std=c++11 -I"$WORK/include" \
-  "$SRC/leptonica/prog/fuzzing/enhance_fuzzer.cc"\
-  -o "$OUT/enhance_fuzzer" \
-  -Isrc/ \
-  "$WORK/lib/liblept.a" \
-  "$WORK/lib/libtiff.a" \
-  "$WORK/lib/libwebp.a" \
-  "$WORK/lib/libpng.a" \
-  "$WORK/lib/libjpeg.a" \
-  "$WORK/lib/libjbig.a" \
-  "$WORK/lib/libzstd.a" \
-  "$WORK/lib/libz.a" \
-  $LIB_FUZZING_ENGINE
-
-
-cp $SRC/leptonica/prog/fuzzing/general_corpus.zip $OUT/pix_rotate_shear_fuzzer_seed_corpus.zip
-cp $SRC/leptonica/prog/fuzzing/general_corpus.zip $OUT/enhance_fuzzer_seed_corpus.zip
-
-cp $SRC/leptonica/prog/fuzzing/pixa_recog_fuzzer_seed_corpus.zip $OUT/
diff --git a/projects/libfido2/Dockerfile b/projects/libfido2/Dockerfile
index a836253..29fc7fb 100644
--- a/projects/libfido2/Dockerfile
+++ b/projects/libfido2/Dockerfile
@@ -18,7 +18,7 @@
 MAINTAINER g.kihlman@yubico.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool
 RUN apt-get install -y cmake libudev-dev pkg-config chrpath
-RUN git clone --branch v0.5.0 https://github.com/PJK/libcbor
+RUN git clone --branch v0.7.0 https://github.com/PJK/libcbor
 RUN git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl
 RUN git clone https://github.com/Yubico/libfido2
 # CIFuzz will replace the libfido directory so put the corpus outside
diff --git a/projects/libgd/Dockerfile b/projects/libgd/Dockerfile
index a85269e..617b0a5 100644
--- a/projects/libgd/Dockerfile
+++ b/projects/libgd/Dockerfile
@@ -21,4 +21,4 @@
 RUN git clone --depth 1 https://github.com/libgd/libgd
 ADD https://lcamtuf.coredump.cx/afl/demo/afl_testcases.tgz $SRC/afl_testcases.tgz
 WORKDIR libgd
-COPY build.sh parser_target.cc $SRC/
+COPY build.sh *.cc $SRC/
diff --git a/projects/libgd/build.sh b/projects/libgd/build.sh
index c49d21b..4aabb06 100755
--- a/projects/libgd/build.sh
+++ b/projects/libgd/build.sh
@@ -32,6 +32,13 @@
       $LIB_FUZZING_ENGINE -lgd -Wl,-Bstatic -lz -Wl,-Bdynamic
 done
 
+for fuzzers in $(find $SRC -name '*_fuzzer.cc'); do
+      fuzz_basename=$(basename -s .cc $fuzzers)
+      $CXX $CXXFLAGS -std=c++11 -I"$WORK/include" -L"$WORK/lib" \
+      $fuzzers -o $OUT/$fuzz_basename \
+      $LIB_FUZZING_ENGINE -lgd -Wl,-Bstatic -lz -Wl,-Bdynamic
+done
+
 mkdir afl_testcases
 (cd afl_testcases; tar xvf "$SRC/afl_testcases.tgz")
 for format in bmp gif png webp; do
diff --git a/projects/libgd/gd_image_string_fuzzer.cc b/projects/libgd/gd_image_string_fuzzer.cc
new file mode 100644
index 0000000..f3435cc
--- /dev/null
+++ b/projects/libgd/gd_image_string_fuzzer.cc
@@ -0,0 +1,53 @@
+// Copyright 2020 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+
+#include "gd.h"
+#include "gdfontg.h"
+#include "gdfontl.h"
+#include "gdfontmb.h"
+#include "gdfonts.h"
+#include "gdfontt.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider stream(data, size);
+    const uint8_t slate_width = stream.ConsumeIntegral<uint8_t>();
+    const uint8_t slate_height = stream.ConsumeIntegral<uint8_t>();
+    gdImagePtr slate_image = gdImageCreateTrueColor(slate_width, slate_height);
+    if (slate_image == nullptr) {
+      return 0;
+    }
+
+    const int x_position = stream.ConsumeIntegral<int>();
+    const int y_position = stream.ConsumeIntegral<int>();
+    const int text_color = stream.ConsumeIntegral<int>();
+    const gdFontPtr font_ptr = stream.PickValueInArray(
+        {gdFontGetGiant(), gdFontGetLarge(), gdFontGetMediumBold(),
+        gdFontGetSmall(), gdFontGetTiny()});
+    const std::string text = stream.ConsumeRemainingBytesAsString();
+
+    gdImageString(slate_image, font_ptr, x_position, y_position,
+                  reinterpret_cast<uint8_t*>(const_cast<char*>(text.c_str())),
+                  text_color);
+    gdImageDestroy(slate_image);
+    return 0;
+}
diff --git a/projects/libpcap/Dockerfile b/projects/libpcap/Dockerfile
index f7acf86..3879928 100644
--- a/projects/libpcap/Dockerfile
+++ b/projects/libpcap/Dockerfile
@@ -22,5 +22,4 @@
 RUN git clone --depth=1 https://github.com/the-tcpdump-group/tcpdump.git tcpdump
 WORKDIR $SRC
 COPY build.sh $SRC/
-COPY patch.diff $SRC/
 
diff --git a/projects/libpcap/build.sh b/projects/libpcap/build.sh
index e44f8b8..75463b3 100755
--- a/projects/libpcap/build.sh
+++ b/projects/libpcap/build.sh
@@ -17,7 +17,6 @@
 
 cd libpcap
 # build project
-git apply ../patch.diff
 mkdir build
 cd build
 cmake ..
diff --git a/projects/libpcap/patch.diff b/projects/libpcap/patch.diff
deleted file mode 100644
index c76b339..0000000
--- a/projects/libpcap/patch.diff
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/optimize.c b/optimize.c
-index 4afd063f..90e8c571 100644
---- a/optimize.c
-+++ b/optimize.c
-@@ -1888,7 +1888,7 @@ opt_root(struct block **b)
- static void
- opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
- {
--
-+	int loopCounter = 0;
- #ifdef BDEBUG
- 	if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
- 		printf("opt_loop(root, %d) begin\n", do_stmts);
-@@ -1909,6 +1909,10 @@ opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
- 			opt_dump(opt_state, ic);
- 		}
- #endif
-+		loopCounter++;
-+		if (loopCounter > 1000) {
-+			break;
-+		}
- 	} while (!opt_state->done);
- }
- 
diff --git a/projects/libra/Dockerfile b/projects/libra/Dockerfile
index 61a4a74..3a2cd4d 100644
--- a/projects/libra/Dockerfile
+++ b/projects/libra/Dockerfile
@@ -21,10 +21,6 @@
 # install other tools we might need
 RUN apt-get update && apt-get install -y cmake curl
 
-# install rust and cargo-fuzz
-ENV CARGO_HOME=/rust RUSTUP_HOME=/rust/rustup PATH=$PATH:/rust/bin
-RUN curl https://sh.rustup.rs | sh -s -- -y 
-
 # get libra
 RUN git clone --depth 1 https://github.com/libra/libra $SRC/libra
 WORKDIR $SRC/libra
diff --git a/projects/libra/build.sh b/projects/libra/build.sh
index c778169..c80e5dc 100644
--- a/projects/libra/build.sh
+++ b/projects/libra/build.sh
@@ -56,9 +56,6 @@
 export CUSTOM_LIBFUZZER_STD_CXX=c++
 # export CUSTOM_LIBFUZZER_STD_CXX=none 
 
-# RUSTC_BOOTSTRAP: to get some nightly features like ASAN
-export RUSTC_BOOTSTRAP=1 
-
 # export fuzzing flags
 RUSTFLAGS="$RUSTFLAGS --cfg fuzzing"          # used to change code logic
 RUSTFLAGS="$RUSTFLAGS -Cdebug-assertions"     # to get debug_assert in rust
diff --git a/projects/libspectre/Dockerfile b/projects/libspectre/Dockerfile
index 13e8243..3d8782e 100755
--- a/projects/libspectre/Dockerfile
+++ b/projects/libspectre/Dockerfile
@@ -23,8 +23,9 @@
 
 RUN git clone --depth 1 https://gitlab.freedesktop.org/libspectre/libspectre.git
 
-RUN wget -O $SRC/libspectre/ghostscript-9.50.tar.gz https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs950/ghostscript-9.50.tar.gz
-RUN tar xvzf $SRC/libspectre/ghostscript-9.50.tar.gz --directory $SRC/libspectre/
+RUN wget -O $SRC/libspectre/ghostscript-9.52.tar.gz https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs952/ghostscript-9.52.tar.gz
+RUN tar xvzf $SRC/libspectre/ghostscript-9.52.tar.gz --directory $SRC/libspectre/
+RUN mv $SRC/libspectre/ghostscript-9.52 $SRC/libspectre/ghostscript
 
 WORKDIR $SRC/libspectre/
 COPY build.sh $SRC/
diff --git a/projects/libssh/build.sh b/projects/libssh/build.sh
index a45c325..b0a3d15 100644
--- a/projects/libssh/build.sh
+++ b/projects/libssh/build.sh
@@ -20,14 +20,14 @@
 pushd $BUILD
 cmake -DCMAKE_C_COMPILER="$CC" -DCMAKE_CXX_COMPILER="$CXX" \
     -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS" \
-    -DBUILD_SHARED_LIBS=OFF $SRC/libssh
+    -DBUILD_SHARED_LIBS=OFF -DWITH_INSECURE_NONE=ON $SRC/libssh
 make "-j$(nproc)"
 
 fuzzers=$(find $SRC/libssh/tests/fuzz/ -name "*_fuzzer.cpp")
 for f in $fuzzers; do
     fuzzerName=$(basename $f .cpp)
     echo "Building fuzzer $fuzzerName"
-    $CXX $CXXFLAGS -std=c++11 -I$SRC/libssh/include/ \
+    $CXX $CXXFLAGS -std=c++11 -I$SRC/libssh/include/ -I$BUILD/include/ \
         "$f" -o "$OUT/$fuzzerName" \
         $LIB_FUZZING_ENGINE ./src/libssh.a -Wl,-Bstatic -lcrypto -lz -Wl,-Bdynamic
 
diff --git a/projects/libtasn1/project.yaml b/projects/libtasn1/project.yaml
index dbd44ae..2fc0067 100644
--- a/projects/libtasn1/project.yaml
+++ b/projects/libtasn1/project.yaml
@@ -2,6 +2,8 @@
 language: c++
 primary_contact: "rockdaboot@gmail.com"
 auto_ccs:
+  - "dbaryshkov@gmail.com"
+  - "ueno@gnu.org"
   - "n.mavrogiannopoulos@gmail.com"
   - "simon@josefsson.org"
 fuzzing_engines:
diff --git a/projects/libtheora/Dockerfile b/projects/libtheora/Dockerfile
index abf8782..7f9d344 100644
--- a/projects/libtheora/Dockerfile
+++ b/projects/libtheora/Dockerfile
@@ -17,8 +17,8 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER guidovranken@gmail.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool
-RUN git clone --depth 1 https://github.com/xiph/ogg.git
-RUN git clone --depth 1 git://git.xiph.org/theora.git libtheora
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/ogg.git
+RUN git clone --depth 1 https://gitlab.xiph.org/xiph/theora.git libtheora
 RUN git clone --depth 1 https://github.com/guidovranken/oss-fuzz-fuzzers.git
 RUN git clone --depth 1 https://github.com/guidovranken/fuzzing-headers.git
 COPY build.sh $SRC/
diff --git a/projects/libtorrent/Dockerfile b/projects/libtorrent/Dockerfile
index acfe56f..d74ab14 100644
--- a/projects/libtorrent/Dockerfile
+++ b/projects/libtorrent/Dockerfile
@@ -18,10 +18,9 @@
 MAINTAINER arvid@libtorrent.org
 RUN apt-get update && apt-get install -y wget libssl-dev
 
-RUN git clone --depth 1 --single-branch --branch boost-1.72.0 --recurse-submodules https://github.com/boostorg/boost.git
+RUN git clone --depth 1 --single-branch --branch boost-1.73.0 --recurse-submodules https://github.com/boostorg/boost.git
 
-
-RUN git clone --depth 1 --single-branch --branch RC_1_2 --recurse-submodules https://github.com/arvidn/libtorrent.git
+RUN git clone --depth 1 --single-branch --branch RC_2_0 --recurse-submodules https://github.com/arvidn/libtorrent.git
 WORKDIR libtorrent
 COPY build.sh $SRC/
 
diff --git a/projects/libusb/Dockerfile b/projects/libusb/Dockerfile
new file mode 100644
index 0000000..71d03ab
--- /dev/null
+++ b/projects/libusb/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER christopher.a.dickens@gmail.com
+RUN apt-get update && apt-get install -y make autoconf automake libtool libudev-dev
+RUN git clone --depth 1 https://github.com/libusb/libusb libusb
+WORKDIR libusb
+COPY build.sh *.cc $SRC/
diff --git a/projects/libusb/build.sh b/projects/libusb/build.sh
new file mode 100755
index 0000000..281aa6e
--- /dev/null
+++ b/projects/libusb/build.sh
@@ -0,0 +1,30 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# build project
+./autogen.sh
+./configure
+make -j$(nproc) all
+
+# build fuzzer
+for fuzzer in $(find $SRC -name '*_fuzzer.cc'); do
+    fuzzer_basename=$(basename -s .cc $fuzzer)
+    $CXX $CXXFLAGS -std=c++11 -I. \
+    $fuzzer $LIB_FUZZING_ENGINE ./libusb/.libs/libusb-1.0.a \
+    -lpthread -ludev \
+    -o $OUT/$fuzzer_basename
+done
diff --git a/projects/libusb/libusb_fuzzer.cc b/projects/libusb/libusb_fuzzer.cc
new file mode 100644
index 0000000..8e543a7
--- /dev/null
+++ b/projects/libusb/libusb_fuzzer.cc
@@ -0,0 +1,49 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+
+#include "libusb/libusb.h"
+#include "libusb/libusbi.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  struct libusb_transfer *transfer;
+  FuzzedDataProvider stream(data, size);
+  uint8_t bmRequestType = stream.ConsumeIntegral<uint8_t>();
+  uint8_t bRequest = stream.ConsumeIntegral<uint8_t>();
+  uint16_t wValue = stream.ConsumeIntegral<uint16_t>();
+  uint16_t wIndex = stream.ConsumeIntegral<uint16_t>();
+  uint16_t wLength = stream.ConsumeIntegral<uint16_t>();
+  std::vector<char> data_ = stream.ConsumeRemainingBytes<char>();
+  unsigned char* buffer = reinterpret_cast<unsigned char*>(data_.data());
+
+  transfer = libusb_alloc_transfer(0);
+  if (!transfer) {
+    return LIBUSB_ERROR_NO_MEM;
+  }
+
+  if (!buffer) {
+    libusb_free_transfer(transfer);
+    return LIBUSB_ERROR_NO_MEM;
+  }
+
+  libusb_fill_control_setup(
+    buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
+
+  libusb_free_transfer(transfer);
+  return 0;
+}
diff --git a/projects/libusb/project.yaml b/projects/libusb/project.yaml
new file mode 100644
index 0000000..fa5cba7
--- /dev/null
+++ b/projects/libusb/project.yaml
@@ -0,0 +1,11 @@
+homepage: "http://libusb.info/"
+language: c++
+primary_contact: "christopher.a.dickens@gmail.com"
+auto_ccs:
+  - "hjelmn@gmail.com"
+sanitizers:
+  - address
+  - memory
+  - undefined
+architectures:
+  - x86_64
diff --git a/projects/libvpx/build.sh b/projects/libvpx/build.sh
index 3f6559d..15d9ea9 100755
--- a/projects/libvpx/build.sh
+++ b/projects/libvpx/build.sh
@@ -31,6 +31,7 @@
 fi
 
 LDFLAGS="$CXXFLAGS" LD=$CXX $SRC/libvpx/configure \
+    --enable-vp9-highbitdepth \
     --disable-unit-tests \
     --disable-examples \
     --size-limit=12288x12288 \
diff --git a/projects/libzmq/build.sh b/projects/libzmq/build.sh
index 8dce7ea..389b7f6 100755
--- a/projects/libzmq/build.sh
+++ b/projects/libzmq/build.sh
@@ -18,15 +18,15 @@
 
 # build project and dependencies
 cd "${SRC}/libsodium"
-./autogen.sh
-./configure --disable-shared
+DO_NOT_UPDATE_CONFIG_SCRIPTS=1 ./autogen.sh
+./configure --disable-shared --prefix=/install_prefix --disable-asm
 make -j$(nproc) V=1 install DESTDIR=/tmp/zmq_install_dir
 
 cd "${SRC}/libzmq"
 ./autogen.sh
-export LDFLAGS="$(PKG_CONFIG_PATH=/tmp/zmq_install_dir/usr/local/lib/pkgconfig pkg-config --static --libs --define-prefix libsodium)"
-export CXXFLAGS="$CXXFLAGS $(PKG_CONFIG_PATH=/tmp/zmq_install_dir/usr/local/lib/pkgconfig pkg-config --static --cflags --define-prefix libsodium)"
-./configure --disable-shared --disable-perf --disable-curve-keygen PKG_CONFIG_PATH=/tmp/zmq_install_dir/usr/local/lib/pkgconfig --with-libsodium=yes --with-fuzzing-installdir=fuzzers --with-fuzzing-engine=$LIB_FUZZING_ENGINE
+export LDFLAGS+=" $(PKG_CONFIG_PATH=/tmp/zmq_install_dir/install_prefix/lib/pkgconfig pkg-config --static --libs --define-prefix libsodium)"
+export CXXFLAGS+=" $(PKG_CONFIG_PATH=/tmp/zmq_install_dir/install_prefix/lib/pkgconfig pkg-config --static --cflags --define-prefix libsodium)"
+./configure --disable-shared --prefix=/install_prefix --disable-perf --disable-curve-keygen PKG_CONFIG_PATH=/tmp/zmq_install_dir/install_prefix/lib/pkgconfig --with-libsodium=yes --with-fuzzing-installdir=fuzzers --with-fuzzing-engine=$LIB_FUZZING_ENGINE
 make -j$(nproc) V=1 install DESTDIR=/tmp/zmq_install_dir
 
-cp /tmp/zmq_install_dir/usr/local/fuzzers/* "${OUT}"
+cp /tmp/zmq_install_dir/install_prefix/fuzzers/* "${OUT}"
diff --git a/projects/libzmq/project.yaml b/projects/libzmq/project.yaml
index 59b178c..517029e 100644
--- a/projects/libzmq/project.yaml
+++ b/projects/libzmq/project.yaml
@@ -4,9 +4,14 @@
 auto_ccs:
   - "luca.boccassi@gmail.com"
   - "somdoron@gmail.com"
+  - "simon.giesecke@gmail.com"
+fuzzing_engines:
+  - libfuzzer
+  - honggfuzz
 sanitizers:
   - address
   - memory
+  - undefined
 architectures:
   - x86_64
   - i386
diff --git a/projects/minify/Dockerfile b/projects/minify/Dockerfile
new file mode 100644
index 0000000..6b6cbe9
--- /dev/null
+++ b/projects/minify/Dockerfile
@@ -0,0 +1,21 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get -u github.com/tdewolff/minify
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/minify/build.sh b/projects/minify/build.sh
new file mode 100755
index 0000000..65d728c
--- /dev/null
+++ b/projects/minify/build.sh
@@ -0,0 +1,17 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+$GOPATH/src/github.com/tdewolff/minify/tests/oss-fuzz-build.sh
diff --git a/projects/minify/project.yaml b/projects/minify/project.yaml
new file mode 100644
index 0000000..2349ee3
--- /dev/null
+++ b/projects/minify/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/tdewolff/minify"
+primary_contact: "tacodewolff@gmail.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/mp4parse-rust/Dockerfile b/projects/mp4parse-rust/Dockerfile
index bd1ec8d..b125761 100644
--- a/projects/mp4parse-rust/Dockerfile
+++ b/projects/mp4parse-rust/Dockerfile
@@ -18,10 +18,6 @@
 MAINTAINER mgregan@mozilla.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool curl cmake python llvm-dev libclang-dev clang
 
-ENV CARGO_HOME=/rust RUSTUP_HOME=/rust/rustup PATH=$PATH:/rust/bin
-RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly
-RUN cargo install cargo-fuzz
-
 RUN git clone --depth 1 https://github.com/mozilla/mp4parse-rust mp4parse-rust
 WORKDIR mp4parse-rust
 
diff --git a/projects/mp4parse-rust/build.sh b/projects/mp4parse-rust/build.sh
index 5af2a68..860a7ac 100755
--- a/projects/mp4parse-rust/build.sh
+++ b/projects/mp4parse-rust/build.sh
@@ -16,19 +16,7 @@
 ################################################################################
 
 # Note: This project creates Rust fuzz targets exclusively
-
-export CUSTOM_LIBFUZZER_PATH="$LIB_FUZZING_ENGINE_DEPRECATED"
-export CUSTOM_LIBFUZZER_STD_CXX=c++
 PROJECT_DIR=$SRC/mp4parse-rust
-
-# Because Rust does not support sanitizers via CFLAGS/CXXFLAGS, the environment
-# variables are overridden with values from base-images/base-clang only
-
-export CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
-export CXXFLAGS_EXTRA="-stdlib=libc++"
-export CXXFLAGS="$CFLAGS $CXXFLAGS_EXTRA"
-export RUSTFLAGS="-Cdebuginfo=1 -Cforce-frame-pointers"
-
 cd $PROJECT_DIR/mp4parse_capi/fuzz && cargo fuzz build -O --debug-assertions
 
 mkdir $PROJECT_DIR/corpus
diff --git a/projects/muparser/Dockerfile b/projects/muparser/Dockerfile
new file mode 100644
index 0000000..2cf1db8
--- /dev/null
+++ b/projects/muparser/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+RUN apt-get update && apt-get install -y make autoconf automake libtool
+RUN apt-get install -y build-essential cmake pkg-config
+RUN git clone --depth 1 https://github.com/beltoforion/muparser.git muparser
+WORKDIR muparser
+COPY build.sh set_eval_fuzzer.cc $SRC/
diff --git a/projects/muparser/build.sh b/projects/muparser/build.sh
new file mode 100755
index 0000000..bbfb6b0
--- /dev/null
+++ b/projects/muparser/build.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# build project
+cmake . -DBUILD_SHARED_LIBS=OFF
+make -j$(nproc)
+
+# install
+make install
+ldconfig
+
+# build fuzzers
+MU_CXXFLAGS=$(pkg-config muparser --cflags)
+MU_LIBS=$(pkg-config muparser --libs)
+
+$CXX -std=c++11 $CXXFLAGS -I. \
+     $MU_CXXFLAGS $MU_LIBS \
+     $SRC/set_eval_fuzzer.cc -o $OUT/set_eval_fuzzer \
+     $LIB_FUZZING_ENGINE libmuparser.a
diff --git a/projects/muparser/project.yaml b/projects/muparser/project.yaml
new file mode 100644
index 0000000..c851981
--- /dev/null
+++ b/projects/muparser/project.yaml
@@ -0,0 +1,10 @@
+homepage: "https://beltoforion.de/article.php?a=muparser"
+language: c++
+primary_contact: "equinox.ib@googlemail.com"
+auto_ccs:
+    - "zhichengcai@google.com"
+fuzzing_engines:
+    - libfuzzer
+sanitizers:
+    - address
+    - undefined
diff --git a/projects/muparser/set_eval_fuzzer.cc b/projects/muparser/set_eval_fuzzer.cc
new file mode 100644
index 0000000..b04b2ff
--- /dev/null
+++ b/projects/muparser/set_eval_fuzzer.cc
@@ -0,0 +1,33 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdint.h>
+#include <stdio.h>
+#include <iostream>
+#include <string>
+
+#include "muParser.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  std::string line_string((char *)data, size);
+  try {
+    mu::Parser parser;
+    parser.SetExpr(line_string);
+    parser.Eval();
+  } catch (mu::Parser::exception_type &e) {
+     // Skip logging errors to avoid log spam.
+     // std::cout << e.GetMsg() << std::endl;
+  }
+  return 0;
+}
diff --git a/projects/mysql-server/targets/CMakeLists.txt b/projects/mysql-server/targets/CMakeLists.txt
index 507ba36..ef2fc6e 100644
--- a/projects/mysql-server/targets/CMakeLists.txt
+++ b/projects/mysql-server/targets/CMakeLists.txt
@@ -6,14 +6,14 @@
   TARGET_LINK_LIBRARIES(fuzz_stmt_fetch mysqlclient)
 
   MYSQL_ADD_EXECUTABLE(fuzz_mysqld fuzz_mysqld.cc util_fuzz.cc onefile.cc)
-  TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
 
   MYSQL_ADD_EXECUTABLE(fuzz_docommand fuzz_docommand.cc util_fuzz.cc onefile.cc)
-  TARGET_LINK_LIBRARIES(fuzz_docommand sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_docommand sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
 
 
   MYSQL_ADD_EXECUTABLE(fuzz_initfile fuzz_initfile.cc util_fuzz.cc onefile.cc)
-  TARGET_LINK_LIBRARIES(fuzz_initfile sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_initfile sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
 else()
   MYSQL_ADD_EXECUTABLE(fuzz_real_query fuzz_real_query.cc)
   TARGET_LINK_LIBRARIES(fuzz_real_query mysqlclient)
@@ -24,14 +24,14 @@
   TARGET_LINK_LIBRARIES(fuzz_stmt_fetch $ENV{LIB_FUZZING_ENGINE})
 
   MYSQL_ADD_EXECUTABLE(fuzz_mysqld fuzz_mysqld.cc util_fuzz.cc)
-  TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_mysqld sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
   TARGET_LINK_LIBRARIES(fuzz_mysqld $ENV{LIB_FUZZING_ENGINE})
 
   MYSQL_ADD_EXECUTABLE(fuzz_docommand fuzz_docommand.cc util_fuzz.cc)
-  TARGET_LINK_LIBRARIES(fuzz_docommand sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_docommand sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
   TARGET_LINK_LIBRARIES(fuzz_docommand $ENV{LIB_FUZZING_ENGINE})
 
   MYSQL_ADD_EXECUTABLE(fuzz_initfile fuzz_initfile.cc util_fuzz.cc)
-  TARGET_LINK_LIBRARIES(fuzz_initfile sql_main sql_gis binlog rpl master slave sql_dd sql_gis mysys binlogevents_static ${ICU_LIBRARIES})
+  TARGET_LINK_LIBRARIES(fuzz_initfile sql_main sql_gis binlog rpl master slave sql_dd mysys minchassis binlogevents_static ${ICU_LIBRARIES})
   TARGET_LINK_LIBRARIES(fuzz_initfile $ENV{LIB_FUZZING_ENGINE})
 endif()
diff --git a/projects/nanopb/Dockerfile b/projects/nanopb/Dockerfile
index fccb1ba..f241ac9 100644
--- a/projects/nanopb/Dockerfile
+++ b/projects/nanopb/Dockerfile
@@ -19,7 +19,7 @@
 RUN apt-get update && apt-get install -y python3-pip git wget
 RUN python3 -m pip install --upgrade pip
 RUN pip3 install protobuf grpcio-tools scons
-RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 100
+RUN update-alternatives --install /usr/bin/python python $(which python3) 100
 RUN git clone --depth 1 https://github.com/nanopb/nanopb $SRC/nanopb
 COPY build.sh $SRC/
 
diff --git a/projects/opensc/build.sh b/projects/opensc/build.sh
index 212d34a..84ab497 100755
--- a/projects/opensc/build.sh
+++ b/projects/opensc/build.sh
@@ -17,12 +17,15 @@
 
 ./bootstrap
 # FIXME FUZZING_LIBS="$LIB_FUZZING_ENGINE" fails with some missing C++ library, I don't know how to fix this
-./configure --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing FUZZING_LIBS="$LIB_FUZZING_ENGINE"
+./configure --disable-optimization --disable-shared --disable-pcsc --enable-ctapi --enable-fuzzing FUZZING_LIBS="$LIB_FUZZING_ENGINE"
 make -j4
 
-cp src/tests/fuzzing/fuzz_asn1_print $OUT
-cp src/tests/fuzzing/fuzz_asn1_sig_value $OUT
-cp src/tests/fuzzing/fuzz_pkcs15_decode $OUT
-cp src/tests/fuzzing/fuzz_pkcs15_reader $OUT
+fuzzerFiles=$(find $SRC/opensc/src/tests/fuzzing/ -name "fuzz_*.c")
 
-#cp src/tests/fuzzing/fuzz_pkcs15_reader.options $OUT
+for F in $fuzzerFiles; do
+    fuzzerName=$(basename $F .c)
+    cp "$SRC/opensc/src/tests/fuzzing/$fuzzerName" $OUT
+    if [ -d "$SRC/opensc/src/tests/fuzzing/corpus/${fuzzerName}" ]; then
+        zip -j $OUT/${fuzzerName}_seed_corpus.zip $SRC/opensc/src/tests/fuzzing/corpus/${fuzzerName}/*
+    fi
+done
diff --git a/projects/opus/Dockerfile b/projects/opus/Dockerfile
index bba1237..29f828e 100644
--- a/projects/opus/Dockerfile
+++ b/projects/opus/Dockerfile
@@ -18,7 +18,7 @@
 MAINTAINER flim@google.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool wget
 
-RUN git clone https://git.xiph.org/opus.git
+RUN git clone https://gitlab.xiph.org/xiph/opus.git
 RUN wget https://opus-codec.org/static/testvectors/opus_testvectors.tar.gz
 WORKDIR opus
 COPY build.sh $SRC/
diff --git a/projects/pcapplusplus/Dockerfile b/projects/pcapplusplus/Dockerfile
new file mode 100644
index 0000000..c015f2b
--- /dev/null
+++ b/projects/pcapplusplus/Dockerfile
@@ -0,0 +1,30 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER zlowram@gmail.com
+
+RUN apt-get update && apt-get install -y gcc g++ make cmake flex bison
+RUN git clone https://github.com/seladb/PcapPlusPlus PcapPlusPlus
+
+# Get tcpdump's test pcaps as seed corpus
+RUN git clone --depth=1 https://github.com/the-tcpdump-group/tcpdump.git tcpdump
+RUN git clone --depth=1 https://github.com/the-tcpdump-group/libpcap.git libpcap
+
+WORKDIR PcapPlusPlus
+
+COPY build.sh $SRC
+COPY *.options $SRC
diff --git a/projects/pcapplusplus/build.sh b/projects/pcapplusplus/build.sh
new file mode 100644
index 0000000..a30f4c3
--- /dev/null
+++ b/projects/pcapplusplus/build.sh
@@ -0,0 +1,40 @@
+#!/bin/bash -eu
+#
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+TARGETS_DIR=Tests/Fuzzers/Bin
+
+# Build libpcap
+cd $SRC/libpcap/
+./configure
+make -j$(nproc)
+
+# Build PcapPlusPlus linking statically against the built libpcap
+cd $SRC/PcapPlusPlus
+./configure-fuzzing.sh --libpcap-static-lib-dir $SRC/libpcap/
+make clean
+make -j$(nproc) fuzzers
+
+# Copy target and options
+cp $TARGETS_DIR/FuzzTarget $OUT
+cp $(ldd $OUT/FuzzTarget | cut -d" " -f3) $OUT
+cp $SRC/default.options $OUT/FuzzTarget.options
+
+# Copy corpora
+cd $SRC/tcpdump
+zip -jr FuzzTarget_seed_corpus.zip tests/*.pcap
+cp FuzzTarget_seed_corpus.zip $OUT/
diff --git a/projects/pcapplusplus/default.options b/projects/pcapplusplus/default.options
new file mode 100644
index 0000000..eb7fde2
--- /dev/null
+++ b/projects/pcapplusplus/default.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+close_fd_mask=3
diff --git a/projects/pcapplusplus/project.yaml b/projects/pcapplusplus/project.yaml
index 2c7d553..a864285 100644
--- a/projects/pcapplusplus/project.yaml
+++ b/projects/pcapplusplus/project.yaml
@@ -3,3 +3,7 @@
 primary_contact: "pcapplusplus@gmail.com"
 auto_ccs:
   - "zlowram@gmail.com"
+sanitizers:
+  - address
+  - memory
+  - undefined
diff --git a/projects/php/build.sh b/projects/php/build.sh
index 0dd2a79..3c007e8 100755
--- a/projects/php/build.sh
+++ b/projects/php/build.sh
@@ -34,7 +34,6 @@
     --disable-all \
     --enable-option-checking=fatal \
     --enable-fuzzer \
-    --enable-json \
     --enable-exif \
     --enable-mbstring \
     --without-pcre-jit \
diff --git a/projects/poppler/pdf_fuzzer.cc b/projects/poppler/pdf_fuzzer.cc
index b278f83..0f158bd 100644
--- a/projects/poppler/pdf_fuzzer.cc
+++ b/projects/poppler/pdf_fuzzer.cc
@@ -18,6 +18,7 @@
 
 #include <cstdint>
 
+#include <poppler-destination.h>
 #include <poppler-global.h>
 #include <poppler-document.h>
 #include <poppler-page.h>
@@ -33,6 +34,10 @@
     delete doc;
     return 0;
   }
+  doc->metadata();
+  doc->create_destination_map();
+  doc->embedded_files();
+  doc->fonts();
 
   poppler::page_renderer r;
   for (int i = 0; i < doc->pages(); i++) {
@@ -41,7 +46,7 @@
       continue;
     }
     r.render_page(p);
-    p->text_list();
+    p->text_list(poppler::page::text_list_include_font);
     delete p;
   }
 
diff --git a/projects/prometheus/Dockerfile b/projects/prometheus/Dockerfile
new file mode 100644
index 0000000..0d2326b
--- /dev/null
+++ b/projects/prometheus/Dockerfile
@@ -0,0 +1,22 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER julius.volz@gmail.com
+RUN go get github.com/prometheus/prometheus/cmd/...
+COPY build.sh $SRC/
+RUN mkdir $SRC/prometheus/
+WORKDIR $SRC/prometheus/
diff --git a/projects/prometheus/build.sh b/projects/prometheus/build.sh
new file mode 100755
index 0000000..c8011af
--- /dev/null
+++ b/projects/prometheus/build.sh
@@ -0,0 +1,29 @@
+#/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+compile_fuzzer github.com/prometheus/prometheus/promql FuzzParseMetric fuzzParseMetric
+compile_fuzzer github.com/prometheus/prometheus/promql FuzzParseOpenMetric fuzzParseOpenMetric
+compile_fuzzer github.com/prometheus/prometheus/promql FuzzParseMetricSelector fuzzParseMetricSelector
+compile_fuzzer github.com/prometheus/prometheus/promql FuzzParseExpr fuzzParseExpr
diff --git a/projects/prometheus/project.yaml b/projects/prometheus/project.yaml
new file mode 100644
index 0000000..de62edc
--- /dev/null
+++ b/projects/prometheus/project.yaml
@@ -0,0 +1,12 @@
+homepage: "https://github.com/prometheus/prometheus"
+primary_contact: "prometheus-team@googlegroups.com"
+auto_ccs :
+  - "julius.volz@gmail.com"
+  - "brian.brazil@robustperception.io"
+  - "roidelapluie@prometheus.io"
+  - "richih@richih.org"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/python3-libraries/build.sh b/projects/python3-libraries/build.sh
index 0c75c07..3da2935 100755
--- a/projects/python3-libraries/build.sh
+++ b/projects/python3-libraries/build.sh
@@ -59,7 +59,6 @@
 cp -R $CPYTHON_INSTALL_PATH $OUT/
 
 cd $SRC/python-library-fuzzers
-rm $CPYTHON_INSTALL_PATH/lib/python3.9/lib-dynload/_tkinter*.so
 make
 
 cp $SRC/python-library-fuzzers/fuzzer-html $OUT/
diff --git a/projects/qt/Dockerfile b/projects/qt/Dockerfile
index ec7261a..71eb4a7 100644
--- a/projects/qt/Dockerfile
+++ b/projects/qt/Dockerfile
@@ -17,10 +17,11 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER rlohningqt@gmail.com
 RUN dpkg --add-architecture i386
-RUN apt-get update && apt-get install -y build-essential libc6-dev:i386
+RUN apt-get update && apt-get install -y libc6-dev:i386
 RUN git clone --branch 5.15 --depth 1 git://code.qt.io/qt/qt5.git qt
 WORKDIR qt
-RUN perl init-repository --module-subset=qtbase
+RUN git submodule update --init --depth 1 qtbase
+RUN git submodule update --init --depth 1 qtdeclarative
 WORKDIR $SRC
 RUN git clone --depth 1 git://code.qt.io/qt/qtqa.git
 RUN git clone --depth 1 https://github.com/google/AFL.git
diff --git a/projects/qt/build.sh b/projects/qt/build.sh
index 7a98772..c44d9f1 100755
--- a/projects/qt/build.sh
+++ b/projects/qt/build.sh
@@ -30,11 +30,14 @@
 # build project
 cd $WORK
 MAKEFLAGS=-j$(nproc) $SRC/qt/configure -qt-libmd4c -platform linux-clang-libc++ -static -opensource -confirm-license -no-opengl -nomake tests -nomake examples -prefix $PWD/qtbase -D QT_NO_DEPRECATED_WARNINGS
-make -j$(nproc)
+make -j$(nproc) > /dev/null
 
 # prepare corpus files
+zip -j $WORK/cbor $SRC/qtqa/fuzzing/testcases/cbor/*
 zip -j $WORK/html $SRC/qtqa/fuzzing/testcases/html/*
+zip -j $WORK/images $SRC/qtqa/fuzzing/testcases/svg/* $SRC/AFL/testcases/images/*/*
 zip -j $WORK/markdown $SRC/qtqa/fuzzing/testcases/markdown/*
+zip -j $WORK/qml $SRC/qtqa/fuzzing/testcases/qml/*
 zip -j $WORK/ssl.pem.zip $SRC/qtqa/fuzzing/testcases/ssl.pem/*
 zip -j $WORK/text $SRC/qtqa/fuzzing/testcases/text/* $SRC/AFL/testcases/others/text/*
 zip -j $WORK/xml $SRC/qtqa/fuzzing/testcases/xml/* $SRC/AFL/testcases/others/xml/*
@@ -79,13 +82,15 @@
     rm -r build_fuzzer
 }
 
-build_fuzzer "new" "qtbase" "corelib/serialization/qcborstreamreader/next/next.pro"
-build_fuzzer "new" "qtbase" "corelib/serialization/qcborvalue/fromcbor/fromcbor.pro"
+build_fuzzer "new" "qtbase" "corelib/serialization/qcborstreamreader/next/next.pro" "cbor"
+build_fuzzer "new" "qtbase" "corelib/serialization/qcborvalue/fromcbor/fromcbor.pro" "cbor"
 build_fuzzer "new" "qtbase" "corelib/serialization/qtextstream/extractionoperator-float/extractionoperator-float.pro" "text"
 build_fuzzer "old" "qtbase" "corelib/serialization/qxmlstream/qxmlstreamreader/readnext/readnext.pro" "xml" "$SRC/AFL/dictionaries/xml.dict"
 build_fuzzer "new" "qtbase" "corelib/text/qregularexpression/optimize/optimize.pro" "" "$SRC/AFL/dictionaries/regexp.dict"
+build_fuzzer "new" "qtbase" "gui/image/qimage/loadfromdata/loadfromdata.pro" "images"
 build_fuzzer "new" "qtbase" "gui/painting/qcolorspace/fromiccprofile/fromiccprofile.pro"
 build_fuzzer "new" "qtbase" "gui/text/qtextdocument/sethtml/sethtml.pro" "html" "$SRC/AFL/dictionaries/html_tags.dict"
 build_fuzzer "old" "qtbase" "gui/text/qtextdocument/setmarkdown/setmarkdown.pro" "markdown"
 build_fuzzer "new" "qtbase" "gui/text/qtextlayout/beginlayout/beginlayout.pro" "text"
 build_fuzzer "new" "qtbase" "network/ssl/qsslcertificate/qsslcertificate/pem/pem.pro" "ssl.pem"
+build_fuzzer "new" "qtdeclarative" "qml/qml/qqmlcomponent/create/create.pro " "qml"
diff --git a/projects/rdkit/Dockerfile b/projects/rdkit/Dockerfile
new file mode 100644
index 0000000..365cd93
--- /dev/null
+++ b/projects/rdkit/Dockerfile
@@ -0,0 +1,43 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER greg.landrum@gmail.com
+RUN apt-get update && apt-get install -y make wget cmake \
+  libeigen3-dev python3 libpython3-all-dev \
+  zlib1g-dev \
+  libbz2-dev
+
+# Install latest cmake
+RUN wget --quiet https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.5-Linux-x86_64.sh; \
+    chmod +x cmake-3.14.5-Linux-x86_64.sh; \
+    ./cmake-3.14.5-Linux-x86_64.sh --skip-license --prefix="/usr/local"
+
+# We're building `rdkit` using clang, but the boost package is built using gcc.
+# For whatever reason, linking would fail.
+# (Mismatch between libstdc++ and libc++ maybe?)
+# It works if we build `rdkit` using gcc or build boost using clang instead.
+# We've opted for building boost using clang.
+RUN cd $SRC && \
+    wget --quiet https://sourceforge.net/projects/boost/files/boost/1.69.0/boost_1_69_0.tar.bz2 && \
+    tar xjf boost_1_69_0.tar.bz2 && \
+    cd $SRC/boost_1_69_0 && \
+    ./bootstrap.sh --with-toolset=clang --with-libraries=serialization,system,iostreams,regex && \
+    ./b2 -q -j2 toolset=clang cxxflags="-fPIC $CXXFLAGS $CXXFLAGS_EXTRA" link=static install
+
+RUN git clone --depth 1 https://github.com/rdkit/rdkit.git $SRC/rdkit
+WORKDIR $SRC/rdkit
+COPY build.sh $SRC/
diff --git a/projects/rdkit/build.sh b/projects/rdkit/build.sh
new file mode 100755
index 0000000..d7999d2
--- /dev/null
+++ b/projects/rdkit/build.sh
@@ -0,0 +1,34 @@
+#!/bin/bash -eu
+# Copyright 2017 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+mkdir -p build && cd build
+cmake -DRDK_BUILD_PYTHON_WRAPPERS=OFF -DLIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE} -DRDK_BUILD_FUZZ_TARGETS=ON -DRDK_INSTALL_STATIC_LIBS=ON -DBoost_USE_STATIC_LIBS=ON ..
+make -j$(nproc)
+make install
+
+# Leave build directory
+cd ..
+
+# Copy the fuzzer executables, zip-ed corpora, options and dictionary files to $OUT
+find . -type f -name '*_fuzzer' -exec cp -v '{}' $OUT ';'
+find . -type f -name '*_fuzzer.dict' -exec cp -v '{}' $OUT ';'
+#find . -type f -name '*_fuzzer.options' -exec cp -v '{}' $OUT ';'
+corpora=$(find . -type d -name "*_fuzzer")
+for corpus in $corpora; do
+	corpus_basename=$(basename $corpus)
+	zip -j $OUT/${corpus_basename}_seed_corpus.zip ${corpus}/*
+done
diff --git a/projects/rdkit/project.yaml b/projects/rdkit/project.yaml
new file mode 100644
index 0000000..ef82b38
--- /dev/null
+++ b/projects/rdkit/project.yaml
@@ -0,0 +1,8 @@
+homepage: "https://github.com/rdkit/rdkit"
+language: c++
+primary_contact: "greg.landrum@gmail.com"
+sanitizers:
+  - address
+  - undefined
+architectures:
+  - x86_64
diff --git a/projects/serde_json/Dockerfile b/projects/serde_json/Dockerfile
new file mode 100644
index 0000000..2bc753a
--- /dev/null
+++ b/projects/serde_json/Dockerfile
@@ -0,0 +1,23 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER david@adalogics.com
+RUN apt-get update && apt-get install -y make autoconf automake libtool curl cmake python llvm-dev libclang-dev clang
+
+RUN git clone --depth 1 https://github.com/serde-rs/json json
+WORKDIR $SRC
+
+COPY build.sh $SRC/
diff --git a/projects/serde_json/build.sh b/projects/serde_json/build.sh
new file mode 100755
index 0000000..9ae8b78
--- /dev/null
+++ b/projects/serde_json/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Note: This project creates Rust fuzz targets exclusively
+cd $SRC/json
+cargo fuzz build -O 
+cp fuzz/target/x86_64-unknown-linux-gnu/release/from_slice $OUT/
diff --git a/projects/serde_json/project.yaml b/projects/serde_json/project.yaml
new file mode 100644
index 0000000..f7b8571
--- /dev/null
+++ b/projects/serde_json/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/serde-rs/json"
+primary_contact: "dtolnay@gmail.com"
+sanitizers:
+  - address
+fuzzing_engines:
+  - libfuzzer
+language: rust
+auto_ccs:
+  - "david@adalogics.com"
diff --git a/projects/skia/skia.diff b/projects/skia/skia.diff
index 9c3e77c..9d47766 100644
--- a/projects/skia/skia.diff
+++ b/projects/skia/skia.diff
@@ -30,12 +30,12 @@
          const uint8_t* rowA = nullptr;
          const uint8_t* rowB = nullptr;
 diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
-index 609e40ccae..db9d67b966 100644
+index 99c8bd8284..335d2e97a0 100644
 --- a/src/core/SkDraw.cpp
 +++ b/src/core/SkDraw.cpp
-@@ -959,6 +959,12 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
+@@ -958,6 +958,12 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
      // transform the path into device space
-     pathPtr->transform(*matrix, devPathPtr);
+     pathPtr->transform(matrixProvider->localToDevice(), devPathPtr);
  
 +#if defined(IS_FUZZING)
 +    if (devPathPtr->countPoints() > 1000) {
@@ -80,7 +80,7 @@
      if (nullptr == addr) {
          return nullptr;
 diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp
-index 705809de99..ef4e406816 100644
+index c840a68a03..5692773a33 100644
 --- a/src/core/SkMaskFilter.cpp
 +++ b/src/core/SkMaskFilter.cpp
 @@ -262,6 +262,11 @@ bool SkMaskFilterBase::filterPath(const SkPath& devPath, const SkMatrix& matrix,
@@ -114,10 +114,10 @@
      SkPath tmpPath;
  
 diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
-index 5afe53ab70..41d28b0602 100644
+index 09c061de51..34b3f0bd63 100644
 --- a/src/core/SkPath.cpp
 +++ b/src/core/SkPath.cpp
-@@ -3142,7 +3142,11 @@ void SkPathPriv::CreateDrawArcPath(SkPath* path, const SkRect& oval, SkScalar st
+@@ -3173,7 +3173,11 @@ void SkPathPriv::CreateDrawArcPath(SkPath* path, const SkRect& oval, SkScalar st
                                     SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect) {
      SkASSERT(!oval.isEmpty());
      SkASSERT(sweepAngle);
@@ -131,10 +131,10 @@
      path->setIsVolatile(true);
      path->setFillType(SkPathFillType::kWinding);
 diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp
-index 041f6f0469..0270f810c4 100644
+index c7e26df8d4..eb9b28141d 100644
 --- a/src/core/SkReadBuffer.cpp
 +++ b/src/core/SkReadBuffer.cpp
-@@ -276,7 +276,12 @@ sk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
+@@ -277,7 +277,12 @@ sk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
  uint32_t SkReadBuffer::getArrayCount() {
      const size_t inc = sizeof(uint32_t);
      fError = fError || !IsPtrAlign4(fReader.peek()) || !fReader.isAvailable(inc);
@@ -148,10 +148,10 @@
  
  /*  Format:
 diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp
-index 589bd1cccd..a4c661c69d 100644
+index eeea9e78f0..4c8d2a8f3f 100644
 --- a/src/core/SkScan_Hairline.cpp
 +++ b/src/core/SkScan_Hairline.cpp
-@@ -121,7 +121,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion*
+@@ -122,7 +122,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion*
              if (ix0 == ix1) {// too short to draw
                  continue;
              }
@@ -164,7 +164,7 @@
              SkFixed slope = SkFixedDiv(dy, dx);
              SkFixed startY = SkFDot6ToFixed(y0) + (slope * ((32 - x0) & 63) >> 6);
  
-@@ -137,7 +141,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion*
+@@ -138,7 +142,11 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion*
              if (iy0 == iy1) { // too short to draw
                  continue;
              }
diff --git a/projects/solidity/Dockerfile b/projects/solidity/Dockerfile
index 9bf5413..58ffe84 100644
--- a/projects/solidity/Dockerfile
+++ b/projects/solidity/Dockerfile
@@ -29,7 +29,6 @@
 RUN git clone --depth 1 https://github.com/google/libprotobuf-mutator.git
 RUN git clone --branch="v0.4.0" --recurse-submodules \
     https://github.com/ethereum/evmone.git
-RUN git clone --branch="z3-4.8.7" https://github.com/Z3Prover/z3.git
 
 # Install statically built dependencies in "/usr" directory
 # Install boost
@@ -62,12 +61,4 @@
     ninja; \
     ninja install;
 
-# Install Z3
-RUN cd $SRC/z3; \
-    mkdir -p build; \
-    cd build; \
-    LDFLAGS=$CXXFLAGS cmake -DZ3_BUILD_LIBZ3_SHARED=OFF -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release ..; \
-    make libz3 -j; \
-    make install;
-
 COPY build.sh $SRC/
diff --git a/projects/solidity/build.sh b/projects/solidity/build.sh
index dc9b869..57757f9 100755
--- a/projects/solidity/build.sh
+++ b/projects/solidity/build.sh
@@ -16,12 +16,12 @@
 ################################################################################
 
 # Compile proto C++ bindings
-protoc \
-    --proto_path=$SRC/solidity/test/tools/ossfuzz yulProto.proto \
-    --cpp_out=$SRC/solidity/test/tools/ossfuzz
-protoc \
-    --proto_path=$SRC/solidity/test/tools/ossfuzz abiV2Proto.proto \
-    --cpp_out=$SRC/solidity/test/tools/ossfuzz
+for protoName in yul abiV2 sol;
+do
+	protoc \
+	    --proto_path=$SRC/solidity/test/tools/ossfuzz "$protoName"Proto.proto \
+	    --cpp_out=$SRC/solidity/test/tools/ossfuzz
+done
 
 # Build solidity
 cd $SRC/solidity
diff --git a/projects/speex/Dockerfile b/projects/speex/Dockerfile
index 05a4253..7ed9981 100644
--- a/projects/speex/Dockerfile
+++ b/projects/speex/Dockerfile
@@ -17,7 +17,8 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER tmatth@videolan.org
 RUN apt-get update && apt-get install -y make autoconf libtool pkg-config wget
-RUN git clone https://git.xiph.org/ogg.git
-RUN git clone https://git.xiph.org/speex.git speex
+RUN git clone https://gitlab.xiph.org/xiph/ogg.git
+RUN git clone https://gitlab.xiph.org/xiph/speex.git speex
 WORKDIR speex
+RUN git checkout speexdec-fuzz-target
 COPY build.sh $SRC/
diff --git a/projects/spidermonkey-ufi/build.sh b/projects/spidermonkey-ufi/build.sh
index 0460c0e..cd1498b 100755
--- a/projects/spidermonkey-ufi/build.sh
+++ b/projects/spidermonkey-ufi/build.sh
@@ -21,16 +21,16 @@
   Wasm
 )
 
-# Install dependencies. Note that bootstrap installs cargo, which must be added
-# to PATH via source. In a successive run (for a different sanitizer), the
-# cargo installation carries over, but bootstrap fails if cargo is not in PATH.
+# Install dependencies.
 export SHELL=/bin/bash
-[[ -f "$HOME/.cargo/env" ]] && source $HOME/.cargo/env
 ../../mach bootstrap --no-interactive --application-choice browser
-source $HOME/.cargo/env
 
 autoconf2.13
 
+# Skip patches for now
+rm ../../tools/fuzzing/libfuzzer/patches/*.patch
+touch ../../tools/fuzzing/libfuzzer/patches/dummy.patch
+
 # Update internal libFuzzer.
 (cd ../../tools/fuzzing/libfuzzer && ./clone_libfuzzer.sh HEAD)
 
diff --git a/projects/spidermonkey/build.sh b/projects/spidermonkey/build.sh
index 042a741..55971eb 100755
--- a/projects/spidermonkey/build.sh
+++ b/projects/spidermonkey/build.sh
@@ -19,9 +19,6 @@
 export SHELL=/bin/bash
 ../../mach bootstrap --no-interactive --application-choice browser
 
-# Set environment for rustc.
-source $HOME/.cargo/env
-
 autoconf2.13
 
 mkdir build_DBG.OBJ
diff --git a/projects/stb/Dockerfile b/projects/stb/Dockerfile
index 30b91b5..89129f4 100644
--- a/projects/stb/Dockerfile
+++ b/projects/stb/Dockerfile
@@ -16,9 +16,16 @@
 
 FROM gcr.io/oss-fuzz-base/base-builder
 
+RUN apt-get update && \
+    apt-get install -y wget tar
+
 MAINTAINER randy408@protonmail.com
 
 RUN git clone --depth 1 https://github.com/nothings/stb.git
 
+RUN wget -O $SRC/stb/gif.tar.gz https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/imagetestsuite/imagetestsuite-gif-1.00.tar.gz
+RUN wget -O $SRC/stb/jpg.tar.gz https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/imagetestsuite/imagetestsuite-jpg-1.00.tar.gz
+RUN wget -O $SRC/stb/tests/gif.dict https://raw.githubusercontent.com/mirrorer/afl/master/dictionaries/gif.dict &> /dev/null
+
 WORKDIR stb
 COPY build.sh $SRC/
diff --git a/projects/stb/build.sh b/projects/stb/build.sh
index 84fbca3..1cbf4c0 100644
--- a/projects/stb/build.sh
+++ b/projects/stb/build.sh
@@ -15,11 +15,27 @@
 #
 ################################################################################
 
-$CXX $CXXFLAGS -std=c++11 -I. \
-    $SRC/stb/tests/stb_png_read_fuzzer.cpp \
+# remove this line when this change is upstreamed
+sed '2d' $SRC/stb/tests/stb_png_read_fuzzer.cpp > $SRC/stb/tests/stbi_read_fuzzer.c
+
+$CXX $CXXFLAGS -std=c++11 -I. -DSTBI_ONLY_PNG  \
+    $SRC/stb/tests/stbi_read_fuzzer.c \
     -o $OUT/stb_png_read_fuzzer $LIB_FUZZING_ENGINE
 
+$CXX $CXXFLAGS -std=c++11 -I. \
+    $SRC/stb/tests/stbi_read_fuzzer.c \
+    -o $OUT/stbi_read_fuzzer $LIB_FUZZING_ENGINE
+
 find $SRC/stb/tests/pngsuite -name "*.png" | \
      xargs zip $OUT/stb_png_read_fuzzer_seed_corpus.zip
 
 cp $SRC/stb/tests/stb_png.dict $OUT/stb_png_read_fuzzer.dict
+
+tar xvzf $SRC/stb/jpg.tar.gz --directory $SRC/stb/tests
+tar xvzf $SRC/stb/gif.tar.gz --directory $SRC/stb/tests
+
+find $SRC/stb/tests -name "*.png" -o -name "*.jpg" -o -name ".gif" | \
+     xargs zip $OUT/stbi_read_fuzzer_seed_corpus.zip
+
+echo "" >> $SRC/stb/tests/gif.dict
+cat $SRC/stb/tests/gif.dict $SRC/stb/tests/stb_png.dict > $OUT/stbi_read_fuzzer.dict
diff --git a/projects/suricata/Dockerfile b/projects/suricata/Dockerfile
index 1c85c34..e4486b9 100644
--- a/projects/suricata/Dockerfile
+++ b/projects/suricata/Dockerfile
@@ -15,7 +15,7 @@
 ################################################################################
 
 FROM gcr.io/oss-fuzz-base/base-builder
-RUN apt-get update && apt-get install -y build-essential autoconf automake libtool make pkg-config rustc cargo python flex bison zlib1g-dev libpcre3-dev
+RUN apt-get update && apt-get install -y build-essential autoconf automake libtool make pkg-config  python flex bison zlib1g-dev libpcre3-dev
 
 #TODO libmagic, liblzma, pcre and other optional libraries
 ADD https://www.tcpdump.org/release/libpcap-1.9.1.tar.gz libpcap-1.9.1.tar.gz
diff --git a/projects/suricata/build.sh b/projects/suricata/build.sh
index 4dd2334..843e9af 100755
--- a/projects/suricata/build.sh
+++ b/projects/suricata/build.sh
@@ -44,10 +44,10 @@
 make install
 cd ..
 
+export CARGO_BUILD_TARGET="x86_64-unknown-linux-gnu"
 
 # build project
 cd suricata
-export PATH=$PATH:/root/.cargo/bin
 sh autogen.sh
 #run configure with right options
 ./src/tests/fuzz/oss-fuzz-configure.sh
diff --git a/projects/systemd/project.yaml b/projects/systemd/project.yaml
index 940d253..1d49f4c 100644
--- a/projects/systemd/project.yaml
+++ b/projects/systemd/project.yaml
@@ -11,6 +11,7 @@
   - dimitri.ledkov@canonical.com
   - poettering@gmail.com
   - watanabe.yu@gmail.com
+  - evvers@ya.ru
   - evverx@gmail.com
   - Tixxdz@gmail.com
   - fsumsal@redhat.com
@@ -18,3 +19,4 @@
   - ssahani@vmware.com
   - chris@chrisdown.name
   - the.anitazha@gmail.com
+  - daan.j.demeyer@gmail.com
diff --git a/projects/tesseract-ocr/build.sh b/projects/tesseract-ocr/build.sh
index 1847668..9943c74 100755
--- a/projects/tesseract-ocr/build.sh
+++ b/projects/tesseract-ocr/build.sh
@@ -1,5 +1,5 @@
 #!/bin/bash -eu
-# Copyright 2019 Google Inc.
+# Copyright 2020 Google Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,45 +14,4 @@
 # limitations under the License.
 #
 ################################################################################
-
-cd $SRC/leptonica
-./autogen.sh
-./configure
-make -j$(nproc)
-make install
-ldconfig
-
-cd $SRC/tesseract
-./autogen.sh
-CXXFLAGS="$CXXFLAGS -D_GLIBCXX_DEBUG" ./configure --disable-graphics --disable-shared
-make -j$(nproc)
-
-cp -R $SRC/tessdata $OUT
-
-$CXX $CXXFLAGS \
-    -I $SRC/tesseract/include \
-     $SRC/tesseract/unittest/fuzzers/fuzzer-api.cpp -o $OUT/fuzzer-api \
-     $SRC/tesseract/.libs/libtesseract.a \
-     /usr/local/lib/liblept.a \
-     /usr/lib/x86_64-linux-gnu/libtiff.a \
-     /usr/lib/x86_64-linux-gnu/libpng.a \
-     /usr/lib/x86_64-linux-gnu/libjpeg.a \
-     /usr/lib/x86_64-linux-gnu/libjbig.a \
-     /usr/lib/x86_64-linux-gnu/liblzma.a \
-     -lz \
-     $LIB_FUZZING_ENGINE
-
-$CXX $CXXFLAGS \
-    -DTESSERACT_FUZZER_WIDTH=512 \
-    -DTESSERACT_FUZZER_HEIGHT=256 \
-    -I $SRC/tesseract/include \
-     $SRC/tesseract/unittest/fuzzers/fuzzer-api.cpp -o $OUT/fuzzer-api-512x256 \
-     $SRC/tesseract/.libs/libtesseract.a \
-     /usr/local/lib/liblept.a \
-     /usr/lib/x86_64-linux-gnu/libtiff.a \
-     /usr/lib/x86_64-linux-gnu/libpng.a \
-     /usr/lib/x86_64-linux-gnu/libjpeg.a \
-     /usr/lib/x86_64-linux-gnu/libjbig.a \
-     /usr/lib/x86_64-linux-gnu/liblzma.a \
-     -lz \
-     $LIB_FUZZING_ENGINE
+$SRC/tesseract/unittest/fuzzers/oss-fuzz-build.sh
diff --git a/projects/tidb/Dockerfile b/projects/tidb/Dockerfile
new file mode 100644
index 0000000..4061d68
--- /dev/null
+++ b/projects/tidb/Dockerfile
@@ -0,0 +1,21 @@
+# Copyright 2019 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get github.com/pingcap/tidb/store
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/tidb/build.sh b/projects/tidb/build.sh
new file mode 100755
index 0000000..2ea7ac7
--- /dev/null
+++ b/projects/tidb/build.sh
@@ -0,0 +1,28 @@
+#/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+compile_fuzzer github.com/pingcap/tidb/types FuzzMarshalJSON fuzzMarshalJSON
+compile_fuzzer github.com/pingcap/tidb/types FuzzNewBitLiteral fuzzNewBitLiteral
+compile_fuzzer github.com/pingcap/tidb/types FuzzNewHexLiteral fuzzNewHexLiteral
diff --git a/projects/tidb/project.yaml b/projects/tidb/project.yaml
new file mode 100644
index 0000000..67ca6ef
--- /dev/null
+++ b/projects/tidb/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/pingcap/tidb"
+primary_contact: "zhouqiang@pingcap.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/tremor/Dockerfile b/projects/tremor/Dockerfile
index 852b99c..6491cbc 100644
--- a/projects/tremor/Dockerfile
+++ b/projects/tremor/Dockerfile
@@ -17,8 +17,8 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER twsmith@mozilla.com
 RUN apt-get update && apt-get install -y make autoconf automake libogg-dev libtool pkg-config wget
-RUN git clone https://git.xiph.org/ogg.git
-RUN git clone https://git.xiph.org/tremor.git
+RUN git clone https://gitlab.xiph.org/xiph/ogg.git
+RUN git clone https://gitlab.xiph.org/xiph/tremor.git
 RUN svn export https://github.com/mozillasecurity/fuzzdata.git/trunk/samples/vorbis decode_corpus
 WORKDIR tremor
 COPY decode_fuzzer.cc $SRC/tremor/
diff --git a/projects/vitess/Dockerfile b/projects/vitess/Dockerfile
new file mode 100644
index 0000000..2bdbfc4
--- /dev/null
+++ b/projects/vitess/Dockerfile
@@ -0,0 +1,28 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER adam@adalogics.com
+RUN go get 	github.com/vitessio/vitess \
+		vitess.io/vitess/go/bytes2 \
+		vitess.io/vitess/go/sqltypes \
+		vitess.io/vitess/go/vt/log \
+		vitess.io/vitess/go/vt/proto/query \
+		vitess.io/vitess/go/vt/proto/vtrpc \
+		vitess.io/vitess/go/vt/vterrors \
+		vitess.io/vitess/go/vt/vtgate/evalengine
+COPY build.sh $SRC/
+WORKDIR $SRC/
diff --git a/projects/vitess/build.sh b/projects/vitess/build.sh
new file mode 100755
index 0000000..99ab3ed
--- /dev/null
+++ b/projects/vitess/build.sh
@@ -0,0 +1,26 @@
+#/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+function compile_fuzzer {
+  path=$1
+  function=$2
+  fuzzer=$3
+
+  go-fuzz -func $function -o $fuzzer.a $path
+
+  $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer
+}
+compile_fuzzer github.com/vitessio/vitess/go/vt/sqlparser Fuzz fuzz
diff --git a/projects/vitess/project.yaml b/projects/vitess/project.yaml
new file mode 100644
index 0000000..a2b1c2e
--- /dev/null
+++ b/projects/vitess/project.yaml
@@ -0,0 +1,9 @@
+homepage: "https://github.com/vitessio/vitess" 
+primary_contact: "andres@planetscale.com"
+auto_ccs :
+  - "adam@adalogics.com"
+language: go
+fuzzing_engines:
+  - libfuzzer
+sanitizers:
+  - address
diff --git a/projects/vorbis/Dockerfile b/projects/vorbis/Dockerfile
index 464555d..8b5838a 100644
--- a/projects/vorbis/Dockerfile
+++ b/projects/vorbis/Dockerfile
@@ -17,10 +17,12 @@
 FROM gcr.io/oss-fuzz-base/base-builder
 MAINTAINER paul.l.kehrer@mail.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool pkg-config wget
-RUN git clone https://git.xiph.org/ogg.git
-RUN git clone https://git.xiph.org/vorbis.git
+RUN git clone https://gitlab.xiph.org/xiph/ogg.git
+RUN git clone https://gitlab.xiph.org/xiph/vorbis.git
 RUN svn export https://github.com/mozillasecurity/fuzzdata.git/trunk/samples/ogg decode_corpus
 RUN svn export --force https://github.com/mozillasecurity/fuzzdata.git/trunk/samples/vorbis decode_corpus
-RUN wget --cut-dirs 3 --recursive --level=1 -A ".ogg" https://people.xiph.org/~xiphmont/test-vectors/vorbis/
+# TODO: remove `people.xiph.org` lines once upstream build script is updated
+RUN mkdir people.xiph.org/
+RUN touch people.xiph.org/dummy.ogg
 WORKDIR vorbis
 COPY build.sh $SRC/
diff --git a/projects/wasmtime/Dockerfile b/projects/wasmtime/Dockerfile
index a954d2d..8057ecd 100644
--- a/projects/wasmtime/Dockerfile
+++ b/projects/wasmtime/Dockerfile
@@ -18,10 +18,6 @@
 MAINTAINER foote@fastly.com
 RUN apt-get update && apt-get install -y make autoconf automake libtool curl cmake python llvm-dev libclang-dev clang
 
-ENV CARGO_HOME=/rust RUSTUP_HOME=/rust/rustup PATH=$PATH:/rust/bin
-RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly
-RUN cargo install cargo-fuzz
-
 RUN git clone --depth 1 https://github.com/bytecodealliance/wasmtime wasmtime
 WORKDIR wasmtime
 RUN git submodule update --init --recursive
diff --git a/projects/wasmtime/build.sh b/projects/wasmtime/build.sh
index b4321d7..5fbbdd5 100755
--- a/projects/wasmtime/build.sh
+++ b/projects/wasmtime/build.sh
@@ -16,20 +16,11 @@
 ################################################################################
 
 # Note: This project creates Rust fuzz targets exclusively
-
-export CUSTOM_LIBFUZZER_PATH="$LIB_FUZZING_ENGINE_DEPRECATED"
-export CUSTOM_LIBFUZZER_STD_CXX=c++
 PROJECT_DIR=$SRC/wasmtime
 
-# Because Rust does not support sanitizers via CFLAGS/CXXFLAGS, the environment
-# variables are overridden with values from base-images/base-clang only
-
-export CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
-export CXXFLAGS_EXTRA="-stdlib=libc++"
-export CXXFLAGS="$CFLAGS $CXXFLAGS_EXTRA"
-export RUSTFLAGS="-Cdebuginfo=1 -Cforce-frame-pointers"
-
-cd $PROJECT_DIR/fuzz && cargo fuzz build -O --debug-assertions --features binaryen
+# Build with all features to enable the binaryen-using fuzz targets, and
+# the peepmatic fuzz targets.
+cd $PROJECT_DIR/fuzz && cargo fuzz build -O --debug-assertions --all-features
 
 FUZZ_TARGET_OUTPUT_DIR=$PROJECT_DIR/target/x86_64-unknown-linux-gnu/release
 for f in $SRC/wasmtime/fuzz/fuzz_targets/*.rs
diff --git a/projects/wuffs/Dockerfile b/projects/wuffs/Dockerfile
index b6a7164..734a19a 100644
--- a/projects/wuffs/Dockerfile
+++ b/projects/wuffs/Dockerfile
@@ -41,6 +41,10 @@
 RUN unzip -j rapidjson.zip -d rapidjson_corpus
 RUN rm rapidjson.zip
 
+RUN git clone --depth 1 https://github.com/minio/simdjson-fuzz
+RUN mv simdjson-fuzz/corpus/corpus simdjson_corpus
+RUN rm -rf simdjson-fuzz
+
 # Finish.
 
 WORKDIR wuffs
diff --git a/projects/wuffs/build.sh b/projects/wuffs/build.sh
index 6177a3b..d51af38 100755
--- a/projects/wuffs/build.sh
+++ b/projects/wuffs/build.sh
@@ -32,8 +32,24 @@
   # Make the optional "gzip_fuzzer_seed_corpus.zip" archive. This means
   # extracting the "foo/bar/*.gz" out of the matching "gzip: foo/bar/*.gz"
   # lines in fuzz/c/std/seed_corpora.txt.
+  #
+  # The seed_corpora.txt lines can contain multiple entries, combining
+  # independent corpora. A naive "zip --junk-paths" of all those files can fail
+  # if there are duplicate file names, which can easily happen if the file name
+  # is a hash of its contents and the contents are a (trivial) minimal
+  # reproducer. We use a de-duplication step of copying all of those files into
+  # a single directory. Doing that in a single "cp" or "mv" call can fail with
+  # "will not overwrite just-created 'foo/etc' with 'bar/etc'", so we make
+  # multiple calls, each copying one file at a time. Later duplicates overwrite
+  # earlier duplicates. It's OK if the contents aren't identical. The result is
+  # still a valid uber-corpus of seed files.
   seeds=$(sed -n -e "/^$b:/s/^$b: *//p" fuzz/c/std/seed_corpora.txt)
   if [ -n "$seeds" ]; then
-    zip --junk-paths $OUT/${b}_fuzzer_seed_corpus.zip $seeds
+    mkdir ${b}_fuzzer_seed_corpus
+    for s in $seeds; do
+      cp $s ${b}_fuzzer_seed_corpus
+    done
+    zip --junk-paths --recurse-paths $OUT/${b}_fuzzer_seed_corpus.zip ${b}_fuzzer_seed_corpus
+    rm -rf ${b}_fuzzer_seed_corpus
   fi
 done
diff --git a/projects/zeek/Dockerfile b/projects/zeek/Dockerfile
new file mode 100644
index 0000000..8eb9d54
--- /dev/null
+++ b/projects/zeek/Dockerfile
@@ -0,0 +1,35 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER jsiwek@corelight.com
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+        patchelf \
+        cmake \
+        ninja-build \
+        flex \
+        bison \
+        libpcap-dev \
+        libssl-dev \
+        libmaxminddb-dev \
+        libkrb5-dev \
+        zlib1g-dev \
+  && rm -rf /var/lib/apt/lists/*
+
+RUN git clone --depth 1 --recursive https://github.com/zeek/zeek zeek
+WORKDIR zeek
+COPY build.sh $SRC/
diff --git a/projects/zeek/build.sh b/projects/zeek/build.sh
new file mode 100644
index 0000000..f02e6b1
--- /dev/null
+++ b/projects/zeek/build.sh
@@ -0,0 +1,76 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+CFLAGS="${CFLAGS} -pthread" CXXFLAGS="${CXXFLAGS} -pthread" \
+    ./configure --prefix=$(pwd)/build/install-root \
+                --build-type=debug \
+                --generator=Ninja \
+                --enable-fuzzers \
+                --disable-python \
+                --disable-zeekctl \
+                --disable-auxtools \
+                --disable-broker-tests
+
+cd build
+ninja install
+
+cp -R ./install-root/share/zeek ${OUT}/oss-fuzz-zeek-scripts
+
+fuzzers=$(find . -name 'zeek-*-fuzzer')
+fuzzer_count=1
+
+function copy_lib
+    {
+    local fuzzer_path=$1
+    local lib=$2
+    cp $(ldd ${fuzzer_path} | grep "${lib}" | awk '{ print $3 }') ${OUT}/lib
+    }
+
+for f in ${fuzzers}; do
+    fuzzer_exe=$(basename ${f})
+    fuzzer_name=$(echo ${fuzzer_exe} | sed 's/zeek-\(.*\)-fuzzer/\1/g')
+
+    cp ${f} ${OUT}/
+
+    # Set up run-time dependency libraries
+    if [[ "${fuzzer_count}" -eq "1" ]]; then
+        mkdir -p ${OUT}/lib
+        zeek_libs=$(ldd ${f} | grep 'zeek/build' | awk '{ print $1 }' )
+
+        for lib in ${zeek_libs}; do
+            copy_lib ${f} ${lib}
+        done
+
+        copy_lib ${f} libpcap
+        copy_lib ${f} libssl
+        copy_lib ${f} libcrypto
+        copy_lib ${f} libz
+        copy_lib ${f} libmaxminddb
+    fi
+
+    patchelf --set-rpath '$ORIGIN/lib' ${OUT}/${fuzzer_exe}
+
+    if [[ -e ../src/fuzzers/${fuzzer_name}.dict ]]; then
+        cp ../src/fuzzers/${fuzzer_name}.dict ${OUT}/${fuzzer_exe}.dict
+    fi
+
+    if [[ -e ../src/fuzzers/${fuzzer_name}-corpus.zip ]]; then
+        cp ../src/fuzzers/${fuzzer_name}-corpus.zip ${OUT}/${fuzzer_exe}_seed_corpus.zip
+    fi
+
+    fuzzer_count=$((fuzzer_count + 1))
+done
diff --git a/projects/zeek/project.yaml b/projects/zeek/project.yaml
new file mode 100644
index 0000000..f84acfa
--- /dev/null
+++ b/projects/zeek/project.yaml
@@ -0,0 +1,17 @@
+homepage: "https://www.zeek.org"
+language: c++
+primary_contact: "security@zeek.org"
+auto_ccs:
+  - "jsiwek@corelight.com"
+  - "robin@corelight.com"
+  - "johanna@corelight.com"
+  - "tim@corelight.com"
+  - "seth@corelight.com"
+  - "justin@corelight.com"
+  - "vern@corelight.com"
+  - "vlad@es.net"
+fuzzing_engines:
+  - libfuzzer
+  - honggfuzz
+sanitizers:
+  - address
diff --git a/projects/zopfli/Dockerfile b/projects/zopfli/Dockerfile
index f4fe985..378b76e 100644
--- a/projects/zopfli/Dockerfile
+++ b/projects/zopfli/Dockerfile
@@ -19,4 +19,4 @@
 RUN apt-get update && apt-get install -y make autoconf automake libtool
 RUN git clone --depth 1 https://github.com/google/zopfli
 WORKDIR zopfli
-COPY build.sh zopfli_compress_fuzzer.cc $SRC/
+COPY build.sh *.cc $SRC/
diff --git a/projects/zopfli/zopfli_deflate_fuzzer.cc b/projects/zopfli/zopfli_deflate_fuzzer.cc
new file mode 100644
index 0000000..07b50c9
--- /dev/null
+++ b/projects/zopfli/zopfli_deflate_fuzzer.cc
@@ -0,0 +1,45 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <string>
+
+#include "deflate.h"
+#include "zopfli.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  ZopfliOptions options;
+  ZopfliInitOptions(&options);
+
+  FuzzedDataProvider stream(data, size);
+
+  // From documentation: valid values for btype are 0, 1, or 2.
+  const int btype = stream.PickValueInArray({0, 1, 2});
+  // The final parameter is an int but it is used as a bool.
+  const int is_final = stream.ConsumeIntegralInRange(0, 1);
+  const std::string input = stream.ConsumeRemainingBytesAsString();
+
+  unsigned char* out = nullptr;
+  size_t outsize = 0;
+  unsigned char bp = 0;  // Apparently must be zero.
+  ZopfliDeflate(&options, btype, is_final,
+                reinterpret_cast<const unsigned char*>(input.data()),
+                input.size(), &bp, &out, &outsize);
+
+  if (out != nullptr) {
+    free(out);
+  }
+
+  return 0;
+}