Skip to content
Permalink
Browse files

add continuous fuzzing via fuzzit

This mainly means adding the code from the old 'fuzz' branch, adding a
go.mod to track dependencies such as go-fuzz and the fuzzit tool, and
then making CI run the appropriate commands for regression testing and
continuous fuzzing.

Finally, add the badge to show the current status.

We've used a separate module to not pollute the main go.mod and go.sum
files with all the fuzzing-specific deps. This also means that it's
simpler to construct a GOPATH for go-fuzz, as we can simply use 'go mod
vendor' and rename the folder.

While at it, start using GOPROXY on CI to speed up the builds, and
remove GO 1.11, since it doesn't support GOPROXY - and since 1.13 is
about to be released.
  • Loading branch information...
mvdan committed Aug 19, 2019
1 parent 78ca878 commit 6c13161a56af5dece4e33497e909ee4cbe3ee6bf
Showing with 487 additions and 11 deletions.
  1. +10 −3 .gitignore
  2. +7 −8 .travis.yml
  3. +1 −0 README.md
  4. +19 −0 _fuzz/it/fuzz-ci
  5. +10 −0 _fuzz/it/fuzz-gopath
  6. +66 −0 _fuzz/it/fuzz.go
  7. +18 −0 _fuzz/it/go.mod
  8. +347 −0 _fuzz/it/go.sum
  9. +9 −0 _fuzz/it/tools.go
@@ -1,6 +1,13 @@
/suppressions/
/crashers/
/sh-fuzz.zip
*.a
*.zip
fuzzit-program

# Don't store any of this in the master branch.
suppressions/
crashers/
gopath/
corpus/
vendor/

/_js/index.js*
/_js/_js.js*
@@ -2,15 +2,14 @@ language: go

env:
global:
- GO111MODULE=on
- GO111MODULE="on"
- GOPROXY="https://proxy.golang.org"

matrix:
include:
- os: linux
go: 1.11.x
- os: linux
go: 1.12.x
env: LATEST_GO=1
env: MAIN_ENV=1
- os: osx
go: 1.12.x
- os: windows
@@ -21,7 +20,7 @@ install: true
script:
- go install ./...
- go test ./...
# TODO: reenable test -race on windows once TestInteractive stops failing
- if [[ $TRAVIS_OS_NAME != "windows" ]]; then go test -short -race ./...; fi
- shfmt -version
- if [[ -n $LATEST_GO ]]; then diff <(echo -n) <(gofmt -d .); fi
- if [[ $TRAVIS_OS_NAME != windows ]]; then go test -short -race ./...; fi
- if [[ -n $MAIN_ENV ]]; then diff <(echo -n) <(gofmt -d .); fi
- if [[ -n $MAIN_ENV ]]; then cd _fuzz/it && ./fuzz-ci local-regression 2>&1 | grep -vE '^Running|^Executed'; fi
- if [[ -n $MAIN_ENV && $TRAVIS_EVENT_TYPE == push && $TRAVIS_BRANCH == master ]]; then ./fuzz-ci fuzzing; fi
@@ -2,6 +2,7 @@

[![GoDoc](https://godoc.org/mvdan.cc/sh?status.svg)](https://godoc.org/mvdan.cc/sh)
[![Build](https://travis-ci.org/mvdan/sh.svg?branch=master)](https://travis-ci.org/mvdan/sh)
[![fuzzit](https://app.fuzzit.dev/badge?org_id=mvdan)](https://fuzzit.dev)

A shell parser, formatter and interpreter. Supports [POSIX Shell], [Bash] and
[mksh]. Requires Go 1.11 or later.
@@ -0,0 +1,19 @@
#!/bin/bash

set -xe

go install \
github.com/dvyukov/go-fuzz/go-fuzz \
github.com/dvyukov/go-fuzz/go-fuzz-build \
github.com/fuzzitdev/fuzzit

./fuzz-gopath
export GOPATH=$PWD/gopath
export GO111MODULES=off

go-fuzz-build -libfuzzer -o fuzzit-program.a .
clang -fsanitize=fuzzer fuzzit-program.a -o fuzzit-program

fuzzit create job --type ${1} mvdan/sh-syntax-parser-printer fuzzit-program

rm -rf gopath/ fuzzit-program.a fuzzit-program
@@ -0,0 +1,10 @@
#!/bin/sh

set -e -x

# Hacky way to make go-fuzz work with modules.
go mod vendor
rm -rf gopath
mkdir -p gopath/src/
mv vendor/*/ gopath/src/
rm -rf vendor
@@ -0,0 +1,66 @@
// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

// +build gofuzz

package sh

import (
"bytes"
"io/ioutil"

"mvdan.cc/sh/v3/syntax"

// This package is required for go-fuzz-build, so pin it here for
// 'go mod vendor' to include it.
_ "github.com/dvyukov/go-fuzz/go-fuzz-dep"
)

func Fuzz(data []byte) int {
// first byte masks for parser/printer options:
// 1: posix, not bash
// 2: mksh, not bash
// 4: keep comments
// 8: simplify
// 16: indent with spaces
// 32: binary next line
// 64: switch case indent
// 128: keep padding
if len(data) < 1 {
return 0
}
opts, src := data[0], data[1:]
parser := syntax.NewParser()
lang := syntax.LangBash
if opts&0x01 != 0 {
lang = syntax.LangPOSIX
} else if opts&0x02 != 0 {
lang = syntax.LangMirBSDKorn
}
syntax.Variant(lang)(parser)
if opts&0x04 != 0 {
syntax.KeepComments(parser)
}
prog, err := parser.Parse(bytes.NewReader(src), "")
if err != nil {
return 0
}
if opts&0x08 != 0 {
syntax.Simplify(prog)
}
printer := syntax.NewPrinter()
if opts&0x10 != 0 {
syntax.Indent(4)(printer)
}
if opts&0x20 != 0 {
syntax.BinaryNextLine(printer)
}
if opts&0x40 != 0 {
syntax.SwitchCaseIndent(printer)
}
if opts&0x80 != 0 {
syntax.KeepPadding(printer)
}
printer.Print(ioutil.Discard, prog)
return 1
}
@@ -0,0 +1,18 @@
module local.tld/fuzz

go 1.13

replace mvdan.cc/sh/v3 => ./../..

require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/dvyukov/go-fuzz v0.0.0-20190808141544-193030f1cb16
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
github.com/frankban/quicktest v1.4.1 // indirect
github.com/fuzzitdev/fuzzit v1.2.8-0.20190819063729-75c132bbbc59
github.com/gorilla/mux v1.7.3 // indirect
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/stephens2424/writerset v1.0.2 // indirect
gotest.tools v2.2.0+incompatible // indirect
mvdan.cc/sh/v3 v3.0.0-00010101000000-000000000000
)

Large diffs are not rendered by default.

@@ -0,0 +1,9 @@
// +build tools

package tools

import (
_ "github.com/dvyukov/go-fuzz/go-fuzz"
_ "github.com/dvyukov/go-fuzz/go-fuzz-build"
_ "github.com/fuzzitdev/fuzzit"
)

0 comments on commit 6c13161

Please sign in to comment.
You can’t perform that action at this time.