aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2022-12-17 11:59:24 +0100
committerDmitry Vyukov <dvyukov@google.com>2022-12-22 10:11:08 +0100
commit8482d3c1035095c89d112c75bfcc2e4095b486bf (patch)
treef2cc2b32e55fd61cbcd03d1b27693fe7c972f07b /pkg
parent412eecf40d514f89060844dc8631f60b80d7bfd2 (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.go71
-rw-r--r--pkg/image/compression_test.go44
-rw-r--r--pkg/ipc/ipc_test.go5
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)