CMD does not show Unix LF when pasting #942

Open
opened 2026-01-30 22:12:03 +00:00 by claunia · 7 comments
Owner

Originally created by @Biswa96 on GitHub (May 10, 2019).

Originally assigned to: @zadjii-msft on GitHub.

  • Build 18890 (18894 on the way...)
  • What doing: Create a file with Unix (LF) line endings. For example,
echo foo
echo bar

Paste it in CMD window. The output is fooecho bar. The output should be in separate lines. Try the same in mintty. It shows correct output.

Originally created by @Biswa96 on GitHub (May 10, 2019). Originally assigned to: @zadjii-msft on GitHub. * Build 18890 (18894 on the way...) * What doing: Create a file with **Unix (LF) line endings**. For example, ```cmd echo foo echo bar ``` Paste it in CMD window. The output is `fooecho bar`. The output should be in separate lines. Try the same in mintty. It shows correct output.
claunia added the Product-ConhostIssue-BugArea-InteractionPriority-2 labels 2026-01-30 22:12:03 +00:00
Author
Owner

@zadjii-msft commented on GitHub (May 10, 2019):

I think this is a notoriously long-standing bug with cmd.exe. @paulcam206 might have more to share on this topic. I'm fairly sure this falls under the category of "we can't change cmd.exe anymore".

I just read the "paste" bit - I'm probably wrong about that above.

@zadjii-msft commented on GitHub (May 10, 2019): ~I think this is a notoriously long-standing bug with cmd.exe. @paulcam206 might have more to share on this topic. I'm fairly sure this falls under the category of "we can't change cmd.exe anymore".~ I just read the "paste" bit - I'm probably wrong about that above.
Author
Owner

@FrankHB commented on GitHub (May 10, 2019):

I agree this should better be fixed, but it can also be a feature :)

I'm working on a REPL which accepts one line per input by default. The language is free-form, which can have multiple lines in the script files. I save some pieces of test code in the script files, and each test case can have more than one lines of code. The LF ending makes more than one lines can be selected together and copied. When they are pasted into the console, the REPL ignores the LF characters, so these lines are automatically concatenated into one. If the bug is fixed, such trick/abuse will be broken.

@FrankHB commented on GitHub (May 10, 2019): I agree this should better be fixed, but it can also be a feature :) I'm working on a REPL which accepts one line per input by default. The language is free-form, which can have multiple lines in the script files. I save some pieces of test code in the script files, and each test case can have more than one lines of code. The LF ending makes more than one lines can be selected together and copied. When they are pasted into the console, the REPL ignores the LF characters, so these lines are automatically concatenated into one. If the bug is fixed, such trick/abuse will be broken.
Author
Owner

@Biswa96 commented on GitHub (Jul 17, 2019):

Any 'official' reply?

@Biswa96 commented on GitHub (Jul 17, 2019): Any 'official' reply?
Author
Owner

@zadjii-msft commented on GitHub (Jul 17, 2019):

I don't know what's at the root of this problem, if it's a recent regression or not, or if it's truly a bug or just "weird things that conhost does that we can't fix cause legacy reasons". I'm throwing it on the 20H1 milestone to make sure someone investigates, though it might be a while. If someone else is passionate about fixing this and would like to dig into why this is happening, power to you :)

@zadjii-msft commented on GitHub (Jul 17, 2019): I don't know what's at the root of this problem, if it's a recent regression or not, or if it's truly a bug or just "weird things that conhost does that we can't fix cause legacy reasons". I'm throwing it on the 20H1 milestone to make sure someone investigates, though it might be a while. If someone else is passionate about fixing this and would like to dig into _why_ this is happening, power to you :)
Author
Owner

@Biswa96 commented on GitHub (Jul 17, 2019):

fixing this and would like to dig into why this is happening

cmd.exe is not open source.

@Biswa96 commented on GitHub (Jul 17, 2019): > fixing this and would like to dig into why this is happening cmd.exe is not open source.
Author
Owner

@zadjii-msft commented on GitHub (Jul 17, 2019):

Yea but conhost is, and conhost is going to be far more valuable in debugging this than cmd.exe.

@zadjii-msft commented on GitHub (Jul 17, 2019): Yea but conhost is, and conhost is going to be _far_ more valuable in debugging this than cmd.exe.
Author
Owner

@zadjii-msft commented on GitHub (Sep 30, 2019):

At first I thought: "this is something that we can't fix because it's legacy cmd madness". But now I'm not so sure.

Lets look at what happens when you try to paste

echo foo
echo bar
echo baz

with only LF line endings:
image

This makes it seem like COOKED_READ in conhost is not properly breaking up the lines on a LF-only paste. In fact, the problem might be even higher, in our reading from the clipboard itself. Let's look at this code, which is responsible for taking the clipboard data and generating INPUT_RECORDs from it:
083be43700/src/interactivity/win32/Clipboard.cpp (L140-L183)

The most interesting bit is on line 171:

     if (IsInVirtualTerminalInputMode() && currentChar == UNICODE_LINEFEED) 
     {
           currentChar = UNICODE_CARRIAGERETURN; 
     } 

When we're in VT input mode (read:wsl), we'll turn single LF characters into a CR before handling the paste. This was in order to solve microsoft/WSL#2006.

If I take out the IsInVirtualTerminalInputMode check, this will fix the cmd scenario:
image

Now the real question is: Is this a safe change? What will this possibly regress? Let's discuss! @miniksa @DHowett-MSFT @carlos-zamora


Also for linking internally: MSFT:20169262 deals with this for batch files, which is almost certainly unsolvable.

@zadjii-msft commented on GitHub (Sep 30, 2019): At first I thought: "this is something that we can't fix because it's legacy cmd madness". But now I'm not so sure. Lets look at what happens when you try to paste ```cmd echo foo echo bar echo baz ``` with only LF line endings: ![image](https://user-images.githubusercontent.com/18356694/65890203-1d593400-e368-11e9-9cbe-340eb883d160.png) This makes it seem like `COOKED_READ` in conhost is not properly breaking up the lines on a LF-only paste. In fact, the problem might be even higher, in our reading from the clipboard itself. Let's look at this code, which is responsible for taking the clipboard data and generating `INPUT_RECORD`s from it: https://github.com/microsoft/terminal/blob/083be43700c01604983a9ff67e9fe6edab8ad0e5/src/interactivity/win32/Clipboard.cpp#L140-L183 The most interesting bit is on line 171: ``` c++ if (IsInVirtualTerminalInputMode() && currentChar == UNICODE_LINEFEED) { currentChar = UNICODE_CARRIAGERETURN; } ``` When we're in VT _input_ mode (read:wsl), we'll turn single LF characters into a CR before handling the paste. This was in order to solve microsoft/WSL#2006. If I take out the `IsInVirtualTerminalInputMode` check, this will fix the cmd scenario: ![image](https://user-images.githubusercontent.com/18356694/65891140-aa50bd00-e369-11e9-99b7-0a708a22b1be.png) Now the real question is: Is this a safe change? What will this possibly regress? Let's discuss! @miniksa @DHowett-MSFT @carlos-zamora <hr> Also for linking internally: MSFT:20169262 deals with this for batch files, which is almost certainly unsolvable.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#942