WSL icon indicating copy to clipboard operation
WSL copied to clipboard

Clipboard corruption with clip.exe

Open ivenhov opened this issue 6 years ago • 14 comments

ver Microsoft Windows [Version 10.0.18363.592]

WSL distro

daniel@Daniel-Dell-XPS:~$ uname -a
Linux Daniel-Dell-XPS 4.4.0-18362-Microsoft #476-Microsoft Fri Nov 01 16:53:00 PST 2019 x86_64 x86_64 x86_64 GNU/Linux

daniel@Daniel-Dell-XPS:~$ cat /etc/*release (trimmed)
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
  • Test case: Attempting to copy string into clipboard using clip.exe. For certain text (possibly depends on the length) clipboard seems to have corrupt data Examples of the correct and corrupt clipboard (pasted content of the clipboard is on the second line, after the command)

This one fails

daniel@Daniel-Dell-XPS:~$ val="<redacted>"; echo -n $val | clip.exe
daniel@Daniel-Dell-XPS:~$ ㄵ㥢㤶㙥㐭ㅡⴰ㝥〰㔭㑣ⵦ㜹㌸づ㕢ぢぢ

With "x" in front of it, it works OK

daniel@Daniel-Dell-XPS:~$ val="<redacted>"; echo -n $val | clip.exe
daniel@Daniel-Dell-XPS:~$ <redacted>

In command line window it looks like: image

  • What's wrong / what should be happening instead: Expecting text to be copied to clipboard regardless of the text length

Possibly related to: https://github.com/microsoft/WSL/issues/3716

Update: Added explanation of the second line on the command line (based on comment from @therealkenc)

ivenhov avatar Jan 28 '20 13:01 ivenhov

Took a bit to figure out what "fail" meant. You are pasting after the clip. Okay. Confirmed here. Don't know whether it is the same as #3716, which celebrated a birthday last month. Probably.

therealkenc avatar Jan 28 '20 17:01 therealkenc

One liner that is a little more succinct:

$ echo -n "51b969e6" | clip.exe; powershell.exe -noprofile -command Get-Clipboard
ㄵ㥢㤶㙥

The only real difference vs. #3716 is that over there we were working with the thesis a single character was the culprit. Appears the contents of the string (not the length) triggers.

$ echo -n "12345678" | clip.exe; powershell.exe -noprofile -command Get-Clipboard
12345678

These results are independently reproducible, not rando buffer corruption.

Now for the (very bad for us) news. I am pretty convinced the culprit is clip.exe proper. There is nothing in the WSL pipe marshaling that is going to deliberately peek at the string contents. If it was WSL interop, it'd fail but good, regardless of the string.

Winclip meanwhile is consistently correct.

image

Bad because, if this hypothesis is correct, the issue dies dreaded tag external.

therealkenc avatar Jan 29 '20 06:01 therealkenc

Thanks for simplifying the test case and further investigation.

For some bizzare reason in regular CMD

echo 51b969e6623423423 | clip.exe

works as expected, ignoring appended \r\n So it is on the borderline WSL and clip.exe

Regarding Winclip this seeps like the way to go. Is there any way to get hold of compiled version of it?

ivenhov avatar Jan 29 '20 21:01 ivenhov

For some bizzare reason in regular CMD echo 51b969e6623423423 | clip.exe

You're imagining semantic equivalencies because the strings echo and | "look the same". Those two scenarios are not semantically equivalent on too many levels to describe. And this is setting aside that the two aren't even the same syntactically, because of the implied CRLF (lack of -n) in the above CMD scenario. Your OP works fine if you drop the -n.

image

[Not that the CRLF is the point. It isn't. The two scenarios are semantically different with or without the CRLF.]

That said, I (double negative) can't prove there isn't a way for WSL interop to make Windows clip.exe happy (while simultaneously not breaking other things). Likewise there is no way to declare clip.exe's behavior broken, because its behavior can always be deemed correct by fiat.

Regarding Winclip this seeps like the way to go. Is there any way to get hold of compiled version of it?

I got it from here. No endorsement; I don't use it, I just found it in a quick google search yesterday. There are other third-party clip clones out there.

therealkenc avatar Jan 29 '20 22:01 therealkenc

Thank you very much

After more fiddling I got what I wanted (including discarding newline)

$ echo -n 51b969e6623423423 | winclip.exe -c | powershell.exe -noprofile -command Get-Clipboard 51b969e6623423423 $ echo -n 51b969e662342342 | winclip.exe -c | powershell.exe -noprofile -command Get-Clipboard 51b969e662342342

But as you mentioned with clip.exe

$ echo -n 51b969e6623423423 | clip.exe | powershell.exe -noprofile -command Get-Clipboard 51b969e6623423423 $ echo -n 51b969e662342342 | clip.exe | powershell.exe -noprofile -command Get-Clipboard ㄵ㥢㤶㙥㈶㐳㌲㈴

So it seems it is somehow dependent on the length. Or the passed value is interpreted as some sort of encoding? I don't know if that helps solving the issue.

ivenhov avatar Jan 29 '20 23:01 ivenhov

Been using this tool for a bit and so far so good.

Install in Windows side:

dotnet tool install --global utf8clip

then in wsl side: echo -n 51b969e6623423423 | utf8clip.exe; powershell.exe -noprofile -command Get-Clipboard

Gorthog avatar Mar 31 '20 09:03 Gorthog

utf8clip works, and I thank @bluemarsh for providing it, but it's absolutely ridiculous that it's needed. Absolutely ridiculous.

Just add a /UTF8 flag. Or respect locale. Or something. Anything but what you're doing. What encoding is even default? 🤦

https://twitter.com/HW_BEAT_THAT/status/1270200908417167363

ctrlcctrlv avatar Jun 09 '20 03:06 ctrlcctrlv

If WSL is using this escape sequence "\x1b[?1h" probably is what is causing the clipboard corruption. I was using it before in the Linux to restore the terminal, but was causing the clipboard corruption. After I removed it the issue stopped. Only with WSL I still have this issue and perhaps is something like a escape sequence being causing all this.

Edit: This may be a little confused but I mean using a ncurses application the clipboard on WSL doesn't work as expected. In a real Linux, even using VirtualBox, it works well. If anyone wants to check what I intend to demonstrate, please see this PR at https://github.com/migueldeicaza/gui.cs/pull/1319. Thanks.

BDisp avatar May 25 '21 23:05 BDisp

Suddenly it start happening for me few weeks ago... I wonder if there is a working solution? ~I tried to install utf8clip but it is failing on Windows 11~. I found that you can just download binaries and add them to the path. You need .NET Core 3.0 be installed.

Works great! Thanks @Gorthog for suggestion.

host1812 avatar Mar 08 '23 17:03 host1812

This also reproduces similarly with Set-Clipboard via powershell.exe, no matter which UTF-8 encoding parameters I set in PowerShell before invoking it - I don't think Set-Clipboard is just a wrapper around clip.exe, right? (surely it's calling the .NET API for the clipboard or something?)

With WSLg, this is slightly better in that xclip inside WSL is able to read/write the clipboard successfully (xclip -selection clipboard -out, for example), but for some reason I haven't been able to figure out it unrelatedly hangs when you run xclip -selection clipboard -in over SSH (my use case involves setting clipboard contents remotely, and SSH directly to my WSL instance is the only way I've found so far to reliably do so without writing some custom bit of software).

I noticed with emoji, not any particular string (but was also able to reproduce with just 51b969e6 as noted above):

wsl-debian$ clip.exe <<<'🌸'; xclip -selection clipboard -out; echo
🌸

What's interesting IMO is that running the same from Git Bash on my host yields a different result, so unless I've horribly misunderstood, it seems like it's WSL related somehow, but I can't figure out exactly how:

git-bash$ clip.exe <<<'🌸'; debian run xclip -selection clipboard -out; echo
🌸

More fun examples, to show it's clipboard-specific:

wsl-debian$ /mnt/c/Program\ Files/Git/usr/bin/cat.exe <<<'🌸'
🌸
wsl-debian$ powershell.exe '$Input' <<<'🌸'
🌸
wsl-debian$ powershell.exe '$Input | Set-Clipboard' <<<'🌸'; xclip -selection clipboard -out; echo
🌸

Edit: very interestingly, it seems that the clipboard functionality in NeoVim is unaffected (even over SSH), so I guess I just need to stop using xclip or clip.exe, rely on WSLg / DISPLAY=:0 + NeoVim and let this go :sweat_smile:

Edit 2: winning ticket:

$ ssh wsl 'DISPLAY=:0 nvim -Es +%\!xclip\ -out\ -selection\ clipboard\ -in' <<<'🙈'
$ ssh wsl DISPLAY=:0 xclip -selection clipboard -out
🙈

(no idea why nvim running xclip is fine but me running xclip directly hangs :shrug: I dug into the nvim implementation for clipboard handling and it just shells out, so I'm at a loss but happy to have a workaround that doesn't involve installing more tools)

tianon avatar Apr 06 '23 23:04 tianon

I was able to circumvent this issue by appending a null character at the end.

# Bug: clipboard returns 'ㄵ㥢㤶㙥㐭ㅡⴰ㝥〰㔭㑣ⵦ㜹㌸づ㕢ぢぢ'
echo -n 51b969e6-4a10-e700-5c4f-9783e0b5b0b0 | clip.exe
# Fix: clipboard returns '51b969e6-4a10-e700-5c4f-9783e0b5b0b0'
printf "51b969e6-4a10-e700-5c4f-9783e0b5b0b0\x00" | clip.exe

magiblot avatar Sep 25 '23 23:09 magiblot

https://github.com/microsoft/WSL/issues/11047 There was a solution here, setting Beta: Use Unicode UTF-8 for global language support in Windows. Although xclip doesn't work for me at all ...

ferdinandyb avatar May 15 '24 12:05 ferdinandyb

i found a solution via iconv

tree | iconv -f utf8 -t utf16le | clip.exe

jalal-o avatar Feb 17 '25 19:02 jalal-o

Ran into this issue today. Very annoying. Found a workaround. Installed xclip in my WSL Ubuntu. Then piped my command into xclip -selection c

Also works for the snippet @magiblot posted.

So I made an alias in my zsh to not have to type it all the time. alias clip='xclip -selection c'

Cookiezzz avatar May 14 '25 13:05 Cookiezzz