-
Notifications
You must be signed in to change notification settings - Fork 280
transpile: Do not leak main argument strings
#1447
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
base: master
Are you sure you want to change the base?
Conversation
e309b65 to
e10b712
Compare
kkysen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a snapshot test for this, too?
326ac44 to
ba0f652
Compare
kkysen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, can you also do the thing where the snapshot test is added first before the fix, then updated along with the fix? Thanks!
| let mut args_strings: Vec<Vec<u8>> = ::std::env::args() | ||
| .map(|arg| { | ||
| ::std::ffi::CString::new(arg) | ||
| .expect("Failed to convert argument into CString.") | ||
| .into_bytes_with_nul() | ||
| }) | ||
| .collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to store a Vec<CString> here. It's clearer what it's supposed to represent that way, and we can call CString::raw on it (c_string.into_raw().cast::<c_char>()).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that would reintroduce the leak. I used Vec<u8> because it lets you get a mutable reference without leaking, which CString does not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How exactly? I might've not been clear enough. I'm suggesting we store args_strings: Vec<CString> and args_ptrs: Vec<*mut c_char>. CString is owning just like Vec<u8> is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But how do you get from CString to *mut c_char?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, .into_raw() is wrong since it takes self. But you can use .as_ptr() from CStr that takes &self.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That gives you an immutable pointer, and casting that to mutable could introduce UB if the user code writes to it.
mainleaks memory ofargs#649.I opted to store the final strings as
Vec<u8>rather than asCString, because the latter does not have a way to get a mutable pointer/reference without leaking it. This is because of the nul termination invariant thatCStringmust uphold.