Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Fix patch crash#945

Merged
implausible merged 3 commits intomasternodegit/nodegit:masterfrom
fix-patch-crashnodegit/nodegit:fix-patch-crashCopy head branch name to clipboard
Mar 9, 2016
Merged

Fix patch crash#945
implausible merged 3 commits intomasternodegit/nodegit:masterfrom
fix-patch-crashnodegit/nodegit:fix-patch-crashCopy head branch name to clipboard

Conversation

@joshaber
Copy link
Collaborator

@joshaber joshaber commented Mar 9, 2016

Libgit2 documents that content isn’t NUL-terminated, so we can’t
call strlen on it. If we do, we’ll probably crash.

joshaber added 2 commits March 9, 2016 10:39
Libgit2 documents that the content isn’t NUL-terminated, so we can’t
call strlen on it.
}

if (j == 0) {
// calculate strlen only once for the first line of the first hunk.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't really describe what we were doing, and I'm not sure I understand what we're trying to do. So I'm not sure if this comment was wrong, or the code is wrong 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment means that we don't want to calculate the length of content every iteration of the loop because that is numLinesInContent * strlen iterations. This slows down performance substantially.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my confusion is that (1) it's not like we were re-using the length, and (2) we're doing this for the first line of every hunk, not just the first line of the first hunk as the comment says.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the way that libgit2 represents the content pointer is like this:
Content ptr points to the start of the first line in the hunk, but continues until the end of the file.
content_len is the length of the line that we are looking at in the hunk
\n\ No newline at end of file\n" is located at the end of content ptr (not at content_len).
content ptr continues to the last line of the file because content ptr does not terminate at the end of lines.

What we need to know at any given line is whether there is no new line at the end of the file as this is used in nodegit for staging. When I worked on this feature it was requested that we preserve the api as closely as possible. The best way to preserve the api was to append the no new line flag on the end of lines where we have discovered a file does not contain a new line at the end.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to investigate what a diff line looks like before we finalize this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you're right to be a bit confused. lol.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the comment is completely wrong.

@joshaber
Copy link
Collaborator Author

joshaber commented Mar 9, 2016

This fixes a crash we saw in Atom. The crashlog would look like this:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000125f72000

...

Thread 14 Crashed:
0   libsystem_c.dylib               0x00007fff863db188 strlen + 72
1   nodegit.node                    0x00000001164ef072 createFromRaw(git_patch*) + 525
2   nodegit.node                    0x00000001165b7069 GitPatch::ConvenientFromDiffWorker::Execute() + 153
3   libnode.dylib                   0x0000000110c4c48e 0x110b08000 + 1328270
4   libnode.dylib                   0x0000000110c4c68b 0x110b08000 + 1328779
5   libnode.dylib                   0x0000000110c57189 0x110b08000 + 1372553
6   libsystem_pthread.dylib         0x00007fff968e9c13 _pthread_body + 131
7   libsystem_pthread.dylib         0x00007fff968e9b90 _pthread_start + 168
8   libsystem_pthread.dylib         0x00007fff968e7375 thread_start + 13

@joshaber
Copy link
Collaborator Author

joshaber commented Mar 9, 2016

This is ready 🙏

@johnhaley81
Copy link
Collaborator

@implausible could you also 👀 this?

@implausible
Copy link
Member

This looks good to me 👍. I don't even know how I got to this solution anymore. So huge thanks to Josh for fixing yet another one of my errors. ❤️

implausible added a commit that referenced this pull request Mar 9, 2016
@implausible implausible merged commit bb9d785 into master Mar 9, 2016
@johnhaley81 johnhaley81 deleted the fix-patch-crash branch March 9, 2016 17:12
@implausible
Copy link
Member

@joshaber took a quick walk. I think I understand where I got this wrong now. The no new line flag only matters for the last hunk in the diff. I assumed it was required for every line of every hunk. This is wrong. Thanks again!

@joshaber
Copy link
Collaborator Author

joshaber commented Mar 9, 2016

Ah, I see. Thanks for clarifying @implausible!

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 this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.