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

Segmentation fault when collecting config entries in vector #836

Closed
fin-ger opened this issue Apr 30, 2022 · 3 comments · Fixed by #854
Closed

Segmentation fault when collecting config entries in vector #836

fin-ger opened this issue Apr 30, 2022 · 3 comments · Fixed by #854

Comments

@fin-ger
Copy link

fin-ger commented Apr 30, 2022

Hi,

the below code snipped creates a segmentation fault:

fn main() {
    let repo = git2::Repository::open(".").unwrap();
    let config = repo.config().unwrap();
    let entries_iter = config.entries(None).unwrap();
    let entries: Vec<_> = entries_iter.map(Result::unwrap).collect();

    for entry in &entries {
        println!("name: {}", entry.name().unwrap());
    }
}

Output:

$ ./target/debug/git-segfault
[1]    498461 segmentation fault (core dumped)

The issue appears when collecting the entries of ConfigEntries and then iterating over them. The following code works just fine:

fn main() {
    let repo = git2::Repository::open(".").unwrap();
    let config = repo.config().unwrap();

    for entry in &config.entries(None).unwrap() {
        println!("name: {}", entry.unwrap().name().unwrap());
    }
}

Thank you for any help!

@ehuss
Copy link
Contributor

ehuss commented Apr 30, 2022

Thanks for the report. I have filed an upstream issue at libgit2/libgit2#6289 with what I think is the issue. Either we are misusing the git iterator API, or there is an issue in its implementation.

@ehuss
Copy link
Contributor

ehuss commented Jun 29, 2022

@alexcrichton Looks like upstream has defined it that config entries cannot live between successive calls to next. Unfortunately, AFAIK, that is incompatible with Rust's iterator interface. Do you have any ideas or preferences on how to fix this? Some thoughts that I've had:

  • Add a new entries_cb function to Config that takes a callback instead of returning an iterator.
  • Use something like streaming_iterator (I don't want to add a dependency for this, just tossing out options)
  • Wait for GATs to stabilize…
  • Mark entries as unsafe and document the restriction.
  • Clone the name and value.

None of these seem particularly appealing to me (most are not serious suggestions).

@alexcrichton
Copy link
Member

alexcrichton commented Jun 30, 2022

Could the iterator returned perhaps get its Iterator removed but still have a next method with a "fixed signature"? (e.g. it borrows the &mut self and threads that through to the ConfigEntry, preventing next again if ConfigEntry is active)

That at least paves the way for someone to later build any of the above interfaces (minus the unsafe variant). This is a pretty low-level library so while ergonomics are nice they don't seem like they're of the utmost importance.

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

Successfully merging a pull request may close this issue.

3 participants