From ba66bb2e818bd33c3c5e93a2b5d58eb9fb728b50 Mon Sep 17 00:00:00 2001 From: Thomas Hallgren Date: Sun, 21 Aug 2022 14:23:01 +0200 Subject: [PATCH] fix(MLST): Prefix MLST entries with a space (#353) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prefix MLST entries with a space * Fix lint issue in handleMLST * Rename ẁriteMLSxOutput to writeMLSxEntry Signed-off-by: Thomas Hallgren --- handle_dirs.go | 4 ++-- handle_files.go | 11 +++++++---- handle_files_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/handle_dirs.go b/handle_dirs.go index 96cb592d..e2c9cbb0 100644 --- a/handle_dirs.go +++ b/handle_dirs.go @@ -285,14 +285,14 @@ func (c *clientHandler) dirTransferMLSD(w io.Writer, files []os.FileInfo) error } for _, file := range files { - if err := c.writeMLSxOutput(w, file); err != nil { + if err := c.writeMLSxEntry(w, file); err != nil { return err } } return nil } -func (c *clientHandler) writeMLSxOutput(w io.Writer, file os.FileInfo) error { +func (c *clientHandler) writeMLSxEntry(w io.Writer, file os.FileInfo) error { var listType string if file.IsDir() { listType = "dir" diff --git a/handle_files.go b/handle_files.go index d6d640ef..581ff315 100644 --- a/handle_files.go +++ b/handle_files.go @@ -466,17 +466,20 @@ func (c *clientHandler) handleMLST(param string) error { path := c.absPath(param) - if info, err := c.driver.Stat(path); err == nil { + info, err := c.driver.Stat(path) + if err == nil { defer c.multilineAnswer(StatusFileOK, "File details")() - if errWrite := c.writeMLSxOutput(c.writer, info); errWrite != nil { - return errWrite + // Each MLSx entry must start with a space when returned in a multiline answer + if err = c.writer.WriteByte(' '); err == nil { + err = c.writeMLSxEntry(c.writer, info) } } else { c.writeMessage(StatusActionNotTaken, fmt.Sprintf("Could not list: %v", err)) + err = nil } - return nil + return err } func (c *clientHandler) handleALLO(param string) error { diff --git a/handle_files_test.go b/handle_files_test.go index 60736e24..e6a10902 100644 --- a/handle_files_test.go +++ b/handle_files_test.go @@ -362,6 +362,40 @@ func TestSTATFile(t *testing.T) { require.Equal(t, StatusFileActionNotTaken, rc) } +func TestMLST(t *testing.T) { + s := NewTestServer(t, true) + conf := goftp.Config{ + User: authUser, + Password: authPass, + } + c, err := goftp.DialConfig(conf, s.Addr()) + require.NoError(t, err, "Couldn't connect") + + defer func() { panicOnError(c.Close()) }() + + // Creating a tiny file + ftpUpload(t, c, createTemporaryFile(t, 10), "file") + + raw, err := c.OpenRawConn() + require.NoError(t, err, "Couldn't open raw connection") + + defer func() { require.NoError(t, raw.Close()) }() + + rc, rsp, err := raw.SendCommand("MLST file") + require.NoError(t, err) + require.Equal(t, StatusFileOK, rc) + + lines := strings.Split(rsp, "\n") + require.Len(t, lines, 3) + path := validMLSxEntryPattern.FindStringSubmatch(lines[1] + "\r\n") + + if len(path) != 2 { + t.Errorf("Valid MLST response example did not pass validation: \"%s\"", lines[1]) + } else if path[1] != "file" { + t.Errorf("Validation returned incorrect pathentry: got \"%s\", want \"%s\"", path, "file") + } +} + func TestMDTM(t *testing.T) { s := NewTestServer(t, true) conf := goftp.Config{