From 4da8d3ffa734736cb61297a4a9c115d053a3fffb Mon Sep 17 00:00:00 2001 From: Daniel Reiter Horn Date: Wed, 21 Nov 2018 00:57:33 -0800 Subject: [PATCH] some negative tests. Expose BrotliDecoderVersion information --- c/go/brotli/brotli.go | 10 ++- c/go/interface_test.go | 188 ++++++++++++++++------------------------- c/py/brotli.py | 17 +++- c/py/brotli_test.py | 22 +++++ 4 files changed, 118 insertions(+), 119 deletions(-) diff --git a/c/go/brotli/brotli.go b/c/go/brotli/brotli.go index bdf6ef59..0a6cbc11 100644 --- a/c/go/brotli/brotli.go +++ b/c/go/brotli/brotli.go @@ -1,7 +1,7 @@ package brotli /* -#cgo CFLAGS: -I../../.. -I. +#cgo CFLAGS: -I. -I../../.. #cgo LDFLAGS: -L../../../target/release -L../target/release -L../../target/release -lbrotli_ffi -lm -ldl #include "brotli/encode.h" #include "brotli/decode.h" @@ -54,6 +54,14 @@ type CompressionOptions struct { AvoidDistancePrefixSearch bool } +func BrotliEncoderVersion() uint32 { + return uint32(C.BrotliEncoderVersion()) +} + +func BrotliDecoderVersion() uint32 { + return uint32(C.BrotliDecoderVersion()) +} + type MultiCompressionReader struct { options CompressionOptions buffer []byte diff --git a/c/go/interface_test.go b/c/go/interface_test.go index 3f3802bd..3e963760 100644 --- a/c/go/interface_test.go +++ b/c/go/interface_test.go @@ -1,12 +1,12 @@ package main import ( - //"io/ioutil" - //"os" "bytes" "fmt" "io" + "io/ioutil" "testing" + "github.com/dropbox/rust-brotli/c/go/brotli" ) @@ -79,6 +79,69 @@ func TestCompressRoundtrip(*testing.T) { panic(fmt.Sprintf("Bytes not equal %d, %d", len(outBuffer.Bytes()), len(data))) } } + +func TestRejectCorruptBuffers(*testing.T) { + tmp := testData() + data := tmp[:len(tmp)-17] + outBuffer := bytes.NewBuffer(nil) + compressedBuffer := bytes.NewBuffer(nil) + var options = brotli.CompressionOptions{ + NumThreads: 1, + Quality: 4, + Catable: true, + Appendable: true, + Magic: true, + } + writer := brotli.NewMultiCompressionWriter( + compressedBuffer, + options, + ) + _, err := writer.Write(data[:]) + if err != nil { + panic(err) + } + err = writer.Close() + if err != nil { + panic(err) + } + decompressorWriter := brotli.NewDecompressionWriter( + outBuffer, + ) + // early EOF + _, err = decompressorWriter.Write(compressedBuffer.Bytes()[:len(compressedBuffer.Bytes())-1]) + if err != nil { + panic(err) + } + err = decompressorWriter.Close() + if err == nil { + panic("Expected error") + } + decompressorWriter = brotli.NewDecompressionWriter( + outBuffer, + ) + _, err = decompressorWriter.Write(compressedBuffer.Bytes()[:len(compressedBuffer.Bytes())/2]) + if err != nil { + panic(err) + } + // missed a byte + _, err = decompressorWriter.Write(compressedBuffer.Bytes()[len(compressedBuffer.Bytes())/2+1:]) + if err == nil { + panic("ExpectedError") + } + _ = decompressorWriter.Close() + corruptBuffer := bytes.NewBuffer(compressedBuffer.Bytes()[:len(compressedBuffer.Bytes())-1]) + decompressorReader := brotli.NewDecompressionReader(corruptBuffer) + _, err = ioutil.ReadAll(decompressorReader) + if err == nil { + panic("ExpectedError") + } + decompressorReader = brotli.NewDecompressionReader(compressedBuffer) + _, err = ioutil.ReadAll(decompressorReader) + if err != nil { + panic(err) + } +} + func TestCompressReader(*testing.T) { data := testData() inBuffer := bytes.NewBuffer(data[:]) @@ -234,120 +297,11 @@ func TestConcatReaderRoundtrip(*testing.T) { } } -/* - useWriter := false— - var toCat []string - for index, arg := range os.Args { - if index == 0 { - continue - } - if arg == "-w" { - useWriter = true - } - if arg == "-d" { - decompress = true - } - if arg == "-cat" { - toCat = append(toCat, os.Args[index+1:]...) - break - } - } - if toCat != nil { - if useWriter { - buffers := make([][]byte, len(toCat)) - for index, fn := range toCat { - var err error - buffers[index], err = ioutil.ReadFile(fn) - if err != nil { - panic(err) - } - } - final, err := BroccoliConcat(buffers...) - if err != nil { - panic(err) - } - _, err = os.Stdout.Write(final) - if err != nil { - panic(err) - } - } else { - files := make([]io.Reader, len(toCat)) - for index, fn := range toCat { - var err error - files[index], err = os.Open(fn) - if err != —nil { - panic(err) - } - } - _, err := io.Copy(os.Stdout, brotli.NewBroccoliConcatReader(files...)) - if err != nil { - panic(err) - } - for _, file := range files { - if readCloser, ok := file.(io.ReadCloser); ok { - _ = readCloser.Close() - } - } - } - return - } else if useWriter { - var writer io.Writer - if decompress { - writer = brotli.NewDecompressionWriter( - os.Stdout, - ) - } else { - writer = brotli.NewMultiCompressionWriter( - os.Stdout, - options, - ) - } - for { - var buffer [65536]byte - count, err := os.Stdin.Read(buffer[:]) - if err == io.EOF { - break - } - if err != nil { - panic(err) - } - _, err = writer.Write(buffer[:count]) - if err != nil { - panic(err) - } - } - if writeCloser, ok := writer.(io.WriteCloser); ok { - err := writeCloser.Close() - if err != nil { - panic(err) - } - } - } else { - var reader io.Reader - if decompress { - reader = brotli.NewDecompressionReader( - os.Stdin, - ) - } else { - reader = brotli.NewMultiCompressionReader( - os.Stdin, - options, - ) - } - for { - var buffer [65536]byte - size, err := reader.Read(buffer[:]) - _, werr := os.Stdout.Write(buffer[:size]) - if werr != nil { - panic(werr) - } - if err == io.EOF { - return - } - if err != nil { - panic(err) - } - } +func TestVersions(*testing.T) { + if brotli.BrotliEncoderVersion() == 0 { + panic(fmt.Sprintf("Bad version %d\n", brotli.BrotliEncoderVersion())) + } + if brotli.BrotliDecoderVersion() == 0 { + panic(fmt.Sprintf("Bad version %d\n", brotli.BrotliDecoderVersion())) } } -*/ diff --git a/c/py/brotli.py b/c/py/brotli.py index 297192e1..348f57a5 100644 --- a/c/py/brotli.py +++ b/c/py/brotli.py @@ -35,6 +35,21 @@ class BrotliDecompressorException(Exception): _BrotliDecoderGetErrorString = brotli_library.BrotliDecoderGetErrorString _BrotliDecoderGetErrorString.restype = c_char_p + +_BrotliEncoderVersion = brotli_library.BrotliEncoderVersion +_BrotliEncoderVersion.restype = c_uint32 + +_BrotliDecoderVersion = brotli_library.BrotliDecoderVersion +_BrotliDecoderVersion.restype = c_uint32 + +def BrotliEncoderVersion(): + # type: () -> int + return _BrotliEncoderVersion() + +def BrotliDecoderVersion(): + # type: () -> int + return _BrotliDecoderVersion() + BROTLI_DECODER_RESULT_ERROR = 0 BROTLI_DECODER_RESULT_SUCCESS = 1 BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2 @@ -125,7 +140,7 @@ def BrotliDecode(any_input, expected_size=4096 * 1024, max_expected_size = 256 * else: expected_size *= 2 if expected_size > max_expected_size: - raise BrotliDecompressorException("Brotli file > " + max_expected_size + " or corrupt brotli file") + raise BrotliDecompressorException("Brotli file > " + str(max_expected_size) + " or corrupt brotli file") def BrotliCompress( diff --git a/c/py/brotli_test.py b/c/py/brotli_test.py index f5efc4de..a72a1a20 100644 --- a/c/py/brotli_test.py +++ b/c/py/brotli_test.py @@ -5,6 +5,10 @@ class TestBrotliLibrary(unittest.TestCase): def setUp(self): self.test_data = make_test_data(4096 * 1024) + def test_version(self): + assert BrotliDecoderVersion() + assert BrotliEncoderVersion() + def test_wp_rt(self): wp = BrotliEncoderCreateWorkPool(8) output = BrotliEncoderCompressWorkPool(wp, @@ -78,6 +82,24 @@ def test_rnd(self): rt = BrotliDecode(output) assert rt == random_data assert len(output) > 130000 + def test_1(self): + output = BrotliCompress(self.test_data[:65536], + { + BROTLI_PARAM_QUALITY:6, + BROTLI_PARAM_CATABLE:1, + BROTLI_PARAM_MAGIC_NUMBER:1, + }, + 8) + corrupt = output[:len(output) - 1] + rt = BrotliDecode(output) + assert rt == self.test_data[:65536] + assert len(output) < 1024 * 1024 + try: + BrotliDecode(corrupt) + except BrotliDecompressorException: + pass + else: + assert False, "Should have errored" if __name__ == '__main__': unittest.main()