mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-23 17:16:40 +01: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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"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
|
// Loosely based off the rules here: http://stackoverflow.com/a/4094897/1048862
|
||||||
// True parsing is much, much trickier.
|
// True parsing is much, much trickier.
|
||||||
func parseWindowsCommand(cmd string) []string {
|
func parseWindowsCommand2(cmd string) []string {
|
||||||
var parts []string
|
var parts []string
|
||||||
var part string
|
var part string
|
||||||
var quoted bool
|
var quoted bool
|
||||||
|
@ -97,3 +98,60 @@ func parseWindowsCommand(cmd string) []string {
|
||||||
|
|
||||||
return parts
|
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) {
|
func TestParseWindowsCommand(t *testing.T) {
|
||||||
for i, test := range []struct {
|
tests := []struct {
|
||||||
input string
|
input string
|
||||||
expected []string
|
expected []string
|
||||||
}{
|
}{
|
||||||
|
@ -51,25 +51,54 @@ func TestParseWindowsCommand(t *testing.T) {
|
||||||
input: `mkdir "C:\ space"`,
|
input: `mkdir "C:\ space"`,
|
||||||
expected: []string{`mkdir`, `C:\ space`},
|
expected: []string{`mkdir`, `C:\ space`},
|
||||||
},
|
},
|
||||||
{ // 10
|
// 10
|
||||||
input: `\\"`,
|
{
|
||||||
expected: []string{`\`},
|
input: `mkdir \\?\C:\Users`,
|
||||||
|
expected: []string{`mkdir`, `\\?\C:\Users`},
|
||||||
},
|
},
|
||||||
{ // 11
|
// 11
|
||||||
input: `"\\\""`,
|
{
|
||||||
expected: []string{`\"`},
|
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)
|
actual := parseWindowsCommand(test.input)
|
||||||
if len(actual) != len(test.expected) {
|
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)
|
t.Errorf("Test %d: Expected %d parts, got %d: %#v", i, len(test.expected), len(actual), actual)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for j := 0; j < len(actual); j++ {
|
for j := 0; j < len(actual); j++ {
|
||||||
if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
|
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)
|
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