Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashes when trying to query clipboard data size for bitmap format #10

Closed
shepmaster opened this issue Apr 7, 2019 · 8 comments
Closed
Labels

Comments

@shepmaster
Copy link

Attempting to debug copying a bitmap from the clipboard to a file, the crate crashes:

use clipboard_win::{formats, Clipboard}; // 2.1.2

fn main() {
    let c = Clipboard::new().expect("new");

    for f in c.enum_formats() {
        println!("{:?}", f);
    }

    let s = c.size(formats::CF_BITMAP).expect("size");
    let mut data = vec![0; s];
    c.get(formats::CF_BITMAP, &mut data).expect("get");

    std::fs::write("unicorn.bmp", &data).expect("Unable to save");
}
49161
49163
49156
49155
49166
3
8
49171
14
2
17
error: process didn't exit successfully: `target\debug\clip.exe` (exit code: 0xc0000374, STATUS_HEAP_CORRUPTION)

This is on Windows 10 (Version 10.0.17134 Build 17134)

@DoumanAsh
Copy link
Owner

I'll take a look, thanks

@DoumanAsh DoumanAsh added the bug label Apr 7, 2019
@DoumanAsh
Copy link
Owner

Out of curiosity could you sahre the way you place your bmp on clipboard, and the bmp itself?

@DoumanAsh
Copy link
Owner

DoumanAsh commented Apr 7, 2019

Ok, this is weird. According to my investigation CF_BITMAP should just fail because GlobalLock cannot be called on handle for it...
So I'm even more curious how you were able to crash, could you also pinpoint at which function call it crashed?

Also please check the size returned by let s = c.size(formats::CF_BITMAP).expect("size");
It should be 0 in this case

@shepmaster
Copy link
Author

the way you place your bmp on clipboard

I've opened it in Paint, select all, copy.

The bmp itself

unicorn-orig.zip

which function call it crashed

From WinDbg:

0:000> kp
 # Child-SP          RetAddr           Call Site
00 00000032`9fbcf510 00007ffe`5c1ab13a ntdll!RtlDebugGetUserInfoHeap+0xb4
01 00000032`9fbcf580 00007ffe`5ab7762d ntdll!RtlGetUserInfoHeap+0x57c5a
02 00000032`9fbcf5e0 00007ff7`82ba2923 KERNEL32!GlobalSize+0x5d
03 00000032`9fbcf630 00007ff7`82ba2a16 clip_b61affd48d7443fb!clipboard_win::raw::size(unsigned int format = 2)+0x43 [C:\Users\IEUser\.cargo\registry\src\github.com-1ecc6299db9ec823\clipboard-win-2.1.2\src\raw.rs @ 149] 
04 00000032`9fbcf680 00007ff7`82ba1d3e clip_b61affd48d7443fb!clipboard_win::Clipboard::size(struct clipboard_win::Clipboard * self = 0x00000032`9fbcf770, unsigned int format = 2)+0x16 [C:\Users\IEUser\.cargo\registry\src\github.com-1ecc6299db9ec823\clipboard-win-2.1.2\src\lib.rs @ 121] 
05 00000032`9fbcf6d0 00007ff7`82ba1c20 clip_b61affd48d7443fb!clip::main(void)+0xae [C:\rust\clip\src\main.rs @ 22] 
06 00000032`9fbcf850 00007ff7`82bb1d47 clip_b61affd48d7443fb!std::rt::lang_start::{{closure}}<(void)+0x10 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs @ 64] 
07 (Inline Function) --------`-------- clip_b61affd48d7443fb!std::rt::lang_start_internal::{{closure}}+0xc [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs @ 49] 
08 00000032`9fbcf890 00007ff7`82bb4a22 clip_b61affd48d7443fb!std::panicking::try::do_call<closure,i32>(void)+0x17 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs @ 297] 
09 00000032`9fbcf8c0 00007ff7`82bb2572 clip_b61affd48d7443fb!panic_unwind::__rust_maybe_catch_panic(void)+0x22 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libpanic_unwind\lib.rs @ 92] 
0a (Inline Function) --------`-------- clip_b61affd48d7443fb!std::panicking::try+0x33 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs @ 276] 
0b (Inline Function) --------`-------- clip_b61affd48d7443fb!std::panic::catch_unwind+0x33 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panic.rs @ 388] 
0c 00000032`9fbcf920 00007ff7`82ba1bfb clip_b61affd48d7443fb!std::rt::lang_start_internal(void)+0x102 [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs @ 48] 
0d 00000032`9fbcf9c0 00007ff7`82ba1f80 clip_b61affd48d7443fb!std::rt::lang_start<(<function> * main = 0x00007ff7`82ba1c90, int64 argc = 0n1, unsigned char ** argv = 0x000001e8`e6ac37b0)+0x3b [/rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs @ 64] 
0e 00000032`9fbcfa10 00007ff7`82bbd180 clip_b61affd48d7443fb!main+0x20
0f (Inline Function) --------`-------- clip_b61affd48d7443fb!invoke_main+0x22 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
10 00000032`9fbcfa40 00007ffe`5ab73dc4 clip_b61affd48d7443fb!__scrt_common_main_seh(void)+0x10c [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 283] 
11 00000032`9fbcfa80 00007ffe`5c163691 KERNEL32!BaseThreadInitThunk+0x14
12 00000032`9fbcfab0 00000000`00000000 ntdll!RtlUserThreadStart+0x21

@DoumanAsh
Copy link
Owner

DoumanAsh commented Apr 7, 2019

This is actually pretty weird... It crashed in syscall for valid clipboard handle...
To be honest i'm not sure how exactly it is possible, since handle should not null.
I suppose I'll give it a try myself, but it sounds like something I will not be able to fix

On side note, as I mentioned we actually should not be able to get clipboard data for bitmap like that.
It turns out bit map data is stored as handle to Bitmap object, so my current approach with GlobalLock will cause error.
Instead of that I started working on abstractions to get Image data https://github.com/DoumanAsh/clipboard-win/blob/master/src/lib.rs#L168
It is not yet finished, but for now you can access dimensions/size and underlying pixel data

P.s. Copying in Paint reproduces issue easily regardless of image

@DoumanAsh
Copy link
Owner

Ok, after some investigation, I found that MS thinks it is ok to crash GlobalSize on BITMAP handle.

To solve it I could adopt following approaches:

  • Make size unsafe and document that BITMAP will cause crash
  • Make size safe by adding extra checks via GlobalLock that should fail for any invalid for GlobalSize handles

@shepmaster I suppose either wouldn't work for you if you need generic approach to clipboard data, but sadly it is very difficult facilitate generic data retrieval due to how default formats like BITMAP works, so either way you'd need to handle bitmap data specially.

@DoumanAsh
Copy link
Owner

Fixed 750d8ad

If you'd like, verify

@DoumanAsh DoumanAsh changed the title Crashes when trying to enumerate formats Crashes when trying to query clipboard data size for bitmap format Apr 8, 2019
@shepmaster
Copy link
Author

work for you

For what it's worth, I was just answering a Stack Overflow question; I don't have any particular pressing need w.r.t. the Windows clipboard ;-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants