mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-14 14:56:27 +03:00
Attempt to fix windows command parsing + add more tests
This commit is contained in:
parent
fec491fb12
commit
0d004ccbab
2 changed files with 96 additions and 9 deletions
|
@ -2,6 +2,7 @@ package middleware
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
@ -46,7 +47,7 @@ func SplitCommandAndArgs(command string) (cmd string, args []string, err error)
|
|||
//
|
||||
// Loosely based off the rules here: http://stackoverflow.com/a/4094897/1048862
|
||||
// True parsing is much, much trickier.
|
||||
func parseWindowsCommand(cmd string) []string {
|
||||
func parseWindowsCommand2(cmd string) []string {
|
||||
var parts []string
|
||||
var part string
|
||||
var quoted bool
|
||||
|
@ -97,3 +98,60 @@ func parseWindowsCommand(cmd string) []string {
|
|||
|
||||
return parts
|
||||
}
|
||||
|
||||
func parseWindowsCommand(cmd string) []string {
|
||||
var parts []string
|
||||
var part string
|
||||
var inQuotes bool
|
||||
var wasBackslash bool
|
||||
|
||||
prefix := "DEBUG:"
|
||||
|
||||
fmt.Println(prefix, "Parsing cmd:", cmd)
|
||||
|
||||
for i, ch := range cmd {
|
||||
fmt.Println(" ", prefix, "Looking at char:", string(ch), "at index", string(i))
|
||||
|
||||
if ch == '\\' {
|
||||
wasBackslash = true
|
||||
// put it in the part - for now we don't know if it's escaping char or path separator
|
||||
part += string(ch)
|
||||
continue
|
||||
}
|
||||
|
||||
if ch == '"' {
|
||||
if wasBackslash {
|
||||
// remove the backslash from the part and add the escaped quote instead
|
||||
part = part[:len(part)-1]
|
||||
part += string(ch)
|
||||
wasBackslash = false
|
||||
continue
|
||||
} else {
|
||||
// normal escaping quotes
|
||||
fmt.Println(" ", prefix, "and it's a quote")
|
||||
inQuotes = !inQuotes
|
||||
continue
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if unicode.IsSpace(ch) && !inQuotes && len(part) > 0 {
|
||||
fmt.Println(" ", prefix, "and it's a space outside quotes")
|
||||
parts = append(parts, part)
|
||||
part = ""
|
||||
wasBackslash = false
|
||||
continue
|
||||
}
|
||||
|
||||
wasBackslash = false
|
||||
part += string(ch)
|
||||
}
|
||||
|
||||
if len(part) > 0 {
|
||||
parts = append(parts, part)
|
||||
part = ""
|
||||
}
|
||||
|
||||
fmt.Println(prefix, strings.Join(parts, ","))
|
||||
return parts
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
func TestParseWindowsCommand(t *testing.T) {
|
||||
for i, test := range []struct {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected []string
|
||||
}{
|
||||
|
@ -51,25 +51,54 @@ func TestParseWindowsCommand(t *testing.T) {
|
|||
input: `mkdir "C:\ space"`,
|
||||
expected: []string{`mkdir`, `C:\ space`},
|
||||
},
|
||||
{ // 10
|
||||
input: `\\"`,
|
||||
expected: []string{`\`},
|
||||
// 10
|
||||
{
|
||||
input: `mkdir \\?\C:\Users`,
|
||||
expected: []string{`mkdir`, `\\?\C:\Users`},
|
||||
},
|
||||
{ // 11
|
||||
input: `"\\\""`,
|
||||
expected: []string{`\"`},
|
||||
// 11
|
||||
{
|
||||
input: `mkdir "\\?\C:\Program Files"`,
|
||||
expected: []string{`mkdir`, `\\?\C:\Program Files`},
|
||||
},
|
||||
} {
|
||||
}
|
||||
var nTests int
|
||||
for i, test := range tests {
|
||||
fmt.Printf("====== Test %d ======\n", i)
|
||||
actual := parseWindowsCommand(test.input)
|
||||
if len(actual) != len(test.expected) {
|
||||
fmt.Printf("Test %d: Expected %d parts, got %d: %#v", i, len(test.expected), len(actual), actual)
|
||||
fmt.Println()
|
||||
t.Errorf("Test %d: Expected %d parts, got %d: %#v", i, len(test.expected), len(actual), actual)
|
||||
continue
|
||||
}
|
||||
for j := 0; j < len(actual); j++ {
|
||||
if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
|
||||
fmt.Printf("Test %d: Expected: %v Actual: %v (index %d)", i, expectedPart, actualPart, j)
|
||||
fmt.Println()
|
||||
t.Errorf("Test %d: Expected: %v Actual: %v (index %d)", i, expectedPart, actualPart, j)
|
||||
}
|
||||
}
|
||||
nTests += 1
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
fmt.Printf("====== Test %d ======\n", nTests)
|
||||
actual := parseWindowsCommand2(test.input)
|
||||
if len(actual) != len(test.expected) {
|
||||
fmt.Printf("Test %d: Expected %d parts, got %d: %#v", nTests, len(test.expected), len(actual), actual)
|
||||
fmt.Println()
|
||||
t.Errorf("Test %d: Expected %d parts, got %d: %#v", nTests, len(test.expected), len(actual), actual)
|
||||
continue
|
||||
}
|
||||
for j := 0; j < len(actual); j++ {
|
||||
if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
|
||||
fmt.Printf("Test %d: Expected: %v Actual: %v (index %d)", nTests, expectedPart, actualPart, j)
|
||||
fmt.Println()
|
||||
t.Errorf("Test %d: Expected: %v Actual: %v (index %d)", nTests, expectedPart, actualPart, j)
|
||||
}
|
||||
}
|
||||
nTests += 1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue