Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class DebugAdapterContext implements IDebugAdapterContext {
private StepFilters stepFilters;
private Path classpathJar = null;
private Path argsfile = null;
private boolean isInitialized = false;

private long shellProcessId = -1;
private long processId = -1;
Expand Down Expand Up @@ -407,4 +408,14 @@ public long getJDWPLatency() {
public void setJDWPLatency(long baseLatency) {
this.jdwpLatency = baseLatency;
}

@Override
public boolean isInitialized() {
return isInitialized;
}

@Override
public void setInitialized(boolean isInitialized) {
this.isInitialized = isInitialized;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 Microsoft Corporation and others.
* Copyright (c) 2017-2022 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -35,7 +35,8 @@ public enum ErrorCode {
EXCEPTION_INFO_FAILURE(1018),
EVALUATION_COMPILE_ERROR(2001),
EVALUATE_NOT_SUSPENDED_THREAD(2002),
HCR_FAILURE(3001);
HCR_FAILURE(3001),
INVALID_DAP_HEADER(3002);

private int id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,8 @@ public interface IDebugAdapterContext {
long getJDWPLatency();

void setJDWPLatency(long baseLatency);

boolean isInitialized();

void setInitialized(boolean isInitialized);
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public CompletableFuture<Messages.Response> handle(Requests.Command command, Req
caps.supportsBreakpointLocationsRequest = true;
caps.supportsStepInTargetsRequest = true;
response.body = caps;
context.setInitialized(true);
return CompletableFuture.completedFuture(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ public List<Command> getTargetCommands() {

@Override
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
if (!context.isInitialized()) {
final String errorMessage = "'launch' request is rejected since the debug session has not been initialized yet.";
logger.log(Level.SEVERE, errorMessage);
return CompletableFuture.completedFuture(
AdapterUtils.setErrorResponse(response, ErrorCode.LAUNCH_FAILURE, errorMessage));
}
LaunchArguments launchArguments = (LaunchArguments) arguments;
Map<String, Object> traceInfo = new HashMap<>();
traceInfo.put("asyncJDWP", context.asyncJDWP());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 Microsoft Corporation and others.
* Copyright (c) 2017-2022 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -33,6 +33,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.microsoft.java.debug.core.adapter.AdapterUtils;
import com.microsoft.java.debug.core.adapter.ErrorCode;
import com.microsoft.java.debug.core.protocol.Events.DebugEvent;

import io.reactivex.disposables.Disposable;
Expand All @@ -54,6 +56,7 @@ public abstract class AbstractProtocolServer implements IProtocolServer {
private ByteBuffer rawData;
private int contentLength = -1;
private AtomicInteger sequenceNumber = new AtomicInteger(1);
private boolean isValidDAPRequest = true;

private PublishSubject<Messages.Response> responseSubject = PublishSubject.<Messages.Response>create();
private PublishSubject<Messages.Request> requestSubject = PublishSubject.<Messages.Request>create();
Expand Down Expand Up @@ -217,7 +220,14 @@ private void processData() {

if (message.type.equals("request")) {
Messages.Request request = JsonUtils.fromJson(messageData, Messages.Request.class);
requestSubject.onNext(request);
if (this.isValidDAPRequest) {
requestSubject.onNext(request);
} else {
Messages.Response response = new Messages.Response(request.seq, request.command);
sendResponse(AdapterUtils.setErrorResponse(response,
ErrorCode.INVALID_DAP_HEADER,
String.format("'%s' request is rejected due to not being a valid DAP message.", request.command)));
}
} else if (message.type.equals("response")) {
Messages.Response response = JsonUtils.fromJson(messageData, Messages.Response.class);
responseSubject.onNext(response);
Expand All @@ -235,10 +245,20 @@ private void processData() {
if (idx != -1) {
Matcher matcher = CONTENT_LENGTH_MATCHER.matcher(rawMessage);
if (matcher.find()) {
this.contentLength = Integer.parseInt(matcher.group(1));
int headerByteLength = rawMessage.substring(0, idx + TWO_CRLF.length())
.getBytes(PROTOCOL_ENCODING).length;
final String contentLengthText = matcher.group(1);
this.contentLength = Integer.parseInt(contentLengthText);
final String headerMessage = rawMessage.substring(0, idx + TWO_CRLF.length());
final int headerByteLength = headerMessage.getBytes(PROTOCOL_ENCODING).length;
this.rawData.removeFirst(headerByteLength); // Remove the header from the raw message.

int expectedHeaderLength = 16 /*"Content-Length: ".length()*/ + contentLengthText.length();
int actualHeaderLength = idx;
if (expectedHeaderLength != actualHeaderLength) {
this.isValidDAPRequest = false;
logger.log(Level.SEVERE, String.format("Illegal DAP request is detected: %s", headerMessage));
} else {
this.isValidDAPRequest = true;
}
continue;
}
}
Expand Down