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