add an util method to convert []byte to string
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
65753fe23e
commit
5d24d665bd
23 changed files with 70 additions and 40 deletions
2
go.mod
2
go.mod
|
@ -79,7 +79,7 @@ require (
|
|||
|
||||
require (
|
||||
cloud.google.com/go v0.112.2 // indirect
|
||||
cloud.google.com/go/auth v0.3.0 // indirect
|
||||
cloud.google.com/go/auth v0.4.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.8 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -3,8 +3,11 @@ cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw=
|
|||
cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms=
|
||||
cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs=
|
||||
cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w=
|
||||
cloud.google.com/go/auth v0.4.0 h1:vcJWEguhY8KuiHoSs/udg1JtIRYm3YAWPBE1moF1m3U=
|
||||
cloud.google.com/go/auth v0.4.0/go.mod h1:tO/chJN3obc5AbRYFQDsuFbL4wW5y8LfbPtDCfgwOVE=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
||||
cloud.google.com/go/compute v1.26.0 h1:uHf0NN2nvxl1Gh4QO83yRCOdMK4zivtMS5gv0dEX0hg=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
|
||||
|
@ -236,6 +239,7 @@ github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD
|
|||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||
|
|
|
@ -329,7 +329,7 @@ func (c *Configuration) getLockTime() (time.Time, error) {
|
|||
acmeLog(logger.LevelError, "unable to read lock file %q: %v", c.lockPath, err)
|
||||
return time.Time{}, err
|
||||
}
|
||||
msec, err := strconv.ParseInt(strings.TrimSpace(string(content)), 10, 64)
|
||||
msec, err := strconv.ParseInt(strings.TrimSpace(util.BytesToString(content)), 10, 64)
|
||||
if err != nil {
|
||||
acmeLog(logger.LevelError, "unable to parse lock time: %v", err)
|
||||
return time.Time{}, fmt.Errorf("unable to parse lock time: %w", err)
|
||||
|
|
|
@ -196,7 +196,7 @@ Please take a look at the usage below to customize the serving parameters`,
|
|||
fmt.Printf("Unable to read password file %q: %v", portablePasswordFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
pwd = strings.TrimSpace(string(content))
|
||||
pwd = strings.TrimSpace(util.BytesToString(content))
|
||||
}
|
||||
service.SetGraceTime(graceTime)
|
||||
service := service.Service{
|
||||
|
@ -523,7 +523,7 @@ func getFileContents(name string) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(contents), nil
|
||||
return util.BytesToString(contents), nil
|
||||
}
|
||||
|
||||
func convertFsProvider() string {
|
||||
|
|
|
@ -345,7 +345,7 @@ func notificationAsEnvVars(event *notifier.FsEvent) []string {
|
|||
if len(event.Metadata) > 0 {
|
||||
data, err := json.Marshal(event.Metadata)
|
||||
if err == nil {
|
||||
result = append(result, fmt.Sprintf("SFTPGO_ACTION_METADATA=%s", string(data)))
|
||||
result = append(result, fmt.Sprintf("SFTPGO_ACTION_METADATA=%s", util.BytesToString(data)))
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -479,7 +479,7 @@ func (c *RetentionCheck) sendHookNotification(elapsed time.Duration, errCheck er
|
|||
|
||||
cmd := exec.CommandContext(ctx, Config.DataRetentionHook, args...)
|
||||
cmd.Env = append(env,
|
||||
fmt.Sprintf("SFTPGO_DATA_RETENTION_RESULT=%s", string(jsonData)))
|
||||
fmt.Sprintf("SFTPGO_DATA_RETENTION_RESULT=%s", util.BytesToString(jsonData)))
|
||||
err := cmd.Run()
|
||||
|
||||
c.conn.Log(logger.LevelDebug, "notified result using command: %q, elapsed: %s err: %v",
|
||||
|
|
|
@ -811,7 +811,7 @@ func (p *EventParams) getStringReplacements(addObjectData, jsonEscaped bool) []s
|
|||
if addObjectData {
|
||||
data, err := p.Object.RenderAsJSON(p.Event != operationDelete)
|
||||
if err == nil {
|
||||
dataString := string(data)
|
||||
dataString := util.BytesToString(data)
|
||||
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
||||
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ func (p *EventParams) getStringReplacements(addObjectData, jsonEscaped bool) []s
|
|||
if len(p.Metadata) > 0 {
|
||||
data, err := json.Marshal(p.Metadata)
|
||||
if err == nil {
|
||||
dataString := string(data)
|
||||
dataString := util.BytesToString(data)
|
||||
replacements[len(replacements)-3] = p.getStringReplacement(dataString, false)
|
||||
replacements[len(replacements)-1] = p.getStringReplacement(dataString, true)
|
||||
}
|
||||
|
@ -1466,7 +1466,8 @@ func executeHTTPRuleAction(c dataprovider.EventActionHTTPConfig, params *EventPa
|
|||
endpoint, time.Since(startTime), resp.StatusCode)
|
||||
if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusNoContent {
|
||||
if rb, err := io.ReadAll(io.LimitReader(resp.Body, 2048)); err == nil {
|
||||
eventManagerLog(logger.LevelDebug, "error notification response from endpoint %q: %s", endpoint, string(rb))
|
||||
eventManagerLog(logger.LevelDebug, "error notification response from endpoint %q: %s",
|
||||
endpoint, util.BytesToString(rb))
|
||||
}
|
||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ func executeNotificationCommand(operation, executor, ip, objectType, objectName,
|
|||
fmt.Sprintf("SFTPGO_PROVIDER_IP=%s", ip),
|
||||
fmt.Sprintf("SFTPGO_PROVIDER_ROLE=%s", role),
|
||||
fmt.Sprintf("SFTPGO_PROVIDER_TIMESTAMP=%d", util.GetTimeAsMsSinceEpoch(time.Now())),
|
||||
fmt.Sprintf("SFTPGO_PROVIDER_OBJECT=%s", string(objectAsJSON)))
|
||||
fmt.Sprintf("SFTPGO_PROVIDER_OBJECT=%s", util.BytesToString(objectAsJSON)))
|
||||
|
||||
startTime := time.Now()
|
||||
err := cmd.Run()
|
||||
|
|
|
@ -297,7 +297,7 @@ func (a *Admin) hashPassword() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Password = string(pwd)
|
||||
a.Password = util.BytesToString(pwd)
|
||||
} else {
|
||||
pwd, err := argon2id.CreateHash(a.Password, argon2Params)
|
||||
if err != nil {
|
||||
|
|
|
@ -118,7 +118,7 @@ func (k *APIKey) hashKey() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k.Key = string(hashed)
|
||||
k.Key = util.BytesToString(hashed)
|
||||
} else {
|
||||
hashed, err := argon2id.CreateHash(k.Key, argon2Params)
|
||||
if err != nil {
|
||||
|
|
|
@ -3255,7 +3255,7 @@ func hashPlainPassword(plainPwd string) (string, error) {
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("bcrypt hashing error: %w", err)
|
||||
}
|
||||
return string(pwd), nil
|
||||
return util.BytesToString(pwd), nil
|
||||
}
|
||||
pwd, err := argon2id.CreateHash(plainPwd, argon2Params)
|
||||
if err != nil {
|
||||
|
@ -4115,7 +4115,7 @@ func getPreLoginHookResponse(loginMethod, ip, protocol string, userAsJSON []byte
|
|||
|
||||
cmd := exec.CommandContext(ctx, config.PreLoginHook, args...)
|
||||
cmd.Env = append(env,
|
||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", string(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", util.BytesToString(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_PROTOCOL=%s", protocol),
|
||||
|
@ -4162,7 +4162,7 @@ func executePreLoginHook(username, loginMethod, ip, protocol string, oidcTokenFi
|
|||
recoveryCodes := u.Filters.RecoveryCodes
|
||||
err = json.Unmarshal(out, &u)
|
||||
if err != nil {
|
||||
return u, fmt.Errorf("invalid pre-login hook response %q, error: %v", string(out), err)
|
||||
return u, fmt.Errorf("invalid pre-login hook response %q, error: %v", util.BytesToString(out), err)
|
||||
}
|
||||
u.ID = userID
|
||||
u.UsedQuotaSize = userUsedQuotaSize
|
||||
|
@ -4257,7 +4257,7 @@ func ExecutePostLoginHook(user *User, loginMethod, ip, protocol string, err erro
|
|||
|
||||
cmd := exec.CommandContext(ctx, config.PostLoginHook, args...)
|
||||
cmd.Env = append(env,
|
||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", string(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_USER=%s", util.BytesToString(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_IP=%s", ip),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_METHOD=%s", loginMethod),
|
||||
fmt.Sprintf("SFTPGO_LOGIND_STATUS=%s", status),
|
||||
|
@ -4326,7 +4326,7 @@ func getExternalAuthResponse(username, password, pkey, keyboardInteractive, ip,
|
|||
cmd := exec.CommandContext(ctx, config.ExternalAuthHook, args...)
|
||||
cmd.Env = append(env,
|
||||
fmt.Sprintf("SFTPGO_AUTHD_USERNAME=%s", username),
|
||||
fmt.Sprintf("SFTPGO_AUTHD_USER=%s", string(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_AUTHD_USER=%s", util.BytesToString(userAsJSON)),
|
||||
fmt.Sprintf("SFTPGO_AUTHD_IP=%s", ip),
|
||||
fmt.Sprintf("SFTPGO_AUTHD_PASSWORD=%s", password),
|
||||
fmt.Sprintf("SFTPGO_AUTHD_PUBLIC_KEY=%s", pkey),
|
||||
|
|
|
@ -99,7 +99,7 @@ func (n *NodeData) validate() error {
|
|||
if n.Proto != NodeProtoHTTP && n.Proto != NodeProtoHTTPS {
|
||||
return util.NewValidationError(fmt.Sprintf("invalid node proto: %s", n.Proto))
|
||||
}
|
||||
n.Key = kms.NewPlainSecret(string(util.GenerateRandomBytes(32)))
|
||||
n.Key = kms.NewPlainSecret(util.BytesToString(util.GenerateRandomBytes(32)))
|
||||
n.Key.SetAdditionalData(n.Host)
|
||||
if err := n.Key.Encrypt(); err != nil {
|
||||
return fmt.Errorf("unable to encrypt node key: %w", err)
|
||||
|
@ -191,7 +191,7 @@ func (n *Node) generateAuthToken(username, role string) (string, error) {
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("unable to sign authentication token: %w", err)
|
||||
}
|
||||
return string(payload), nil
|
||||
return util.BytesToString(payload), nil
|
||||
}
|
||||
|
||||
func (n *Node) prepareRequest(ctx context.Context, username, role, relativeURL, method string,
|
||||
|
|
|
@ -155,7 +155,7 @@ func (s *Share) hashPassword() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Password = string(hashed)
|
||||
s.Password = util.BytesToString(hashed)
|
||||
} else {
|
||||
hashed, err := argon2id.CreateHash(s.Password, argon2Params)
|
||||
if err != nil {
|
||||
|
|
|
@ -63,7 +63,7 @@ func NewServer(config *Configuration, configDir string, binding Binding, id int)
|
|||
}
|
||||
bannerContent, err := os.ReadFile(bannerFilePath)
|
||||
if err == nil {
|
||||
server.initialMsg = string(bannerContent)
|
||||
server.initialMsg = util.BytesToString(bannerContent)
|
||||
} else {
|
||||
logger.WarnToConsole("unable to read FTPD banner file: %v", err)
|
||||
logger.Warn(logSender, "", "unable to read banner file: %v", err)
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"github.com/drakkan/sftpgo/v2/internal/common"
|
||||
"github.com/drakkan/sftpgo/v2/internal/dataprovider"
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
)
|
||||
|
||||
func getDefenderHosts(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -76,7 +77,7 @@ func getIPFromID(r *http.Request) (string, error) {
|
|||
if err != nil {
|
||||
return "", errors.New("invalid host id")
|
||||
}
|
||||
ip := string(decoded)
|
||||
ip := util.BytesToString(decoded)
|
||||
err = validateIPAddress(ip)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -1594,7 +1594,7 @@ func getGCSConfig(r *http.Request) (vfs.GCSFsConfig, error) {
|
|||
}
|
||||
return config, err
|
||||
}
|
||||
config.Credentials = kms.NewPlainSecret(string(fileBytes))
|
||||
config.Credentials = kms.NewPlainSecret(util.BytesToString(fileBytes))
|
||||
config.AutomaticCredentials = 0
|
||||
return config, err
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
sdkkms "github.com/sftpgo/sdk/kms"
|
||||
)
|
||||
|
||||
|
@ -132,7 +133,7 @@ func (s *builtinSecret) Decrypt() error {
|
|||
return err
|
||||
}
|
||||
s.Status = sdkkms.SecretStatusPlain
|
||||
s.Payload = string(plaintext)
|
||||
s.Payload = util.BytesToString(plaintext)
|
||||
s.Key = ""
|
||||
s.AdditionalData = ""
|
||||
return nil
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"github.com/drakkan/sftpgo/v2/internal/util"
|
||||
sdkkms "github.com/sftpgo/sdk/kms"
|
||||
"gocloud.dev/secrets/localsecrets"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
|
@ -104,7 +105,7 @@ func (s *localSecret) Decrypt() error {
|
|||
return err
|
||||
}
|
||||
s.Status = sdkkms.SecretStatusPlain
|
||||
s.Payload = string(plaintext)
|
||||
s.Payload = util.BytesToString(plaintext)
|
||||
s.Key = ""
|
||||
s.AdditionalData = ""
|
||||
s.Mode = 0
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
ftpserverlog "github.com/fclairamb/go-log"
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -283,7 +284,7 @@ func (l *StdLoggerWrapper) Write(p []byte) (n int, err error) {
|
|||
p = p[0 : n-1]
|
||||
}
|
||||
|
||||
Log(LevelError, l.Sender, "", string(p))
|
||||
Log(LevelError, l.Sender, "", bytesToString(p))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -363,3 +364,12 @@ func (l *LeveledLogger) With(keysAndValues ...any) ftpserverlog.Logger {
|
|||
additionalKeyVals: append(l.additionalKeyVals, keysAndValues...),
|
||||
}
|
||||
}
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
// unsafe.SliceData relies on cap whereas we want to rely on len
|
||||
if len(b) == 0 {
|
||||
return ""
|
||||
}
|
||||
// https://github.com/golang/go/blob/4ed358b57efdad9ed710be7f4fc51495a7620ce2/src/strings/builder.go#L41
|
||||
return unsafe.String(unsafe.SliceData(b), len(b))
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ func (c *Configuration) configureLoginBanner(serverConfig *ssh.ServerConfig, con
|
|||
}
|
||||
bannerContent, err := os.ReadFile(bannerFilePath)
|
||||
if err == nil {
|
||||
banner := string(bannerContent)
|
||||
banner := util.BytesToString(bannerContent)
|
||||
serverConfig.BannerCallback = func(_ ssh.ConnMetadata) string {
|
||||
return banner
|
||||
}
|
||||
|
@ -603,7 +603,8 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
|||
|
||||
logger.Log(logger.LevelInfo, common.ProtocolSSH, connectionID,
|
||||
"User %q logged in with %q, from ip %q, client version %q, negotiated algorithms: %+v",
|
||||
user.Username, loginType, ipAddr, string(sconn.ClientVersion()), sconn.Conn.(ssh.AlgorithmsConnMetadata).Algorithms())
|
||||
user.Username, loginType, ipAddr, util.BytesToString(sconn.ClientVersion()),
|
||||
sconn.Conn.(ssh.AlgorithmsConnMetadata).Algorithms())
|
||||
dataprovider.UpdateLastLogin(&user)
|
||||
|
||||
sshConnection := common.NewSSHConnection(connectionID, conn)
|
||||
|
@ -639,12 +640,12 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
|||
|
||||
switch req.Type {
|
||||
case "subsystem":
|
||||
if string(req.Payload[4:]) == "sftp" {
|
||||
if util.BytesToString(req.Payload[4:]) == "sftp" {
|
||||
ok = true
|
||||
connection := &Connection{
|
||||
BaseConnection: common.NewBaseConnection(connID, common.ProtocolSFTP, conn.LocalAddr().String(),
|
||||
conn.RemoteAddr().String(), user),
|
||||
ClientVersion: string(sconn.ClientVersion()),
|
||||
ClientVersion: util.BytesToString(sconn.ClientVersion()),
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
LocalAddr: conn.LocalAddr(),
|
||||
channel: channel,
|
||||
|
@ -656,7 +657,7 @@ func (c *Configuration) AcceptInboundConnection(conn net.Conn, config *ssh.Serve
|
|||
connection := Connection{
|
||||
BaseConnection: common.NewBaseConnection(connID, "sshd_exec", conn.LocalAddr().String(),
|
||||
conn.RemoteAddr().String(), user),
|
||||
ClientVersion: string(sconn.ClientVersion()),
|
||||
ClientVersion: util.BytesToString(sconn.ClientVersion()),
|
||||
RemoteAddr: conn.RemoteAddr(),
|
||||
LocalAddr: conn.LocalAddr(),
|
||||
channel: channel,
|
||||
|
@ -816,7 +817,7 @@ func loginUser(user *dataprovider.User, loginMethod, publicKey string, conn ssh.
|
|||
}
|
||||
p := &ssh.Permissions{}
|
||||
p.Extensions = make(map[string]string)
|
||||
p.Extensions["sftpgo_user"] = string(json)
|
||||
p.Extensions["sftpgo_user"] = util.BytesToString(json)
|
||||
p.Extensions["sftpgo_login_method"] = loginMethod
|
||||
return p, nil
|
||||
}
|
||||
|
@ -1180,7 +1181,7 @@ func (c *Configuration) validatePasswordCredentials(conn ssh.ConnMetadata, pass
|
|||
var sshPerm *ssh.Permissions
|
||||
|
||||
ipAddr := util.GetIPFromRemoteAddress(conn.RemoteAddr().String())
|
||||
if user, err = dataprovider.CheckUserAndPass(conn.User(), string(pass), ipAddr, common.ProtocolSSH); err == nil {
|
||||
if user, err = dataprovider.CheckUserAndPass(conn.User(), util.BytesToString(pass), ipAddr, common.ProtocolSSH); err == nil {
|
||||
sshPerm, err = loginUser(&user, method, "", conn)
|
||||
}
|
||||
user.Username = conn.User()
|
||||
|
|
|
@ -367,7 +367,7 @@ func (e *I18nError) Args() string {
|
|||
if len(e.args) > 0 {
|
||||
data, err := json.Marshal(e.args)
|
||||
if err == nil {
|
||||
return string(data)
|
||||
return BytesToString(data)
|
||||
}
|
||||
}
|
||||
return "{}"
|
||||
|
|
|
@ -44,6 +44,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unsafe"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/lithammer/shortuuid/v3"
|
||||
|
@ -288,6 +289,16 @@ func ParseBytes(s string) (int64, error) {
|
|||
return 0, fmt.Errorf("unhandled size name: %v", extra)
|
||||
}
|
||||
|
||||
// BytesToString converts []byte to string without allocations.
|
||||
func BytesToString(b []byte) string {
|
||||
// unsafe.SliceData relies on cap whereas we want to rely on len
|
||||
if len(b) == 0 {
|
||||
return ""
|
||||
}
|
||||
// https://github.com/golang/go/blob/4ed358b57efdad9ed710be7f4fc51495a7620ce2/src/strings/builder.go#L41
|
||||
return unsafe.String(unsafe.SliceData(b), len(b))
|
||||
}
|
||||
|
||||
// GetIPFromRemoteAddress returns the IP from the remote address.
|
||||
// If the given remote address cannot be parsed it will be returned unchanged
|
||||
func GetIPFromRemoteAddress(remoteAddress string) string {
|
||||
|
@ -660,7 +671,7 @@ func EncodeTLSCertToPem(tlsCert *x509.Certificate) (string, error) {
|
|||
Type: "CERTIFICATE",
|
||||
Bytes: tlsCert.Raw,
|
||||
}
|
||||
return string(pem.EncodeToMemory(&publicKeyBlock)), nil
|
||||
return BytesToString(pem.EncodeToMemory(&publicKeyBlock)), nil
|
||||
}
|
||||
|
||||
// CheckTCP4Port quits the app if bind on the given IPv4 port fails.
|
||||
|
@ -704,7 +715,7 @@ func GetSSHPublicKeyAsString(pubKey []byte) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(ssh.MarshalAuthorizedKey(k)), nil
|
||||
return BytesToString(ssh.MarshalAuthorizedKey(k)), nil
|
||||
}
|
||||
|
||||
// GetRealIP returns the ip address as result of parsing the specified
|
||||
|
@ -880,7 +891,7 @@ func JSONEscape(val string) string {
|
|||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(b[1 : len(b)-1])
|
||||
return BytesToString(b[1 : len(b)-1])
|
||||
}
|
||||
|
||||
// ReadConfigFromFile reads a configuration parameter from the specified file
|
||||
|
@ -901,5 +912,5 @@ func ReadConfigFromFile(name, configDir string) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(val)), nil
|
||||
return strings.TrimSpace(BytesToString(val)), nil
|
||||
}
|
||||
|
|
|
@ -448,10 +448,10 @@ func (f *webDavFile) Patch(patches []webdav.Proppatch) ([]webdav.Propstat, error
|
|||
for _, p := range patch.Props {
|
||||
if status == http.StatusForbidden && !hasError {
|
||||
if !patch.Remove && util.Contains(lastModifiedProps, p.XMLName.Local) {
|
||||
parsed, err := parseTime(string(p.InnerXML))
|
||||
parsed, err := parseTime(util.BytesToString(p.InnerXML))
|
||||
if err != nil {
|
||||
f.Connection.Log(logger.LevelWarn, "unsupported last modification time: %q, err: %v",
|
||||
string(p.InnerXML), err)
|
||||
util.BytesToString(p.InnerXML), err)
|
||||
hasError = true
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue