Explorar o código

Merge pull request #86 from greatroar/corner-cases

Fix and test some corner cases in the decoders
Pierre Curto %!s(int64=5) %!d(string=hai) anos
pai
achega
a74653b609

+ 2 - 0
internal/lz4block/decode_amd64.s

@@ -26,6 +26,8 @@ TEXT ·decodeBlock(SB), NOSPLIT, $64-56
 
 	MOVQ src_base+24(FP), SI
 	MOVQ src_len+32(FP), R9
+	CMPQ R9, $0
+	JE   err_corrupt
 	ADDQ SI, R9
 
 	// shortcut ends

+ 3 - 1
internal/lz4block/decode_other.go

@@ -60,8 +60,10 @@ func decodeBlock(dst, src []byte) (ret int) {
 				di += lLen
 			}
 		}
-		if si >= uint(len(src)) {
+		if si == uint(len(src)) {
 			return int(di)
+		} else if si > uint(len(src)) {
+			return hasError
 		}
 
 		offset := uint(src[si]) | uint(src[si+1])<<8

+ 30 - 0
internal/lz4block/decode_test.go

@@ -84,6 +84,11 @@ func TestBlockDecode(t *testing.T) {
 		src  []byte
 		exp  []byte
 	}{
+		{
+			"empty_input",
+			[]byte{0},
+			[]byte{},
+		},
 		{
 			"literal_only_short",
 			emitSeq("hello", 0, 0),
@@ -135,3 +140,28 @@ func TestBlockDecode(t *testing.T) {
 		})
 	}
 }
+
+func TestDecodeBlockInvalid(t *testing.T) {
+	t.Parallel()
+
+	dst := make([]byte, 100)
+
+	for _, test := range []struct {
+		name string
+		src  string
+	}{
+		{
+			"empty_input",
+			"",
+		},
+		{
+			"final_lit_too_short",
+			"\x20a", // litlen = 2 but only a single-byte literal
+		},
+	} {
+		r := decodeBlock(dst, []byte(test.src))
+		if r >= 0 {
+			t.Errorf("no error for %s", test.name)
+		}
+	}
+}