Commit 0d004ccb authored by makpoc's avatar makpoc

Attempt to fix windows command parsing + add more tests

parent fec491fb
...@@ -2,6 +2,7 @@ package middleware ...@@ -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) ...@@ -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 { ...@@ -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 ( ...@@ -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) { ...@@ -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
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment