Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continuous fuzzing #55

Merged
merged 7 commits into from
Sep 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
dist: bionic
language: go
sudo: false
services:
- docker
env:
GO111MODULE=on
global:
- GO111MODULE=on
# FUZZIT_API_KEY
- secure: "FEm1wF/Ttd5RIvDPg5I/aSAhBWuvkvjmkInFxlVKP4BfLsR1B1ogXV4zKFQiZugyppBta+qP4qP+tSbThSvP9JOCr+/ivnTyYLg/DH1RfQnC7rJmAaZwHGHB+NwblRzU621uIZ4RVvaE391YVJf5519gc+M+bxZ6DO0ScdpbIAVV/7JR9c7Tuvoyi57/MEwAS39k7h83ms8JgRYwuvzpVH9nb6AfYs+CzXuRlsG5mHqFnmzLyG0ewnqh18OoWbyKQwBmM+EoIGmckM8NQZaXWBhEuDP7qdl+QatNfZtK3YwBx2plahBXXMee3NpOAEHOkWxNw1uMb1B8ILDrzrx8oX1A4fF/ZeJl7JLZS/fQUMhDnLG5soA0xaEoAvwhQIHFi3e207rsq9UJsnQlRGhRWzMvx85UR5z+yiur8nVUkogu1DGpH/BPdWbTs+d8behSr7t6Sepo7enjJOPJLz6U67JlP31HvnaLICMEXxJy54BAbdu/47vqFp15lcIMHyDzPltHHWi6uGuRFQPYz8pM5ZAKQ945dO/ZELyEHbjUiLTMFeVoANzahuY56BX6hvsygcOlBWB6ukoJANvxgvM/QYkbh9dMBajYsZqHCWOKRVbBakkqPAUqkBNPOADTp5ZgUwmRySIGzX2X+Efl7cFYZVu+IJl968F8hqYajvS/VCs="
go:
- 1.10.x
- 1.11.x
Expand All @@ -18,3 +24,15 @@ script:
- go test -v -race ./...
- go test -v -covermode=count -coverprofile=cov.out
- $HOME/gopath/bin/goveralls -coverprofile=cov.out -service=travis-ci -repotoken "$COVERALLS_TOKEN" || true
jobs:
include:
- stage: Fuzz regression
go: 1.12.x
script:
- ./fuzzit.sh local-regression

- stage: Fuzz
if: branch = master AND type IN (push)
go: 1.12.x
script:
- ./fuzzit.sh fuzzing
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[![Coverage Status](https://coveralls.io/repos/github/oklog/ulid/badge.svg?branch=master&cache=0)](https://coveralls.io/github/oklog/ulid?branch=master)
[![GoDoc](https://godoc.org/github.com/oklog/ulid?status.svg)](https://godoc.org/github.com/oklog/ulid)
[![Apache 2 licensed](https://img.shields.io/badge/license-Apache2-blue.svg)](https://raw.githubusercontent.com/oklog/ulid/master/LICENSE)
[![fuzzit](https://app.fuzzit.dev/badge?org_id=oklog)](https://app.fuzzit.dev/orgs/oklog/dashboard)

A Go port of [alizain/ulid](https://github.com/alizain/ulid) with binary format implemented.

Expand Down
36 changes: 36 additions & 0 deletions fuzzit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
set -xe

# Validate arguments
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <fuzz-type>"
exit 1
fi

# Configure
NAME=ulid
ROOT=.
TYPE=$1

# Setup
export GO111MODULE="off"
go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-build
go get -d -v -u ./...
if [ ! -f fuzzit ]; then
wget -q -O fuzzit https://github.com/fuzzitdev/fuzzit/releases/download/v2.4.29/fuzzit_Linux_x86_64
chmod a+x fuzzit
fi

# Fuzz
function fuzz {
FUNC=Fuzz$1
TARGET=$2
DIR=${3:-$ROOT}
go-fuzz-build -libfuzzer -func $FUNC -o fuzzer.a $DIR
clang -fsanitize=fuzzer fuzzer.a -o fuzzer
./fuzzit create job --type $TYPE $NAME/$TARGET fuzzer
}
fuzz New new
fuzz NewMonotonic new-monotonic
fuzz Parse parse
fuzz ParseStrict parse-strict
114 changes: 114 additions & 0 deletions ulid_fuzz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// +build gofuzz

package ulid

import (
"bytes"
"encoding/binary"
)

// FuzzNew tests ULID construction.
func FuzzNew(fuzz []byte) int {
ms, entropy := extractFuzzTimestamp(fuzz)
id, err := New(ms, bytes.NewReader(entropy))
if err != nil {
return 0
}
id.Bytes()
id.Entropy()
id.Time()
_, err = id.MarshalText()
if err != nil {
return 0
}
_, err = id.MarshalBinary()
if err != nil {
return 0
}
return 1
}

// FuzzNewMonotonic tests ULID construction with monotonic entropy.
func FuzzNewMonotonic(fuzz []byte) int {
if len(fuzz) < (8 * 10) {
return -1
}
timestamps := fuzz[0 : 8*10]
var entropy []byte
if len(fuzz) > (8 * 10) {
entropy = fuzz[8*10:]
} else {
entropy = []byte{}
}
monotonic := Monotonic(bytes.NewReader(entropy), 0)
var ms uint64
for range [10]struct{}{} {
ms, timestamps = extractFuzzTimestamp(timestamps)
id, err := New(ms, monotonic)
if err != nil {
return 0
}
id.Bytes()
id.Entropy()
id.Time()
_, err = id.MarshalText()
if err != nil {
return 0
}
_, err = id.MarshalBinary()
if err != nil {
return 0
}
}
return 1
}

// FuzzParse tests ULID parsing.
func FuzzParse(fuzz []byte) int {
id, err := Parse(string(fuzz))
if err != nil {
return 0
}
id.Bytes()
id.Entropy()
id.Time()
_, err = id.MarshalText()
if err != nil {
return 0
}
_, err = id.MarshalBinary()
if err != nil {
return 0
}
return 1
}

// FuzzParse tests strict ULID parsing.
func FuzzParseStrict(fuzz []byte) int {
id, err := ParseStrict(string(fuzz))
if err != nil {
return 0
}
id.Bytes()
id.Entropy()
id.Time()
_, err = id.MarshalText()
if err != nil {
return 0
}
_, err = id.MarshalBinary()
if err != nil {
return 0
}
return 1
}

func extractFuzzTimestamp(fuzz []byte) (ms uint64, rest []byte) {
binary.Read(bytes.NewReader(fuzz), binary.LittleEndian, &ms)
if len(fuzz) > 8 {
rest = fuzz[7:]
} else {
rest = []byte{}
}
return
}