Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Łukasz Nowak
caddy
Commits
94ff7dc6
Commit
94ff7dc6
authored
Oct 27, 2015
by
Matt Holt
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #287 from Makpoc/parsewincmd
Fix windows command parsing
parents
cc229aef
d1b667fb
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
307 additions
and
61 deletions
+307
-61
middleware/commands.go
middleware/commands.go
+98
-5
middleware/commands_test.go
middleware/commands_test.go
+209
-56
No files found.
middleware/commands.go
View file @
94ff7dc6
...
...
@@ -2,18 +2,30 @@ package middleware
import
(
"errors"
"runtime"
"unicode"
"github.com/flynn/go-shlex"
)
var
runtimeGoos
=
runtime
.
GOOS
// SplitCommandAndArgs takes a command string and parses it
// shell-style into the command and its separate arguments.
func
SplitCommandAndArgs
(
command
string
)
(
cmd
string
,
args
[]
string
,
err
error
)
{
parts
,
err
:=
shlex
.
Split
(
command
)
if
err
!=
nil
{
err
=
errors
.
New
(
"error parsing command: "
+
err
.
Error
())
return
}
else
if
len
(
parts
)
==
0
{
var
parts
[]
string
if
runtimeGoos
==
"windows"
{
parts
=
parseWindowsCommand
(
command
)
// parse it Windows-style
}
else
{
parts
,
err
=
parseUnixCommand
(
command
)
// parse it Unix-style
if
err
!=
nil
{
err
=
errors
.
New
(
"error parsing command: "
+
err
.
Error
())
return
}
}
if
len
(
parts
)
==
0
{
err
=
errors
.
New
(
"no command contained in '"
+
command
+
"'"
)
return
}
...
...
@@ -25,3 +37,84 @@ func SplitCommandAndArgs(command string) (cmd string, args []string, err error)
return
}
// parseUnixCommand parses a unix style command line and returns the
// command and its arguments or an error
func
parseUnixCommand
(
cmd
string
)
([]
string
,
error
)
{
return
shlex
.
Split
(
cmd
)
}
// parseWindowsCommand parses windows command lines and
// returns the command and the arguments as an array. It
// should be able to parse commonly used command lines.
// Only basic syntax is supported:
// - spaces in double quotes are not token delimiters
// - double quotes are escaped by either backspace or another double quote
// - except for the above case backspaces are path separators (not special)
//
// Many sources point out that escaping quotes using backslash can be unsafe.
// Use two double quotes when possible. (Source: http://stackoverflow.com/a/31413730/2616179 )
//
// This function has to be used on Windows instead
// of the shlex package because this function treats backslash
// characters properly.
func
parseWindowsCommand
(
cmd
string
)
[]
string
{
const
backslash
=
'\\'
const
quote
=
'"'
var
parts
[]
string
var
part
string
var
inQuotes
bool
var
lastRune
rune
for
i
,
ch
:=
range
cmd
{
if
i
!=
0
{
lastRune
=
rune
(
cmd
[
i
-
1
])
}
if
ch
==
backslash
{
// put it in the part - for now we don't know if it's an
// escaping char or path separator
part
+=
string
(
ch
)
continue
}
if
ch
==
quote
{
if
lastRune
==
backslash
{
// remove the backslash from the part and add the escaped quote instead
part
=
part
[
:
len
(
part
)
-
1
]
part
+=
string
(
ch
)
continue
}
if
lastRune
==
quote
{
// revert the last change of the inQuotes state
// it was an escaping quote
inQuotes
=
!
inQuotes
part
+=
string
(
ch
)
continue
}
// normal escaping quotes
inQuotes
=
!
inQuotes
continue
}
if
unicode
.
IsSpace
(
ch
)
&&
!
inQuotes
&&
len
(
part
)
>
0
{
parts
=
append
(
parts
,
part
)
part
=
""
continue
}
part
+=
string
(
ch
)
}
if
len
(
part
)
>
0
{
parts
=
append
(
parts
,
part
)
part
=
""
}
return
parts
}
middleware/commands_test.go
View file @
94ff7dc6
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment