git2-rs icon indicating copy to clipboard operation
git2-rs copied to clipboard

DiffLine mangled memory

Open FintanH opened this issue 9 months ago • 1 comments

I've come across a strange issue where the use of a DiffLine in two different locations ends up with some mangled looking output. I've created a reproducible in this repository https://github.com/FintanH/git2-diff-memory. If you cargo run you should see the following output:

PRINT FROM INSIDE find_lines
- h2 {
+ .event {
    margin-bottom: 1rem;
  }
- .event {
+ h2 {
    margin-bottom: 1rem;
+   padding: 1px;
  }
  hr {
    margin: 1rem 0;
PRINT FROM OUTSIDE find_lines
�H��U  >�r��Sn-bottom: 1rem;
  }
- .event {
+ h2 {
    margin-bottom: 1rem;
+   padding: 1px;
  }
  hr {
    margin: 1rem 0;

Afaict, the outputs should be equal – the range of lines is not different so it should not be selecting other data. My best guess is that the raw pointer within the DiffLine is getting corrupted somehow by returning it within the Vec.

Let me know if I can provide anymore info to help 😊

FintanH avatar Mar 04 '25 17:03 FintanH

I've added another commit where only the content is returned as &'a [u8], and it still ends up with the same output. However, if that's changed to a Vec<u8> it's safe and the outputs are the same.

FintanH avatar Mar 04 '25 17:03 FintanH

Thanks for the report! I have opened a fix at https://github.com/rust-lang/git2-rs/pull/1141.

ehuss avatar Mar 12 '25 15:03 ehuss

Nice 🙏 Have you tested it on the example repo I posted or would you like me to? 😊

FintanH avatar Mar 12 '25 15:03 FintanH

Yea, I tested it. It will now fail to compile because of the lifetimes. You'll need to copy the buffers if you want it to outlive the Patch, or change it so that the Patch is not dropped before the buffers.

ehuss avatar Mar 12 '25 15:03 ehuss

Ah, that makes sense 👌 Thanks for the explanation!

FintanH avatar Mar 12 '25 16:03 FintanH