Added fuzzing tests

This commit is contained in:
Zahary Karadjov 2020-05-20 21:05:35 +03:00
parent b4cd68e27a
commit f6a87764a3
No known key found for this signature in database
GPG Key ID: C8936F8A3073D609
9 changed files with 121 additions and 12 deletions

9
.gitignore vendored
View File

@ -1,3 +1,10 @@
nimcache/
snappycpp/
master
*.exe
*.a
*.a
# Fuzzer-generated files
crash-*

View File

@ -1,7 +1,7 @@
import
stew/ranges/ptr_arith,
faststreams/[inputs, outputs, buffers, multisync],
snappy/utils
snappy/[types, utils]
const
tagLiteral* = 0x00
@ -11,10 +11,8 @@ const
inputMargin = 16 - 1
type
SnappyError* = object of CatchableError
UnexpectedEofError* = object of SnappyError
MalformedSnappyData* = object of SnappyError
export
types
# PutUvarint encodes a uint64 into buf and returns the number of bytes written.
proc putUvarint(s: OutputStream, x: uint64) =

View File

@ -1,8 +1,11 @@
import
../snappy, ../snappy/utils,
../tests/openarrays_snappy as oas,
faststreams/[inputs, outputs, multisync],
stew/endians2
stew/endians2,
../snappy, utils, types,
../tests/openarrays_snappy as oas
export
types
{.compile: "crc32c.c".}
# TODO: we don't have a native implementation of CRC32C algorithm yet.
@ -63,7 +66,7 @@ proc uncompressFramedStream*(input: InputStream, output: OutputStream) {.fsMulti
if uncompressedLen <= 0:
raise newException(MalformedSnappyData, "Failed to decompress content")
if not checkCrcAndAppend(Sync output, uncompressedData.toOpenArray(0, uncompressedLen-1), crc):
raise newException(MalformedSnappyData, "Content CRC checksum failed")
@ -88,11 +91,14 @@ proc uncompressFramedStream*(input: InputStream, output: OutputStream) {.fsMulti
finally:
close output
proc framingFormatUncompress*(input: openarray[byte]): seq[byte] =
proc framingFormatUncompress*(input: InputStream): seq[byte] =
var output = memoryOutput()
uncompressFramedStream unsafeMemoryInput(input), output
uncompressFramedStream input, output
return output.getOutput
proc framingFormatUncompress*(input: openarray[byte]): seq[byte] =
framingFormatUncompress unsafeMemoryInput(input)
proc processFrame*(output: OutputStream, dst: var openArray[byte], src: openArray[byte]) =
let
crc = masked_crc32c(src[0].unsafeAddr, src.len.uint)

5
snappy/types.nim Normal file
View File

@ -0,0 +1,5 @@
type
SnappyError* = object of CatchableError
UnexpectedEofError* = object of SnappyError
MalformedSnappyData* = object of SnappyError

3
tests/fuzzing/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
corpus/
nimcache/

View File

@ -0,0 +1,37 @@
import
os,
../../snappy,
../../snappy/framing
let
fuzzingDir = getAppDir()
dataDir = fuzzingDir / ".." / "data"
corpusDir = fuzzingDir / "corpus"
blockFormatCorpusDir = corpusDir / "block_format"
framingFormatCorpusDir = corpusDir / "framing_format"
removeDir corpusDir
createDir blockFormatCorpusDir
createDir framingFormatCorpusDir
for kind, file in walkDir(dataDir):
if kind != pcFile:
continue
let size = getFileSize(file)
if size > 50000:
continue
let
fileContents = cast[seq[byte]](readFile(file))
fileName = splitFile(file).name
blockFileName = changeFileExt(fileName, "snappy")
framingFileName = changeFileExt(fileName, "fsnappy")
writeFile(blockFormatCorpusDir / blockFileName,
snappy.encode(fileContents))
writeFile(framingFormatCorpusDir / framingFileName,
framingFormatCompress(fileContents))

View File

@ -0,0 +1,13 @@
import
testutils/fuzzing,
../../snappy
test:
block:
try:
let decoded = snappy.decode(payload)
let encoded = snappy.encode(decoded)
doAssert encoded == payload
except SnappyError:
discard

View File

@ -0,0 +1,17 @@
import
faststreams/inputs, testutils/fuzzing,
../../snappy/framing
test:
block:
try:
let input = unsafeMemoryInput(payload)
let decoded = framingFormatUncompress(input)
if input.len.get > 0:
break
let encoded = framingFormatCompress(decoded)
doAssert encoded == payload
except SnappyError:
discard

View File

@ -0,0 +1,23 @@
import
os, strformat,
confutils, testutils/fuzzing_engines
type
SnappyFormat = enum
block_format
framing_format
cli do (format {.argument.}: SnappyFormat,
fuzzer = libFuzzer):
let
fuzzingDir = thisDir()
fuzzingFile = fuzzingDir / "fuzz_" & addFileExt($format, "nim")
corpusDir = fuzzingDir / "corpus" / $format
let
collectCorpusNim = fuzzingDir / "collect_corpus.nim"
fuzzNims = fuzzingDir / ".." / ".." / ".." / "nim-testutils" / "testutils" / "fuzzing" / "fuzz.nims"
exec &"""nim c -r "{collectCorpusNim}""""
exec &"""nim "{fuzzNims}" {fuzzer} "{fuzzingFile}" "{corpusDir}" """