service/dap: validate the client configurations in initialize request (#2435)
The client can specify certain configurations in the initialize request. For example, pathFormat determines the pathFormat. We do not currently support configuring pathFormat, linesStartAt1, or columnsStartAt1, so we report an error if the client attempts to set these to an unsupported value.
This commit is contained in:
parent
c5d58f494a
commit
49555a9e8a
@ -346,6 +346,13 @@ func (c *Client) InitializeRequest() {
|
||||
c.send(request)
|
||||
}
|
||||
|
||||
// InitializeRequestWithArgs sends an 'initialize' request with specified arguments.
|
||||
func (c *Client) InitializeRequestWithArgs(args dap.InitializeRequestArguments) {
|
||||
request := &dap.InitializeRequest{Request: *c.newRequest("initialize")}
|
||||
request.Arguments = args
|
||||
c.send(request)
|
||||
}
|
||||
|
||||
// LaunchRequest sends a 'launch' request with the specified args.
|
||||
func (c *Client) LaunchRequest(mode, program string, stopOnEntry bool) {
|
||||
request := &dap.LaunchRequest{Request: *c.newRequest("launch")}
|
||||
|
@ -12,6 +12,7 @@ const (
|
||||
// values below are inspired the original vscode-go debug adaptor.
|
||||
FailedToLaunch = 3000
|
||||
FailedToAttach = 3001
|
||||
FailedToInitialize = 3002
|
||||
UnableToSetBreakpoints = 2002
|
||||
UnableToDisplayThreads = 2003
|
||||
UnableToProduceStackTrace = 2004
|
||||
|
@ -608,6 +608,22 @@ func (s *Server) logToConsole(msg string) {
|
||||
}
|
||||
|
||||
func (s *Server) onInitializeRequest(request *dap.InitializeRequest) {
|
||||
if request.Arguments.PathFormat != "path" {
|
||||
s.sendErrorResponse(request.Request, FailedToInitialize, "Failed to initialize",
|
||||
fmt.Sprintf("Unsupported 'pathFormat' value '%s'.", request.Arguments.PathFormat))
|
||||
return
|
||||
}
|
||||
if !request.Arguments.LinesStartAt1 {
|
||||
s.sendErrorResponse(request.Request, FailedToInitialize, "Failed to initialize",
|
||||
"Only 1-based line numbers are supported.")
|
||||
return
|
||||
}
|
||||
if !request.Arguments.ColumnsStartAt1 {
|
||||
s.sendErrorResponse(request.Request, FailedToInitialize, "Failed to initialize",
|
||||
"Only 1-based column numbers are supported.")
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(polina): Respond with an error if debug session is in progress?
|
||||
response := &dap.InitializeResponse{Response: *newResponse(request.Request)}
|
||||
response.Body.SupportsConfigurationDoneRequest = true
|
||||
|
@ -50,6 +50,16 @@ func runTest(t *testing.T, name string, test func(c *daptest.Client, f protest.F
|
||||
var buildFlags protest.BuildFlags = protest.AllNonOptimized
|
||||
fixture := protest.BuildFixture(name, buildFlags)
|
||||
|
||||
// Start the DAP server.
|
||||
client := startDapServer(t)
|
||||
// client.Close will close the client connectinon, which will cause a connection error
|
||||
// on the server side and signal disconnect to unblock Stop() above.
|
||||
defer client.Close()
|
||||
|
||||
test(client, fixture)
|
||||
}
|
||||
|
||||
func startDapServer(t *testing.T) *daptest.Client {
|
||||
// Start the DAP server.
|
||||
listener, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
@ -76,11 +86,7 @@ func runTest(t *testing.T, name string, test func(c *daptest.Client, f protest.F
|
||||
}()
|
||||
|
||||
client := daptest.NewClient(listener.Addr().String())
|
||||
// This will close the client connectinon, which will cause a connection error
|
||||
// on the server side and signal disconnect to unblock Stop() above.
|
||||
defer client.Close()
|
||||
|
||||
test(client, fixture)
|
||||
return client
|
||||
}
|
||||
|
||||
// TestLaunchStopOnEntry emulates the message exchange that can be observed with
|
||||
@ -3337,6 +3343,66 @@ func TestBadAttachRequest(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestBadInitializeRequest(t *testing.T) {
|
||||
runInitializeTest := func(args dap.InitializeRequestArguments, err string) {
|
||||
t.Helper()
|
||||
// Only one initialize request is allowed, so use a new server
|
||||
// for each test.
|
||||
client := startDapServer(t)
|
||||
// client.Close will close the client connectinon, which will cause a connection error
|
||||
// on the server side and signal disconnect to unblock Stop() above.
|
||||
defer client.Close()
|
||||
|
||||
client.InitializeRequestWithArgs(args)
|
||||
response := client.ExpectErrorResponse(t)
|
||||
if response.Command != "initialize" {
|
||||
t.Errorf("Command got %q, want \"launch\"", response.Command)
|
||||
}
|
||||
if response.Message != "Failed to initialize" {
|
||||
t.Errorf("Message got %q, want \"Failed to launch\"", response.Message)
|
||||
}
|
||||
if response.Body.Error.Id != 3002 {
|
||||
t.Errorf("Id got %d, want 3002", response.Body.Error.Id)
|
||||
}
|
||||
if response.Body.Error.Format != err {
|
||||
t.Errorf("\ngot %q\nwant %q", response.Body.Error.Format, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Bad path format.
|
||||
runInitializeTest(dap.InitializeRequestArguments{
|
||||
AdapterID: "go",
|
||||
PathFormat: "url", // unsupported 'pathFormat'
|
||||
LinesStartAt1: true,
|
||||
ColumnsStartAt1: true,
|
||||
Locale: "en-us",
|
||||
},
|
||||
"Failed to initialize: Unsupported 'pathFormat' value 'url'.",
|
||||
)
|
||||
|
||||
// LinesStartAt1 must be true.
|
||||
runInitializeTest(dap.InitializeRequestArguments{
|
||||
AdapterID: "go",
|
||||
PathFormat: "path",
|
||||
LinesStartAt1: false, // only 1-based line numbers are supported
|
||||
ColumnsStartAt1: true,
|
||||
Locale: "en-us",
|
||||
},
|
||||
"Failed to initialize: Only 1-based line numbers are supported.",
|
||||
)
|
||||
|
||||
// ColumnsStartAt1 must be true.
|
||||
runInitializeTest(dap.InitializeRequestArguments{
|
||||
AdapterID: "go",
|
||||
PathFormat: "path",
|
||||
LinesStartAt1: true,
|
||||
ColumnsStartAt1: false, // only 1-based column numbers are supported
|
||||
Locale: "en-us",
|
||||
},
|
||||
"Failed to initialize: Only 1-based column numbers are supported.",
|
||||
)
|
||||
}
|
||||
|
||||
func TestBadlyFormattedMessageToServer(t *testing.T) {
|
||||
runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
|
||||
// Send a badly formatted message to the server, and expect it to close the
|
||||
|
Loading…
Reference in New Issue
Block a user