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

Properly support skipping of non-mandatory extensions #1066

Merged
merged 5 commits into from
Apr 9, 2024

Conversation

codablock
Copy link
Contributor

See the 2 individual commits.

This fix might cause some existing repos to fail now, because go-git did not properly fail on link extensions (split index). I assume it's fine to fail, as this extension is mandatory anyway and behaviour is actually undefined/buggy when handling of it is skipped.

Fixes: #299

@codablock
Copy link
Contributor Author

Some reasoning behind the first commit:

I looked into how git figures out how many extensions are present and found https://github.com/git/git/blob/master/read-cache.c#L2047. It knows when to stop when EOF - hash_size - header_size is reached. It however knows the file size while performing this check, which is different for go-git inside Decode().

go-git does not know the file size because it is not passed around. I decided to not change this as it would lead to an api-incompatible change. So instead, I decided to perform a peek based test to see if enough bytes are remaining that an extension could possibly be present.

Before this, go-git was relying on the peeked header to not include a valid
4 char string header. While doing this, it did not differentiate between
the errournously read final hash and an unknown extension.

This made it impossible to properly skip unknown optional extensions while
detecting EOF early enough.
Copy link
Member

@pjbgf pjbgf left a comment

Choose a reason for hiding this comment

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

@codablock please add some tests to ensure we don't get regressions in the future.

plumbing/format/index/decoder.go Outdated Show resolved Hide resolved
plumbing/format/index/decoder.go Outdated Show resolved Hide resolved
plumbing/format/index/decoder.go Outdated Show resolved Hide resolved
Before this, go-git would prematurely bail out of extensions processing
when an unknown extension was encountered. This had two issues:

1. It did not account for mandatory (lower case header) extensions
2. It did not properly update the calculated hash, leading to an
   "invalid checksum" error.
@codablock
Copy link
Contributor Author

codablock commented Apr 6, 2024

@pjbgf Handled all the review comments. I also added a test for invalid index hashes and truncated extensions.

@codablock
Copy link
Contributor Author

Test failures seem to be unrelated?

Copy link
Member

@pjbgf pjbgf left a comment

Choose a reason for hiding this comment

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

@codablock nice job, thanks for working on this. 🙇

@pjbgf pjbgf merged commit cd6633c into go-git:master Apr 9, 2024
16 checks passed
@codablock codablock deleted the fix-unknown-extensions branch April 10, 2024 08:02
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.

Worktree.Status() always fail
2 participants