Fix whitespace handling before, after or inside a filename
This commit is contained in:
parent
95f4fe9d35
commit
99ba1079f9
49
ftp.go
49
ftp.go
@ -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 {
|
||||||
|
fields = append(fields, s[i+1:])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if fieldStart == -1 {
|
||||||
|
fieldStart = i
|
||||||
|
if len(fields) == n-1 {
|
||||||
|
nextbreak = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if fieldStart != -1 {
|
||||||
match := fmt.Sprintf(" %s ", fields[offset-1])
|
fields = append(fields, s[fieldStart:])
|
||||||
index := strings.Index(line, match)
|
|
||||||
if index == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
return fields
|
||||||
index += len(match)
|
|
||||||
return strings.TrimSpace(line[index:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
@ -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)},
|
||||||
|
Loading…
Reference in New Issue
Block a user