]> git.r.bdr.sh - rbdr/mobius/commitdiff
Add support for Mac Roman character encoding.
authorJeff Halter <redacted>
Thu, 4 Apr 2024 22:37:28 +0000 (15:37 -0700)
committerJeff Halter <redacted>
Thu, 4 Apr 2024 22:47:18 +0000 (15:47 -0700)
https://en.wikipedia.org/wiki/Mac_OS_Roman

hotline/file_path.go
hotline/files.go
hotline/server.go
hotline/transaction_handlers.go

index 97ce417e484550202cfb1b4da284ce57ef7c2ef7..620f54d5cd0a5b969ade3237ad57617d65fd370e 100644 (file)
@@ -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
 }
index 63fa482d498ab4c44d450b9a58bae33b2c5e89ca..0746b1f6ef51d1f5f26bdf8fad34cd386ce11ea6 100644 (file)
@@ -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)))
index e4232b6feb30ac2e36c92b40565216f84e8e218f..f4eef9bd63b646403228ed36547817e0075183c6 100644 (file)
@@ -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
index ee95cc0cfe8abac6ace7b878ab0c96f6daff6ccd..931340e5c4f94edd88b4914d479a2f4cdd349b2e 100644 (file)
@@ -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