{"action":"reopened","issue":{"url":"https://api.github.com/repos/Immington-Industries/rust-wlc/issues/13","repository_url":"https://api.github.com/repos/Immington-Industries/rust-wlc","labels_url":"https://api.github.com/repos/Immington-Industries/rust-wlc/issues/13/labels{/name}","comments_url":"https://api.github.com/repos/Immington-Industries/rust-wlc/issues/13/comments","events_url":"https://api.github.com/repos/Immington-Industries/rust-wlc/issues/13/events","html_url":"https://github.com/Immington-Industries/rust-wlc/issues/13","id":135263701,"number":13,"title":"Unsafety in lib.rs","user":{"login":"Stebalien","id":310393,"avatar_url":"https://avatars.githubusercontent.com/u/310393?v=3","gravatar_id":"","url":"https://api.github.com/users/Stebalien","html_url":"https://github.com/Stebalien","followers_url":"https://api.github.com/users/Stebalien/followers","following_url":"https://api.github.com/users/Stebalien/following{/other_user}","gists_url":"https://api.github.com/users/Stebalien/gists{/gist_id}","starred_url":"https://api.github.com/users/Stebalien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Stebalien/subscriptions","organizations_url":"https://api.github.com/users/Stebalien/orgs","repos_url":"https://api.github.com/users/Stebalien/repos","events_url":"https://api.github.com/users/Stebalien/events{/privacy}","received_events_url":"https://api.github.com/users/Stebalien/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Immington-Industries/rust-wlc/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":{"login":"Timidger","id":3515754,"avatar_url":"https://avatars.githubusercontent.com/u/3515754?v=3","gravatar_id":"","url":"https://api.github.com/users/Timidger","html_url":"https://github.com/Timidger","followers_url":"https://api.github.com/users/Timidger/followers","following_url":"https://api.github.com/users/Timidger/following{/other_user}","gists_url":"https://api.github.com/users/Timidger/gists{/gist_id}","starred_url":"https://api.github.com/users/Timidger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Timidger/subscriptions","organizations_url":"https://api.github.com/users/Timidger/orgs","repos_url":"https://api.github.com/users/Timidger/repos","events_url":"https://api.github.com/users/Timidger/events{/privacy}","received_events_url":"https://api.github.com/users/Timidger/received_events","type":"User","site_admin":false},"milestone":null,"comments":1,"created_at":"2016-02-21T21:43:20Z","updated_at":"2016-02-21T23:15:09Z","closed_at":null,"body":"```rust\r\npub fn init(interface: WlcInterface) -> bool {\r\n    unsafe {\r\n        let args: Vec<*const libc::c_char> = env::args().into_iter()\r\n            .map(|arg| arg.as_ptr() as *const libc::c_char ).collect();\r\n\r\n        wlc_init(&interface, args.len() as i32, args.as_ptr() as *const *const libc::c_char)\r\n    }\r\n}\r\n// ...\r\npub fn init_with_args(interface: WlcInterface, args: Vec<String>) -> bool {\r\n    unsafe {\r\n        wlc_init(&interface, args.len() as i32, args.as_ptr() as *const *const libc::c_char)\r\n    }\r\n}\r\n```\r\n\r\n1. The pointers to the arguments become invalid the second you drop the `String`s.\r\n2. These strings are *not* valid C strings (they aren't null terminated). Well, they are in this case but that's just coincidence and could break at any time.\r\n\r\n```rust\r\npub fn exec(bin: String, args: Vec<String>) {\r\n    unsafe {\r\n        let bin_c = CString::new(bin).unwrap().as_ptr() as *const libc::c_char;\r\n\r\n        let argv: Vec<CString> = args.into_iter()\r\n            .map(|arg| CString::new(arg).unwrap() ).collect();\r\n\r\n        let args: Vec<*const libc::c_char> = argv.into_iter()\r\n            .map(|arg: CString| { arg.as_ptr() as *const libc::c_char }).collect();\r\n\r\n        wlc_exec(bin_c, args.as_ptr() as *const *const libc::c_char);\r\n    }\r\n}\r\n```\r\n\r\nAgain, these pointers are invalid after you drop the CStrings themselves.\r\n\r\n\r\n```rust\r\npub fn pointer_to_string(pointer: *const libc::c_char) -> String {\r\n    let slice = unsafe { ffi::CStr::from_ptr(pointer) };\r\n    slice.to_string_lossy().into_owned()\r\n}\r\n```\r\n\r\nThis function really should be marked unsafe. `pointer` could point to anything."}}