Skip to content

Commit

Permalink
Windows root parse fix pt 2
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Dominic Della Valle <ddvpublic@gmail.com>
  • Loading branch information
djdv committed Nov 12, 2016
1 parent f2b271c commit d431c12
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions commands/cli/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
files "github.com/ipfs/go-ipfs/commands/files"
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
u "gx/ipfs/Qmb912gdngC1UWwTkhuW8knyRbcWeu5kqkxBpveLmW8bSr/go-ipfs-util"

)

var log = logging.Logger("commands/cli")
Expand Down Expand Up @@ -399,8 +400,18 @@ func getArgDef(i int, argDefs []cmds.Argument) *cmds.Argument {

const notRecursiveFmtStr = "'%s' is a directory, use the '-%s' flag to specify directories"
const dirNotSupportedFmtStr = "Invalid path '%s', argument '%s' does not support directories"
const winDriveLetterFmtStr = "%q is a drive letter not a drive path, append a \\ to your input"

func appendFile(fpath string, argDef *cmds.Argument, recursive, hidden bool) (files.File, error) {
// resolve Windows relative dot paths like X:.\somepath
if len(fpath) >= 3 && fpath[0] != '/' && fpath[1:3] == ":." {
var err error
fpath, err = filepath.Abs(fpath)
if err != nil {
return nil, err
}
}

if fpath == "." {
cwd, err := os.Getwd()
if err != nil {
Expand Down Expand Up @@ -429,10 +440,29 @@ func appendFile(fpath string, argDef *cmds.Argument, recursive, hidden bool) (fi
}
}

// special case for Windows drive roots i.e. X:\
// drive path must be preserved and not converted to X: or /
if len(fpath) == 3 && fpath[0] != '/' && fpath[1:3] == `:\` {
return files.NewSerialFile(fpath, fpath, hidden, stat)
// special cases for Windows drive roots i.e. X:\ and their long form \\?\X:\
// drive path must be preserved and not converted to `X:`, `X:.`, or `/`
switch len(fpath) {
case 3:
// X: will be cleaned to `X:.` which is not what is intended, a case for handling dot relative paths is above
if fpath[0] != '/' && fpath[1:3] == ":." {
return nil, fmt.Errorf(winDriveLetterFmtStr, fpath[:2])
}
// X:\ needs to preserve the `\`, path.Base would remove it
if fpath[0] != '/' && fpath[1:3] == ":\\" {
return files.NewSerialFile(fpath, fpath, hidden, stat)
}
case 6:
// \\?\X: long prefix form of X:
if fpath[:4] == "\\\\?\\" && fpath[5] == ':' {
return nil, fmt.Errorf(winDriveLetterFmtStr, fpath)
}
case 7:
// \\?\X:\ long prefix form of X:\
if fpath[:4] == "\\\\?\\" && fpath[5] == ':' && fpath[6] == '\\' {
fpath = string(fpath[4]) + ":\\"
return files.NewSerialFile(fpath, fpath, hidden, stat)
}
}

return files.NewSerialFile(path.Base(filepath.ToSlash(fpath)), fpath, hidden, stat)
Expand Down

0 comments on commit d431c12

Please sign in to comment.