Fix whitespace handling before, after or inside a filename

This commit is contained in:
Ludovic Fauvet 2017-01-13 12:37:05 +01:00
parent 95f4fe9d35
commit 99ba1079f9
2 changed files with 33 additions and 18 deletions

49
ftp.go
View File

@ -4,13 +4,13 @@ package ftp
import ( import (
"bufio" "bufio"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"net/textproto" "net/textproto"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unicode"
) )
// EntryType describes the different types of an Entry. // EntryType describes the different types of an Entry.
@ -337,26 +337,42 @@ func parseRFC3659ListLine(line string) (*Entry, error) {
return e, nil return e, nil
} }
// parse file or folder name with multiple spaces // parse file or folder name with starting or containing multiple whitespaces
func parseLsListLineName(line string, fields []string, offset int) string { func fieldsLsList(s string) []string {
if offset < 1 { n := 8
return "" fields := make([]string, 0, n)
fieldStart := -1
nextbreak := false
for i, c := range s {
if unicode.IsSpace(c) {
if fieldStart >= 0 {
fields = append(fields, s[fieldStart:i])
fieldStart = -1
} }
if nextbreak {
match := fmt.Sprintf(" %s ", fields[offset-1]) fields = append(fields, s[i+1:])
index := strings.Index(line, match) break
if index == -1 {
return ""
} }
} else {
index += len(match) if fieldStart == -1 {
return strings.TrimSpace(line[index:]) fieldStart = i
if len(fields) == n-1 {
nextbreak = true
}
}
}
}
if fieldStart != -1 {
fields = append(fields, s[fieldStart:])
}
return fields
} }
// parseLsListLine parses a directory line in a format based on the output of // parseLsListLine parses a directory line in a format based on the output of
// the UNIX ls command. // the UNIX ls command.
func parseLsListLine(line string) (*Entry, error) { func parseLsListLine(line string) (*Entry, error) {
fields := strings.Fields(line) fields := fieldsLsList(line)
if len(fields) >= 7 && fields[1] == "folder" && fields[2] == "0" { if len(fields) >= 7 && fields[1] == "folder" && fields[2] == "0" {
e := &Entry{ e := &Entry{
Type: EntryTypeFolder, Type: EntryTypeFolder,
@ -412,10 +428,7 @@ func parseLsListLine(line string) (*Entry, error) {
return nil, err return nil, err
} }
e.Name = parseLsListLineName(line, fields, 8) e.Name = fields[8]
if len(e.Name) == 0 {
e.Name = strings.Join(fields[8:], " ")
}
return e, nil return e, nil
} }

View File

@ -25,6 +25,8 @@ var listTests = []line{
{"drwxr-xr-x 3 110 1002 3 Dec 02 2009 pub", "pub", 0, EntryTypeFolder, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)}, {"drwxr-xr-x 3 110 1002 3 Dec 02 2009 pub", "pub", 0, EntryTypeFolder, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)},
{"drwxr-xr-x 3 110 1002 3 Dec 02 2009 p u b", "p u b", 0, EntryTypeFolder, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)}, {"drwxr-xr-x 3 110 1002 3 Dec 02 2009 p u b", "p u b", 0, EntryTypeFolder, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)},
{"-rw-r--r-- 1 marketwired marketwired 12016 Mar 16 2016 2016031611G087802-001.newsml", "2016031611G087802-001.newsml", 12016, EntryTypeFile, time.Date(2016, time.March, 16, 0, 0, 0, 0, time.UTC)}, {"-rw-r--r-- 1 marketwired marketwired 12016 Mar 16 2016 2016031611G087802-001.newsml", "2016031611G087802-001.newsml", 12016, EntryTypeFile, time.Date(2016, time.March, 16, 0, 0, 0, 0, time.UTC)},
{"-rw-r--r-- 1 marketwired marketwired 2016 Mar 16 2016 2016031611G087802-001.newsml", "2016031611G087802-001.newsml", 2016, EntryTypeFile, time.Date(2016, time.March, 16, 0, 0, 0, 0, time.UTC)},
{"-rw-r--r-- 1 marketwired marketwired 12016 Mar 16 2016 2016031611G087802-001.newsml ", " 2016031611G087802-001.newsml ", 12016, EntryTypeFile, time.Date(2016, time.March, 16, 0, 0, 0, 0, time.UTC)},
{"-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 fileName", "fileName", 1234567, EntryTypeFile, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)}, {"-rwxr-xr-x 3 110 1002 1234567 Dec 02 2009 fileName", "fileName", 1234567, EntryTypeFile, time.Date(2009, time.December, 2, 0, 0, 0, 0, time.UTC)},
{"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin -> usr/bin", 0, EntryTypeLink, time.Date(thisYear, time.January, 25, 0, 17, 0, 0, time.UTC)}, {"lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin", "bin -> usr/bin", 0, EntryTypeLink, time.Date(thisYear, time.January, 25, 0, 17, 0, 0, time.UTC)},