Skip to content

Commit

Permalink
hyperv: Replace SplitLines with FirstLine
Browse files Browse the repository at this point in the history
In the hyperv code, there are many occurrences of
resp := os.SplitLines(stdout)
if resp[0] == ...

This does not check if `resp` is empty before trying to reference it,
which recently triggered a panic in crc (
#3764 )

This code adds a `FirstLine` helper which will return an empty string
if stdout is "".

This should fix #3764
  • Loading branch information
cfergeau authored and anjannath committed Jul 26, 2023
1 parent 2fa56f0 commit 6b61c2f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 13 deletions.
14 changes: 7 additions & 7 deletions pkg/drivers/hyperv/hyperv_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,18 @@ func (d *Driver) GetState() (state.State, error) {
return state.Error, fmt.Errorf("Failed to find the VM status: %v - %s", err, stderr)
}

resp := crcstrings.SplitLines(stdout)
if len(resp) < 1 {
resp := crcstrings.FirstLine(stdout)
if resp == "" {
return state.Error, fmt.Errorf("unexpected Hyper-V state %s", stdout)
}

switch resp[0] {
switch resp {
case "Starting", "Running", "Stopping":
return state.Running, nil
case "Off":
return state.Stopped, nil
default:
return state.Error, fmt.Errorf("unexpected Hyper-V state %s", resp[0])
return state.Error, fmt.Errorf("unexpected Hyper-V state %s", resp)
}
}

Expand Down Expand Up @@ -398,12 +398,12 @@ func (d *Driver) GetIP() (string, error) {
return "", err
}

resp := crcstrings.SplitLines(stdout)
if len(resp) < 1 {
resp := crcstrings.FirstLine(stdout)
if resp == "" {
return "", fmt.Errorf("IP not found")
}

return resp[0], nil
return resp, nil
}

func (d *Driver) GetSharedDirs() ([]drivers.SharedDir, error) {
Expand Down
12 changes: 6 additions & 6 deletions pkg/drivers/hyperv/powershell_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func hypervAvailable() error {
return err
}

resp := crcstrings.SplitLines(stdout)
if resp[0] != "Hyper-V" {
resp := crcstrings.FirstLine(stdout)
if resp != "Hyper-V" {
return ErrNotInstalled
}

Expand Down Expand Up @@ -62,8 +62,8 @@ func isHypervAdministrator() bool {
return false
}

resp := crcstrings.SplitLines(stdout)
return resp[0] == "True"
resp := crcstrings.FirstLine(stdout)
return resp == "True"
}

func isWindowsAdministrator() (bool, error) {
Expand All @@ -72,8 +72,8 @@ func isWindowsAdministrator() (bool, error) {
return false, err
}

resp := crcstrings.SplitLines(stdout)
return resp[0] == "True", nil
resp := crcstrings.FirstLine(stdout)
return resp == "True", nil
}

func quote(text string) string {
Expand Down
9 changes: 9 additions & 0 deletions pkg/strings/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ func SplitLines(input string) []string {

return output
}

func FirstLine(input string) string {
lines := SplitLines(input)
if len(lines) == 0 {
return ""
}

return lines[0]
}
43 changes: 43 additions & 0 deletions pkg/strings/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,46 @@ func TestSplitLines(t *testing.T) {
}
})
}

type firstLineTest struct {
input string
firstLine string
}

var firstLineTests = map[string]firstLineTest{
"ThreeLines": {
input: "line1\nline2\nline3\n",
firstLine: "line1",
},
"ThreeLinesNoFinalEOL": {
input: "line1\nline2\nline3",
firstLine: "line1",
},
"WindowsEOL": {
input: "line1\r\nline2\r\nline3\r\n",
firstLine: "line1",
},
"EmptyString": {
input: "",
firstLine: "",
},
"EOLOnly": {
input: "\n",
firstLine: "",
},
"NoEOL": {
input: "line1",
firstLine: "line1",
},
}

func TestFirstLine(t *testing.T) {
t.Run("FirstLine", func(t *testing.T) {
for name, test := range firstLineTests {
t.Run(name, func(t *testing.T) {
firstLine := FirstLine(test.input)
assert.Equal(t, test.firstLine, firstLine)
})
}
})
}

0 comments on commit 6b61c2f

Please sign in to comment.