use super::*; unsafe extern "C" { fn PasteboardSynchronize(pasteboard: Object) -> u32; fn PasteboardGetItemIdentifier(pasteboard: Object, index: isize, item: *mut usize) -> i32; fn PasteboardCopyItemFlavorData( pasteboard: Object, item: usize, flavor: Object, data: *mut Object, ) -> i32; fn CFDataGetBytePtr(data: Object) -> *const u8; fn CFDataGetLength(data: Object) -> isize; } #[test] fn native_publication_preserves_plain_utf8_bytes_on_an_isolated_pasteboard() { // A private pasteboard leaves the user's clipboard untouched. let _pool = unsafe { AutoreleasePool(objc_autoreleasePoolPush()) }; let name = unsafe { Owned::new(CFStringCreateWithCString( ptr::null(), c"vamp-native-clipboard-regression".as_ptr(), 0x0800_0100, )) .unwrap() }; let board = unsafe { let mut board = ptr::null(); check(PasteboardCreate(name.0, &mut board)).unwrap(); Owned::new(board).unwrap() }; let reader = unsafe { let send: unsafe extern "C" fn(Object, Object, Object) -> Object = std::mem::transmute(objc_msgSend as unsafe extern "C" fn()); send( objc_getClass(c"NSPasteboard".as_ptr()), sel_registerName(c"pasteboardWithName:".as_ptr()), name.0, ) }; for text in [ "", "é e\u{301} 👨‍💻\n\0tail", "{\\rtf1 plain text}", "%!PS-Adobe-3.0\nplain", ] { write_to(name.0, text).unwrap(); assert_eq!(read_from(reader).unwrap(), text); unsafe { PasteboardSynchronize(board.0); let mut item = 0; check(PasteboardGetItemIdentifier(board.0, 1, &mut item)).unwrap(); let flavor = Owned::new(CFStringCreateWithCString( ptr::null(), c"public.utf8-plain-text".as_ptr(), 0x0800_0100, )) .unwrap(); let mut data = ptr::null(); check(PasteboardCopyItemFlavorData( board.0, item, flavor.0, &mut data, )) .unwrap(); let data = Owned::new(data).unwrap(); let length = CFDataGetLength(data.0) as usize; let bytes = if length == 0 { &[] } else { std::slice::from_raw_parts(CFDataGetBytePtr(data.0), length) }; assert_eq!(bytes, text.as_bytes()); } } let maximum = "x".repeat(super::super::MAX_CLIPBOARD_BYTES); write_to(name.0, &maximum).unwrap(); assert_eq!(read_from(reader).unwrap(), maximum); write_to(name.0, &(maximum + "x")).unwrap(); assert_eq!( read_from(reader).unwrap_err(), "System clipboard text exceeds 4 MiB" ); }