Repository navigation
Built-in SSH console sends bare LF on Linux causing stair-step output #301
Description
Built-in SSH console sends bare LF on Linux causing stair-step output
Description
When AutoPlug-Client is running on Linux, output forwarded through the
built-in SSH console is rendered in a "stair-step" pattern.
Each new line moves the cursor down but does not return it to column 0.
Example:
line 1
line 2
line 3
The AutoPlug SSH welcome banner itself is rendered correctly.
Environment
AutoPlug host:
- Linux / Debian (Trixie)
- AutoPlug version: 10.2.0
- Java version: open jdk 25.0.4.1
SSH clients tested:
- Windows OpenSSH
- Debian OpenSSH under WSL2
- Native Debian OpenSSH
The exact same behavior occurs with all three clients.
I previously used AutoPlug on a Windows host and did not encounter this
problem there.
Reproduction
-
Run AutoPlug-Client on Linux with its built-in SSH server enabled.
-
Connect to the AutoPlug SSH port.
-
Execute a command producing multiple lines, for example:
help .help -
The lines progressively move to the right instead of starting at
column 0.
The problem can also be inspected with:
ssh -tt autoplug@server -p PORT | cat -v
The AutoPlug welcome banner contains ^M (CR), while captured/forwarded
console output only contains LF.
Cause
On current master, SSHServerConsoleReceive.start() explicitly writes the
welcome banner using CRLF (\r\n).
Captured console output follows this path:
System.out / System.err
-> ConsoleOutputCapturer
-> SSHManager
-> SSHServerConsoleReceive.broadcast()
-> SSH OutputStream
ConsoleOutputCapturer preserves the original output bytes and SSHManager
forwards the captured String unchanged.
SSHServerConsoleReceive.broadcast() currently only checks whether the
message ends in \n and appends another \n if required. Existing line
endings inside the message are written unchanged to the SSH OutputStream.
On Linux, captured console output normally contains LF (\n) only.
Therefore bare LF is sent to the terminal without a carriage return.
On Windows this problem can be masked because captured console output
may already contain CRLF (\r\n).
This therefore appears to be a platform-independent SSH terminal newline
normalization issue that becomes visible when AutoPlug runs on Unix/Linux.
Suggested minimal fix
Normalize bare LF to CRLF before writing captured output to the SSH
terminal, while preserving existing CRLF sequences.
For example in
SSHServerConsoleReceive.broadcast(String message):
public void broadcast(String message) {
try {
// SSH terminals need CRLF line endings.
// Preserve existing CRLF and convert bare LF to CRLF.
message = message.replace("\r\n", "\n")
.replace("\n", "\r\n");
if (!message.endsWith("\n")) {
message += message.endsWith("\r") ? "\n" : "\r\n";
}
out.write(message.getBytes(StandardCharsets.UTF_8));
out.flush();
} catch (IOException e) {
AL.warn(e);
}
}Using System.lineSeparator() would not solve the issue, because it
returns LF on Linux. The SSH terminal output itself needs to be
normalized.
Activity