From: Jeff Halter Date: Thu, 4 Apr 2024 22:37:28 +0000 (-0700) Subject: Add support for Mac Roman character encoding. X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/commitdiff_plain/2e1aec0fcfd412cff22cc4fc996973e403589ad8 Add support for Mac Roman character encoding. https://en.wikipedia.org/wiki/Mac_OS_Roman --- 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