summaryrefslogtreecommitdiffstats
path: root/modules/util
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2023-08-14 18:30:16 +0800
committerGitHub <noreply@github.com>2023-08-14 10:30:16 +0000
commited1be4ca68daa9782ea65135110799a4bf0697f8 (patch)
tree29d3465f32643df3e3d7f76e56e3dad4afb56b75 /modules/util
parentcafce3b4b5afb3f254a48e87f1516d7b5dc209b6 (diff)
downloadgitea-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.go11
-rw-r--r--modules/util/util_test.go14
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))
+}