cli: Fix crash with invalid JSON diagnostics
If a JSON diagnostic value has a highlight end offset which is before the highlight start offset, this would previously panic. This commit adds a normalization step to prevent the crash.
This commit is contained in:
parent
3a9b369b43
commit
25f99857cf
|
@ -240,6 +240,16 @@ func appendSourceSnippets(buf *bytes.Buffer, diag *viewsjson.Diagnostic, color *
|
||||||
// Split the snippet and render the highlighted section with underlines
|
// Split the snippet and render the highlighted section with underlines
|
||||||
start := snippet.HighlightStartOffset
|
start := snippet.HighlightStartOffset
|
||||||
end := snippet.HighlightEndOffset
|
end := snippet.HighlightEndOffset
|
||||||
|
|
||||||
|
// Only buggy diagnostics can have an end range before the start, but
|
||||||
|
// we need to ensure we don't crash here if that happens.
|
||||||
|
if end < start {
|
||||||
|
end = start + 1
|
||||||
|
if end > len(code) {
|
||||||
|
end = len(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
before, highlight, after := code[0:start], code[start:end], code[end:]
|
before, highlight, after := code[0:start], code[start:end], code[end:]
|
||||||
code = fmt.Sprintf(color.Color("%s[underline]%s[reset]%s"), before, highlight, after)
|
code = fmt.Sprintf(color.Color("%s[underline]%s[reset]%s"), before, highlight, after)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
"github.com/mitchellh/colorstring"
|
"github.com/mitchellh/colorstring"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
|
viewsjson "github.com/hashicorp/terraform/command/views/json"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -699,3 +701,56 @@ eventually make it onto multiple lines. THE END
|
||||||
t.Fatalf("unexpected output: got:\n%s\nwant\n%s\n", output, expected)
|
t.Fatalf("unexpected output: got:\n%s\nwant\n%s\n", output, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test cases covering invalid JSON diagnostics which should still render
|
||||||
|
// correctly. These JSON diagnostic values cannot be generated from the
|
||||||
|
// json.NewDiagnostic code path, but we may read and display JSON diagnostics
|
||||||
|
// in future from other sources.
|
||||||
|
func TestDiagnosticFromJSON_invalid(t *testing.T) {
|
||||||
|
tests := map[string]struct {
|
||||||
|
Diag *viewsjson.Diagnostic
|
||||||
|
Want string
|
||||||
|
}{
|
||||||
|
"zero-value end range and highlight end byte": {
|
||||||
|
&viewsjson.Diagnostic{
|
||||||
|
Severity: viewsjson.DiagnosticSeverityError,
|
||||||
|
Summary: "Bad end",
|
||||||
|
Detail: "It all went wrong.",
|
||||||
|
Range: &viewsjson.DiagnosticRange{
|
||||||
|
Filename: "ohno.tf",
|
||||||
|
Start: viewsjson.Pos{Line: 1, Column: 23, Byte: 22},
|
||||||
|
End: viewsjson.Pos{Line: 0, Column: 0, Byte: 0},
|
||||||
|
},
|
||||||
|
Snippet: &viewsjson.DiagnosticSnippet{
|
||||||
|
Code: `resource "foo_bar "baz" {`,
|
||||||
|
StartLine: 1,
|
||||||
|
HighlightStartOffset: 22,
|
||||||
|
HighlightEndOffset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`[red]╷[reset]
|
||||||
|
[red]│[reset] [bold][red]Error: [reset][bold]Bad end[reset]
|
||||||
|
[red]│[reset]
|
||||||
|
[red]│[reset] on ohno.tf line 1:
|
||||||
|
[red]│[reset] 1: resource "foo_bar "baz[underline]"[reset] {
|
||||||
|
[red]│[reset]
|
||||||
|
[red]│[reset] It all went wrong.
|
||||||
|
[red]╵[reset]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// This empty Colorize just passes through all of the formatting codes
|
||||||
|
// untouched, because it doesn't define any formatting keywords.
|
||||||
|
colorize := &colorstring.Colorize{}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
got := strings.TrimSpace(DiagnosticFromJSON(test.Diag, colorize, 40))
|
||||||
|
want := strings.TrimSpace(test.Want)
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("wrong result\ngot:\n%s\n\nwant:\n%s\n\n", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue