1
0
Fork 0
golang-github-dop251-base64dec/decoder_test.go
Daniel Baumann 0e47c428eb
Adding upstream version 0.0~git20231022.c6c9f9a.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-22 11:58:01 +02:00

149 lines
3.6 KiB
Go

package base64dec
import (
"bytes"
"encoding/base64"
"fmt"
"testing"
)
func TestDecodeBase64(t *testing.T) {
f := func(t *testing.T, input, expectedResult string, expectedError error) {
decoded := make([]byte, base64.RawStdEncoding.DecodedLen(len(input)))
n, err := DecodeBase64(decoded, input)
if err != expectedError {
t.Fatal(err)
}
encoded := base64.StdEncoding.EncodeToString(decoded[:n])
if encoded != expectedResult {
t.Fatal(encoded)
}
}
t.Run("empty input", func(t *testing.T) {
f(t, "", "", nil)
})
t.Run("newlines only", func(t *testing.T) {
f(t, "\r\n", "", nil)
})
t.Run("correct padding", func(t *testing.T) {
f(t, "Z9CA-w==", "Z9CA+w==", nil)
})
t.Run("correct padding split by newline", func(t *testing.T) {
f(t, "Z9CA-w=\n=", "Z9CA+w==", nil)
})
t.Run("correct padding with concatenation", func(t *testing.T) {
f(t, "Z9CA-w==Z9CA-w==", "Z9CA+w==", base64.CorruptInputError(8))
})
t.Run("trailing newline", func(t *testing.T) {
f(t, "Z9CA+wZ9CA-w\n", "Z9CA+wZ9CA+w", nil)
})
t.Run("trailing newline with padding", func(t *testing.T) {
f(t, "Z9CA+wZ9CA-www==\n", "Z9CA+wZ9CA+www==", nil)
})
t.Run("garbage after newline", func(t *testing.T) {
f(t, "Z9CA+wZ9CA-www==\n?", "Z9CA+wZ9CA+www==", base64.CorruptInputError(17))
})
t.Run("no padding", func(t *testing.T) {
f(t, "Z9CA-w", "Z9CA+w==", nil)
})
t.Run("no padding, garbage at the end", func(t *testing.T) {
f(t, "Z9CA-w???", "Z9CA+w==", base64.CorruptInputError(6))
})
t.Run("not enough padding", func(t *testing.T) {
f(t, "Z9CA-w=", "Z9CA+w==", base64.CorruptInputError(6))
})
t.Run("incorrect padding", func(t *testing.T) {
f(t, "Z9CA====", "Z9CA", base64.CorruptInputError(4))
})
t.Run("incorrect padding with extra base64", func(t *testing.T) {
f(t, "Z9CA-w=Z9CA-w=", "Z9CA+w==", base64.CorruptInputError(6))
})
t.Run("incorrect padding with garbage", func(t *testing.T) {
f(t, "Z9CA-w=???", "Z9CA+w==", base64.CorruptInputError(6))
})
}
func FuzzDecodeBase64(f *testing.F) {
f.Add([]byte{})
f.Add([]byte("\x14\xfb\x9c\x03\xd9\x7e"))
f.Add([]byte("\x14\xfb\x9c\x03\xd9"))
f.Add([]byte("\x14\xfb\x9c\x03"))
f.Fuzz(func(t *testing.T, b []byte) {
encoded := base64.StdEncoding.EncodeToString(b)
decoded := make([]byte, len(b))
n, err := DecodeBase64(decoded, encoded)
if err != nil {
t.Fatalf("%v: %v", b, err)
}
if !bytes.Equal(decoded[:n], b) {
t.Fatal(b)
}
})
}
func FuzzDecodeBase64String(f *testing.F) {
f.Add("Z9CA-w")
f.Add("=\n=")
f.Add("=")
f.Add("====")
f.Fuzz(func(t *testing.T, s string) {
decoded := make([]byte, base64.RawStdEncoding.DecodedLen(len(s)))
_, _ = DecodeBase64(decoded, s) // should not panic
})
}
func BenchmarkDecodeBase64(b *testing.B) {
sizes := []int{2, 4, 8, 64, 8192}
dst := make([]byte, 8192)
benchFunc := func(b *testing.B, benchSize int) {
data := base64.StdEncoding.EncodeToString(make([]byte, benchSize))
b.SetBytes(int64(len(data)))
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
DecodeBase64(dst, data)
}
}
for _, size := range sizes {
b.Run(fmt.Sprintf("%d", size), func(b *testing.B) {
benchFunc(b, size)
})
}
}
func BenchmarkDecodeBase64Std(b *testing.B) {
sizes := []int{2, 4, 8, 64, 8192}
dst := make([]byte, 8192)
benchFunc := func(b *testing.B, benchSize int) {
data := base64.StdEncoding.EncodeToString(make([]byte, benchSize))
b.SetBytes(int64(len(data)))
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
base64.StdEncoding.Decode(dst, []byte(data))
}
}
for _, size := range sizes {
b.Run(fmt.Sprintf("%d", size), func(b *testing.B) {
benchFunc(b, size)
})
}
}