Skip to content

Commit 44ecffa

Browse files
committed
fix: broken FilterInputStream in StreamConnectionProvider#forwardCopyTo
1 parent 509dc6f commit 44ecffa

2 files changed

Lines changed: 95 additions & 13 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025
3+
* This program and the accompanying materials are made
4+
* available under the terms of the Eclipse Public License 2.0
5+
* which is available at https://www.eclipse.org/legal/epl-2.0/
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*******************************************************************************/
9+
package org.eclipse.lsp4e.test.server;
10+
11+
import static java.nio.charset.StandardCharsets.UTF_8;
12+
import static org.junit.Assert.*;
13+
14+
import java.io.ByteArrayInputStream;
15+
import java.io.ByteArrayOutputStream;
16+
import java.io.IOException;
17+
import java.io.InputStream;
18+
import java.io.OutputStream;
19+
import java.net.URI;
20+
21+
import org.eclipse.lsp4e.server.StreamConnectionProvider;
22+
import org.eclipse.lsp4j.jsonrpc.messages.Message;
23+
import org.eclipse.lsp4j.services.LanguageServer;
24+
import org.junit.Test;
25+
26+
public class StreamConnectionProviderTest {
27+
28+
private static StreamConnectionProvider newProvider() {
29+
return new StreamConnectionProvider() {
30+
@Override
31+
public void start() throws IOException {
32+
}
33+
34+
@Override
35+
public InputStream getInputStream() {
36+
return null;
37+
}
38+
39+
@Override
40+
public OutputStream getOutputStream() {
41+
return null;
42+
}
43+
44+
@Override
45+
public InputStream getErrorStream() {
46+
return null;
47+
}
48+
49+
@Override
50+
public void stop() {
51+
}
52+
53+
@Override
54+
public void handleMessage(Message message, LanguageServer languageServer, URI rootURI) {
55+
}
56+
};
57+
}
58+
59+
@Test
60+
public void test_forwardCopy_singleByteRead_writesToProvidedOutput() throws Exception {
61+
final var input = new ByteArrayInputStream("ABC".getBytes(UTF_8));
62+
final var sink = new ByteArrayOutputStream();
63+
64+
try (InputStream forwarding = newProvider().forwardCopyTo(input, sink)) {
65+
while ((forwarding.read()) != -1) {
66+
// read one byte at a time to exercise single-byte read path
67+
}
68+
}
69+
assertEquals("expected input to be forwarded to provided OutputStream", "ABC", sink.toString(UTF_8));
70+
}
71+
72+
@Test
73+
public void test_forwardCopy_readArray_onEOF_returnsMinusOne_noException() throws Exception {
74+
final var emptyInput = new ByteArrayInputStream(new byte[0]);
75+
final var sink = new ByteArrayOutputStream();
76+
77+
try (final var forwarding = newProvider().forwardCopyTo(emptyInput, sink)) {
78+
final var buf = new byte[8];
79+
int n = forwarding.read(buf); // should be -1 and not throw
80+
assertEquals("expected EOF (-1) on empty stream", -1, n);
81+
}
82+
assertArrayEquals(new byte[0], sink.toByteArray());
83+
}
84+
}

org.eclipse.lsp4e/src/org/eclipse/lsp4e/server/StreamConnectionProvider.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,25 +75,23 @@ public interface StreamConnectionProvider {
7575
@Override
7676
public int read() throws IOException {
7777
int res = super.read();
78-
System.err.print((char) res);
78+
if (res == -1) {
79+
return -1;
80+
}
81+
output.write(res);
7982
return res;
8083
}
8184

8285
@Override
8386
public int read(byte[] b, int off, int len) throws IOException {
8487
int bytes = super.read(b, off, len);
85-
final var payload = new byte[bytes];
86-
System.arraycopy(b, off, payload, 0, bytes);
87-
output.write(payload, 0, payload.length);
88-
return bytes;
89-
}
90-
91-
@Override
92-
public int read(byte[] b) throws IOException {
93-
int bytes = super.read(b);
94-
final var payload = new byte[bytes];
95-
System.arraycopy(b, 0, payload, 0, bytes);
96-
output.write(payload, 0, payload.length);
88+
if (bytes == -1) {
89+
return -1;
90+
}
91+
if (bytes == 0) {
92+
return 0;
93+
}
94+
output.write(b, off, bytes);
9795
return bytes;
9896
}
9997
};

0 commit comments

Comments
 (0)