Closed bcmyers closed 1 year ago
Thanks for the PR! However, I feel like this isn't correct.
Looking at author()
specifically, the git_signature
is owned by the git_commit
object. The function git_commit__free
takes care of freeing the signature. Although git objects are reference counted, I believe there are scenarios where those internal caches can get cleared which can evict those objects. Once the object is freed, it will free the signature, leaving the Rust Signature
object pointing at already freed memory.
Yep. I think you're right. Thanks for looking into this. I'll close this out.
This PR fixes #895
It is very similar to https://github.com/rust-lang/git2-rs/pull/302, which addressed a similar issue: https://github.com/rust-lang/git2-rs/issues/299
Overview
On the
Commit
struct, there are several "getter" methods where the lifetime of the return object is tied to a borrow ofSelf
:pub fn author(&self) -> Signature<'_> {
pub fn body(&self) -> Option<&str> {
In other words, written without elision, these signatures all look like
pub fn author<'a>(&'a self) -> Signature<'a> {
pub fn body<'a>(&'a self) -> Option<&'a str> {
But the pointers that are returned by these methods all live as long as the
'repo
lifetime if you look at the C code. In other words, they should all have these (more flexible) signatures:There is a very similar problem happening for the "getter" methods of the
Signature
struct.This PR fixes these methods so that they return references with the correct (more flexible) lifetimes.
Motivating example
This code should compile
but fails with
The C code
The equivalent "getter" methods are defined in the underlying C code is here:
The pointers they return live here:
I believe all these pointers live as long as this raw
*mut raw::git_commit
pointer here:which has the
'repo
lifetime.