diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-08-14 18:30:16 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-14 10:30:16 +0000 |
commit | ed1be4ca68daa9782ea65135110799a4bf0697f8 (patch) | |
tree | 29d3465f32643df3e3d7f76e56e3dad4afb56b75 /modules/util | |
parent | cafce3b4b5afb3f254a48e87f1516d7b5dc209b6 (diff) | |
download | gitea-ed1be4ca68daa9782ea65135110799a4bf0697f8.tar.gz gitea-ed1be4ca68daa9782ea65135110799a4bf0697f8.zip |
Handle base64 decoding correctly to avoid panic (#26483)
Fix the panic if the "base64 secret" is too long.
Diffstat (limited to 'modules/util')
-rw-r--r-- | modules/util/util.go | 11 | ||||
-rw-r--r-- | modules/util/util_test.go | 14 |
2 files changed, 25 insertions, 0 deletions
diff --git a/modules/util/util.go b/modules/util/util.go index 9d5e6c1e89..cc25539967 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -6,6 +6,7 @@ package util import ( "bytes" "crypto/rand" + "encoding/base64" "fmt" "math/big" "strconv" @@ -261,3 +262,13 @@ func ToFloat64(number any) (float64, error) { func ToPointer[T any](val T) *T { return &val } + +func Base64FixedDecode(encoding *base64.Encoding, src []byte, length int) ([]byte, error) { + decoded := make([]byte, encoding.DecodedLen(len(src))+3) + if n, err := encoding.Decode(decoded, src); err != nil { + return nil, err + } else if n != length { + return nil, fmt.Errorf("invalid base64 decoded length: %d, expects: %d", n, length) + } + return decoded[:length], nil +} diff --git a/modules/util/util_test.go b/modules/util/util_test.go index c5830ce01c..8509d8aced 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -4,6 +4,7 @@ package util import ( + "encoding/base64" "regexp" "strings" "testing" @@ -233,3 +234,16 @@ func TestToPointer(t *testing.T) { val123 := 123 assert.False(t, &val123 == ToPointer(val123)) } + +func TestBase64FixedDecode(t *testing.T) { + _, err := Base64FixedDecode(base64.RawURLEncoding, []byte("abcd"), 32) + assert.ErrorContains(t, err, "invalid base64 decoded length") + _, err = Base64FixedDecode(base64.RawURLEncoding, []byte(strings.Repeat("a", 64)), 32) + assert.ErrorContains(t, err, "invalid base64 decoded length") + + str32 := strings.Repeat("x", 32) + encoded32 := base64.RawURLEncoding.EncodeToString([]byte(str32)) + decoded32, err := Base64FixedDecode(base64.RawURLEncoding, []byte(encoded32), 32) + assert.NoError(t, err) + assert.Equal(t, str32, string(decoded32)) +} |