fix(server): Improve structure analyzer for ssh_config

Signed-off-by: Myzel394 <github.7a2op@simplelogin.co>
This commit is contained in:
Myzel394 2025-02-17 22:40:47 +01:00 committed by Myzel394
parent 706b8137dd
commit 98f76fd839
No known key found for this signature in database
GPG Key ID: B603E877F73D4ABB
3 changed files with 40 additions and 42 deletions

View File

@ -39,9 +39,26 @@ func checkOption(
option *ast.SSHOption,
block ast.SSHBlock,
) {
if option.Key == nil {
return
}
///// General checks
checkIsUsingDoubleQuotes(ctx, option.Key.Value, option.Key.LocationRange)
checkQuotesAreClosed(ctx, option.Key.Value, option.Key.LocationRange)
if option.Separator == nil || option.Separator.Value.Value == "" {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: option.Key.LocationRange.ToLSPRange(),
Message: fmt.Sprintf("There should be a separator between an option and its value"),
Severity: &common.SeverityError,
})
} else {
checkIsUsingDoubleQuotes(ctx, option.Separator.Value, option.Separator.LocationRange)
checkQuotesAreClosed(ctx, option.Separator.Value, option.Separator.LocationRange)
}
///// Check if the key is valid
docOption, optionFound := fields.Options[option.Key.Key]
if !optionFound {
@ -58,22 +75,13 @@ func checkOption(
Option: option,
Block: block,
}
return
}
}
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: option.Key.LocationRange.ToLSPRange(),
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
Severity: &common.SeverityError,
})
}
// Check for values that are not allowed in Host blocks
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost {
if utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
// Since we don't know the option, we can't verify the value
return
} else {
// Check for values that are not allowed in Host blocks
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: option.Key.LocationRange.ToLSPRange(),
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
@ -82,7 +90,8 @@ func checkOption(
}
}
if option.OptionValue != nil && optionFound {
///// Check if the value is valid
if option.OptionValue != nil {
checkIsUsingDoubleQuotes(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
checkQuotesAreClosed(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
@ -98,17 +107,6 @@ func checkOption(
})
}
}
if option.Separator == nil || option.Separator.Value.Value == "" {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: option.Key.LocationRange.ToLSPRange(),
Message: fmt.Sprintf("There should be a separator between an option and its value"),
Severity: &common.SeverityError,
})
} else {
checkIsUsingDoubleQuotes(ctx, option.Separator.Value, option.Separator.LocationRange)
checkQuotesAreClosed(ctx, option.Separator.Value, option.Separator.LocationRange)
}
}
func checkBlock(

View File

@ -9,18 +9,6 @@ import (
protocol "github.com/tliron/glsp/protocol_3_16"
)
func analyzeQuotesAreValid(
ctx *analyzerContext,
) {
for _, info := range ctx.document.Config.GetAllOptions() {
checkIsUsingDoubleQuotes(ctx, info.Option.Key.Value, info.Option.Key.LocationRange)
checkIsUsingDoubleQuotes(ctx, info.Option.OptionValue.Value, info.Option.OptionValue.LocationRange)
checkQuotesAreClosed(ctx, info.Option.Key.Value, info.Option.Key.LocationRange)
checkQuotesAreClosed(ctx, info.Option.OptionValue.Value, info.Option.OptionValue.LocationRange)
}
}
func checkIsUsingDoubleQuotes(
ctx *analyzerContext,
value commonparser.ParsedString,

View File

@ -7,6 +7,18 @@ import (
protocol "github.com/tliron/glsp/protocol_3_16"
)
func testQuotes(
ctx *analyzerContext,
) {
for _, info := range ctx.document.Config.GetAllOptions() {
checkIsUsingDoubleQuotes(ctx, info.Option.Key.Value, info.Option.Key.LocationRange)
checkIsUsingDoubleQuotes(ctx, info.Option.OptionValue.Value, info.Option.OptionValue.LocationRange)
checkQuotesAreClosed(ctx, info.Option.Key.Value, info.Option.Key.LocationRange)
checkQuotesAreClosed(ctx, info.Option.OptionValue.Value, info.Option.OptionValue.LocationRange)
}
}
func TestSimpleInvalidQuotesExample(
t *testing.T,
) {
@ -17,7 +29,7 @@ PermitRootLogin 'yes'
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeQuotesAreValid(ctx)
testQuotes(ctx)
if !(len(ctx.diagnostics) == 1) {
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
@ -34,7 +46,7 @@ func TestSingleQuotesKeyAndOptionExample(
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeQuotesAreValid(ctx)
testQuotes(ctx)
if !(len(ctx.diagnostics) == 2) {
t.Errorf("Expected 2 ctx.diagnostics, got %v", len(ctx.diagnostics))
@ -51,7 +63,7 @@ PermitRootLogin "yes
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeQuotesAreValid(ctx)
testQuotes(ctx)
if !(len(ctx.diagnostics) == 1) {
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
@ -68,7 +80,7 @@ func TestIncompleteQuotesExample(
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeQuotesAreValid(ctx)
testQuotes(ctx)
if !(len(ctx.diagnostics) == 1) {
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))