diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-12-17 11:59:24 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-12-22 10:11:08 +0100 |
| commit | 8482d3c1035095c89d112c75bfcc2e4095b486bf (patch) | |
| tree | f2cc2b32e55fd61cbcd03d1b27693fe7c972f07b /pkg | |
| parent | 412eecf40d514f89060844dc8631f60b80d7bfd2 (diff) | |
pkg/image: factor out from prog
Move image compression-related function to a separate package.
In preperation for subsequent changes that make decompression
more complex. Prog package is already large and complex.
Also makes running compression tests/benchmarks much faster.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/image/compression.go | 71 | ||||
| -rw-r--r-- | pkg/image/compression_test.go | 44 | ||||
| -rw-r--r-- | pkg/ipc/ipc_test.go | 5 |
3 files changed, 118 insertions, 2 deletions
diff --git a/pkg/image/compression.go b/pkg/image/compression.go new file mode 100644 index 000000000..9878b460d --- /dev/null +++ b/pkg/image/compression.go @@ -0,0 +1,71 @@ +// Copyright 2022 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package image + +import ( + "bytes" + "compress/zlib" + "encoding/base64" + "fmt" + "io" +) + +func Compress(rawData []byte) []byte { + var buffer bytes.Buffer + zlibWriter := zlib.NewWriter(&buffer) + + _, err := zlibWriter.Write(rawData) + if err != nil { + panic(fmt.Sprintf("could not compress with zlib: %v", err)) + } + + err = zlibWriter.Close() + if err != nil { + panic(fmt.Sprintf("could not finalize compression with zlib: %v", err)) + } + + return buffer.Bytes() +} + +func Decompress(compressedData []byte) ([]byte, error) { + buf := new(bytes.Buffer) + err := DecompressWriter(buf, compressedData) + return buf.Bytes(), err +} + +func DecompressWriter(w io.Writer, compressedData []byte) error { + zlibReader, err := zlib.NewReader(bytes.NewReader(compressedData)) + if err != nil { + return fmt.Errorf("could not initialise zlib: %v", err) + } + + if _, err := io.Copy(w, zlibReader); err != nil { + return fmt.Errorf("could not read data with zlib: %v", err) + } + + return zlibReader.Close() +} + +func DecodeB64(b64Data []byte) ([]byte, error) { + decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewReader(b64Data)) + rawData, err := io.ReadAll(decoder) + if err != nil { + return nil, fmt.Errorf("could not decode Base64: %v", err) + } + return rawData, nil +} + +func EncodeB64(rawData []byte) []byte { + var buf bytes.Buffer + encoder := base64.NewEncoder(base64.StdEncoding, &buf) + _, err := encoder.Write(rawData) + if err != nil { + panic(fmt.Sprintf("could not encode Base64: %v", err)) + } + err = encoder.Close() + if err != nil { + panic(fmt.Sprintf("could not finalize encoding to Base64: %v", err)) + } + return buf.Bytes() +} diff --git a/pkg/image/compression_test.go b/pkg/image/compression_test.go new file mode 100644 index 000000000..cf18ed340 --- /dev/null +++ b/pkg/image/compression_test.go @@ -0,0 +1,44 @@ +// Copyright 2022 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package image + +import ( + "bytes" + "fmt" + "math/rand" + "testing" + + "github.com/google/syzkaller/pkg/testutil" +) + +func TestCompress(t *testing.T) { + r := rand.New(testutil.RandSource(t)) + err := testRoundTrip(r, Compress, Decompress) + if err != nil { + t.Fatalf("compress/decompress %v", err) + } +} + +func TestEncode(t *testing.T) { + r := rand.New(testutil.RandSource(t)) + err := testRoundTrip(r, EncodeB64, DecodeB64) + if err != nil { + t.Fatalf("encode/decode Base64 %v", err) + } +} + +func testRoundTrip(r *rand.Rand, transform func([]byte) []byte, inverse func([]byte) ([]byte, error)) error { + for i := 0; i < testutil.IterCount(); i++ { + randBytes := testutil.RandMountImage(r) + resultBytes := transform(randBytes) + resultBytes, err := inverse(resultBytes) + if err != nil { + return err + } + if !bytes.Equal(randBytes, resultBytes) { + return fmt.Errorf("roundtrip changes data (original length %d)", len(randBytes)) + } + } + return nil +} diff --git a/pkg/ipc/ipc_test.go b/pkg/ipc/ipc_test.go index c1d3af69a..a3ab140f1 100644 --- a/pkg/ipc/ipc_test.go +++ b/pkg/ipc/ipc_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/google/syzkaller/pkg/csource" + "github.com/google/syzkaller/pkg/image" . "github.com/google/syzkaller/pkg/ipc" "github.com/google/syzkaller/pkg/ipc/ipcconfig" "github.com/google/syzkaller/pkg/osutil" @@ -210,9 +211,9 @@ func TestZlib(t *testing.T) { r := rand.New(testutil.RandSource(t)) for i := 0; i < 10; i++ { data := testutil.RandMountImage(r) - compressed := prog.Compress(data) + compressed := image.Compress(data) text := fmt.Sprintf(`syz_compare_zlib(&(0x7f0000000000)="$%s", AUTO, &(0x7f0000800000)="$%s", AUTO)`, - prog.EncodeB64(data), prog.EncodeB64(compressed)) + image.EncodeB64(data), image.EncodeB64(compressed)) p, err := target.Deserialize([]byte(text), prog.Strict) if err != nil { t.Fatalf("failed to deserialize empty program: %v", err) |
