Skip to content

Commit 6e294e1

Browse files
Reject invalid DAP request (#466)
1 parent e0f2bd2 commit 6e294e1

File tree

6 files changed

+50
-7
lines changed

6 files changed

+50
-7
lines changed

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class DebugAdapterContext implements IDebugAdapterContext {
5656
private StepFilters stepFilters;
5757
private Path classpathJar = null;
5858
private Path argsfile = null;
59+
private boolean isInitialized = false;
5960

6061
private long shellProcessId = -1;
6162
private long processId = -1;
@@ -407,4 +408,14 @@ public long getJDWPLatency() {
407408
public void setJDWPLatency(long baseLatency) {
408409
this.jdwpLatency = baseLatency;
409410
}
411+
412+
@Override
413+
public boolean isInitialized() {
414+
return isInitialized;
415+
}
416+
417+
@Override
418+
public void setInitialized(boolean isInitialized) {
419+
this.isInitialized = isInitialized;
420+
}
410421
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ErrorCode.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Microsoft Corporation and others.
2+
* Copyright (c) 2017-2022 Microsoft Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -35,7 +35,8 @@ public enum ErrorCode {
3535
EXCEPTION_INFO_FAILURE(1018),
3636
EVALUATION_COMPILE_ERROR(2001),
3737
EVALUATE_NOT_SUSPENDED_THREAD(2002),
38-
HCR_FAILURE(3001);
38+
HCR_FAILURE(3001),
39+
INVALID_DAP_HEADER(3002);
3940

4041
private int id;
4142

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,8 @@ public interface IDebugAdapterContext {
154154
long getJDWPLatency();
155155

156156
void setJDWPLatency(long baseLatency);
157+
158+
boolean isInitialized();
159+
160+
void setInitialized(boolean isInitialized);
157161
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public CompletableFuture<Messages.Response> handle(Requests.Command command, Req
6767
caps.supportsBreakpointLocationsRequest = true;
6868
caps.supportsStepInTargetsRequest = true;
6969
response.body = caps;
70+
context.setInitialized(true);
7071
return CompletableFuture.completedFuture(response);
7172
}
7273
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ public List<Command> getTargetCommands() {
7777

7878
@Override
7979
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
80+
if (!context.isInitialized()) {
81+
final String errorMessage = "'launch' request is rejected since the debug session has not been initialized yet.";
82+
logger.log(Level.SEVERE, errorMessage);
83+
return CompletableFuture.completedFuture(
84+
AdapterUtils.setErrorResponse(response, ErrorCode.LAUNCH_FAILURE, errorMessage));
85+
}
8086
LaunchArguments launchArguments = (LaunchArguments) arguments;
8187
Map<String, Object> traceInfo = new HashMap<>();
8288
traceInfo.put("asyncJDWP", context.asyncJDWP());

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Microsoft Corporation and others.
2+
* Copyright (c) 2017-2022 Microsoft Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -33,6 +33,8 @@
3333
import java.util.regex.Matcher;
3434
import java.util.regex.Pattern;
3535

36+
import com.microsoft.java.debug.core.adapter.AdapterUtils;
37+
import com.microsoft.java.debug.core.adapter.ErrorCode;
3638
import com.microsoft.java.debug.core.protocol.Events.DebugEvent;
3739

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

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

218221
if (message.type.equals("request")) {
219222
Messages.Request request = JsonUtils.fromJson(messageData, Messages.Request.class);
220-
requestSubject.onNext(request);
223+
if (this.isValidDAPRequest) {
224+
requestSubject.onNext(request);
225+
} else {
226+
Messages.Response response = new Messages.Response(request.seq, request.command);
227+
sendResponse(AdapterUtils.setErrorResponse(response,
228+
ErrorCode.INVALID_DAP_HEADER,
229+
String.format("'%s' request is rejected due to not being a valid DAP message.", request.command)));
230+
}
221231
} else if (message.type.equals("response")) {
222232
Messages.Response response = JsonUtils.fromJson(messageData, Messages.Response.class);
223233
responseSubject.onNext(response);
@@ -235,10 +245,20 @@ private void processData() {
235245
if (idx != -1) {
236246
Matcher matcher = CONTENT_LENGTH_MATCHER.matcher(rawMessage);
237247
if (matcher.find()) {
238-
this.contentLength = Integer.parseInt(matcher.group(1));
239-
int headerByteLength = rawMessage.substring(0, idx + TWO_CRLF.length())
240-
.getBytes(PROTOCOL_ENCODING).length;
248+
final String contentLengthText = matcher.group(1);
249+
this.contentLength = Integer.parseInt(contentLengthText);
250+
final String headerMessage = rawMessage.substring(0, idx + TWO_CRLF.length());
251+
final int headerByteLength = headerMessage.getBytes(PROTOCOL_ENCODING).length;
241252
this.rawData.removeFirst(headerByteLength); // Remove the header from the raw message.
253+
254+
int expectedHeaderLength = 16 /*"Content-Length: ".length()*/ + contentLengthText.length();
255+
int actualHeaderLength = idx;
256+
if (expectedHeaderLength != actualHeaderLength) {
257+
this.isValidDAPRequest = false;
258+
logger.log(Level.SEVERE, String.format("Illegal DAP request is detected: %s", headerMessage));
259+
} else {
260+
this.isValidDAPRequest = true;
261+
}
242262
continue;
243263
}
244264
}

0 commit comments

Comments
 (0)