fix(sshd_config): Improve analyzer for match blocks

This commit is contained in:
Myzel394 2024-09-13 22:26:22 +02:00
parent f25c11b966
commit 0abcb043ad
No known key found for this signature in database
GPG Key ID: DEC4AAB876F73185
3 changed files with 100 additions and 35 deletions

View File

@ -18,42 +18,100 @@ func analyzeOptionsAreValid(
it := d.Config.Options.Iterator()
for it.Next() {
line := it.Key().(uint32)
entry := it.Value().(ast.SSHEntry)
option := entry.GetOption()
if option.Key != nil {
docOption, found := fields.Options[option.Key.Value]
if !found {
errs = append(errs, common.LSPError{
Range: option.Key.LocationRange,
Err: errors.New(fmt.Sprintf("Unknown option: %s", option.Key.Value)),
})
continue
}
if option.OptionValue == nil {
continue
}
invalidValues := docOption.CheckIsValid(option.OptionValue.Value)
errs = append(
errs,
utils.Map(
invalidValues,
func(invalidValue *docvalues.InvalidValue) common.LSPError {
err := docvalues.LSPErrorFromInvalidValue(line, *invalidValue)
err.ShiftCharacter(option.OptionValue.Start.Character)
return err
},
)...,
)
switch entry.(type) {
case *ast.SSHOption:
errs = append(errs, checkOption(entry.(*ast.SSHOption), false)...)
case *ast.SSHMatchBlock:
matchBlock := entry.(*ast.SSHMatchBlock)
errs = append(errs, checkMatchBlock(matchBlock)...)
}
}
return errs
}
func checkOption(
option *ast.SSHOption,
isInMatchBlock bool,
) []common.LSPError {
errs := make([]common.LSPError, 0)
if option.Key != nil {
docOption, found := fields.Options[option.Key.Value]
if !found {
errs = append(errs, common.LSPError{
Range: option.Key.LocationRange,
Err: errors.New(fmt.Sprintf("Unknown option: %s", option.Key.Value)),
})
return errs
}
if _, found := fields.MatchAllowedOptions[option.Key.Value]; !found && isInMatchBlock {
errs = append(errs, common.LSPError{
Range: option.Key.LocationRange,
Err: errors.New(fmt.Sprintf("Option '%s' is not allowed inside Match blocks", option.Key.Value)),
})
return errs
}
if option.OptionValue == nil {
return errs
}
invalidValues := docOption.CheckIsValid(option.OptionValue.Value)
errs = append(
errs,
utils.Map(
invalidValues,
func(invalidValue *docvalues.InvalidValue) common.LSPError {
err := docvalues.LSPErrorFromInvalidValue(option.Start.Line, *invalidValue)
err.ShiftCharacter(option.OptionValue.Start.Character)
return err
},
)...,
)
}
return errs
}
func checkMatchBlock(
matchBlock *ast.SSHMatchBlock,
) []common.LSPError {
errs := make([]common.LSPError, 0)
matchOption := matchBlock.MatchEntry.OptionValue
if matchOption != nil {
invalidValues := fields.Options["Match"].CheckIsValid(matchOption.Value)
errs = append(
errs,
utils.Map(
invalidValues,
func(invalidValue *docvalues.InvalidValue) common.LSPError {
err := docvalues.LSPErrorFromInvalidValue(matchBlock.Start.Line, *invalidValue)
err.ShiftCharacter(matchOption.Start.Character)
return err
},
)...,
)
}
it := matchBlock.Options.Iterator()
for it.Next() {
option := it.Value().(*ast.SSHOption)
errs = append(errs, checkOption(option, true)...)
}
return errs

View File

@ -574,8 +574,8 @@ Only a subset of keywords may be used on the lines following a Match keyword. Av
SubValue: docvalues.KeyEnumAssignmentValue{
Separator: " ",
Values: map[docvalues.EnumString]docvalues.Value{
docvalues.CreateEnumString("User"): docvalues.UserValue("", true),
docvalues.CreateEnumString("Group"): docvalues.GroupValue("", true),
docvalues.CreateEnumString("User"): docvalues.StringValue{},
docvalues.CreateEnumString("Group"): docvalues.StringValue{},
docvalues.CreateEnumString("Host"): docvalues.StringValue{},
docvalues.CreateEnumString("LocalAddress"): docvalues.StringValue{},
docvalues.CreateEnumString("LocalPort"): docvalues.NumberValue{Min: &ZERO, Max: &MAX_PORT},

View File

@ -9,5 +9,12 @@ func TextDocumentHover(
context *glsp.Context,
params *protocol.HoverParams,
) (*protocol.Hover, error) {
// line := params.Position.Line
// cursor := params.Position.Character
//
// d := sshdconfig.DocumentParserMap[params.TextDocument.URI]
//
// entry, matchBlock := d.Config.FindOption(line)
return nil, nil
}