aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hotline/file_path.go6
-rw-r--r--hotline/files.go4
-rw-r--r--hotline/server.go7
-rw-r--r--hotline/transaction_handlers.go22
4 files changed, 31 insertions, 8 deletions
diff --git a/hotline/file_path.go b/hotline/file_path.go
index 97ce417..620f54d 100644
--- a/hotline/file_path.go
+++ b/hotline/file_path.go
@@ -5,6 +5,7 @@ import (
"bytes"
"encoding/binary"
"errors"
+ "fmt"
"io"
"path/filepath"
"strings"
@@ -119,6 +120,9 @@ func readPath(fileRoot string, filePath, fileName []byte) (fullPath string, err
subPath,
filepath.Join("/", string(fileName)),
)
-
+ fullPath, err = txtDecoder.String(fullPath)
+ if err != nil {
+ return "", fmt.Errorf("invalid filepath encoding: %w", err)
+ }
return fullPath, nil
}
diff --git a/hotline/files.go b/hotline/files.go
index 63fa482..0746b1f 100644
--- a/hotline/files.go
+++ b/hotline/files.go
@@ -118,6 +118,10 @@ func getFileNameList(path string, ignoreList []string) (fields []Field, err erro
}
strippedName := strings.ReplaceAll(file.Name(), ".incomplete", "")
+ strippedName, err = txtEncoder.String(strippedName)
+ if err != nil {
+ return nil, err
+ }
nameSize := make([]byte, 2)
binary.BigEndian.PutUint16(nameSize, uint16(len(strippedName)))
diff --git a/hotline/server.go b/hotline/server.go
index e4232b6..f4eef9b 100644
--- a/hotline/server.go
+++ b/hotline/server.go
@@ -8,6 +8,7 @@ import (
"fmt"
"github.com/go-playground/validator/v10"
"go.uber.org/zap"
+ "golang.org/x/text/encoding/charmap"
"gopkg.in/yaml.v3"
"io"
"io/fs"
@@ -29,6 +30,12 @@ type requestCtx struct {
remoteAddr string
}
+// Converts bytes from Mac Roman encoding to UTF-8
+var txtDecoder = charmap.Macintosh.NewDecoder()
+
+// Converts bytes from UTF-8 to Mac Roman encoding
+var txtEncoder = charmap.Macintosh.NewEncoder()
+
type Server struct {
NetInterface string
Port int
diff --git a/hotline/transaction_handlers.go b/hotline/transaction_handlers.go
index ee95cc0..931340e 100644
--- a/hotline/transaction_handlers.go
+++ b/hotline/transaction_handlers.go
@@ -385,8 +385,13 @@ func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
return res, err
}
+ encodedName, err := txtEncoder.String(fw.name)
+ if err != nil {
+ return res, fmt.Errorf("invalid filepath encoding: %w", err)
+ }
+
res = append(res, cc.NewReply(t,
- NewField(FieldFileName, []byte(fw.name)),
+ NewField(FieldFileName, []byte(encodedName)),
NewField(FieldFileTypeString, fw.ffo.FlatFileInformationFork.friendlyType()),
NewField(FieldFileCreatorString, fw.ffo.FlatFileInformationFork.friendlyCreator()),
NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment),
@@ -478,7 +483,11 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
if err != nil {
return nil, err
}
- hlFile.name = string(fileNewName)
+ hlFile.name, err = txtDecoder.String(string(fileNewName))
+ if err != nil {
+ return res, fmt.Errorf("invalid filepath encoding: %w", err)
+ }
+
err = hlFile.move(fileDir)
if os.IsNotExist(err) {
res = append(res, cc.NewErrReply(t, "Cannot rename file "+string(fileName)+" because it does not exist or cannot be found."))
@@ -566,9 +575,6 @@ func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err erro
res = append(res, cc.NewErrReply(t, "Cannot delete file "+fileName+" because it does not exist or cannot be found."))
return res, err
}
- if err != nil {
- return res, err
- }
switch mode := fi.Mode(); {
case mode.IsDir():
if !cc.Authorize(accessMoveFolder) {
@@ -614,6 +620,10 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
}
}
newFolderPath := path.Join(cc.Server.Config.FileRoot, subPath, folderName)
+ newFolderPath, err = txtDecoder.String(newFolderPath)
+ if err != nil {
+ return res, fmt.Errorf("invalid filepath encoding: %w", err)
+ }
// TODO: check path and folder name lengths
@@ -622,8 +632,6 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
return []Transaction{cc.NewErrReply(t, msg)}, nil
}
- // TODO: check for disallowed characters to maintain compatibility for original client
-
if err := cc.Server.FS.Mkdir(newFolderPath, 0777); err != nil {
msg := fmt.Sprintf("Cannot create folder \"%s\" because an error occurred.", folderName)
return []Transaction{cc.NewErrReply(t, msg)}, nil