Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Handle git_buf's from users more liberally #2036

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

Merged
merged 1 commit into from
Jan 8, 2014

Conversation

ethomson
Copy link
Member

@ethomson ethomson commented Jan 8, 2014

When accepting git_bufs as user input (in git_blob_filtered_content), we state that we accept a git_buf that has a ptr value of NULL, but we in fact do not.

From buffer.h:

ptr points to the start of the allocated memory. If it is NULL, then the git_buf is considered empty and libgit2 will feel free to overwrite it with new data.

Thus, consumers tend to create a git_buf where all members are 0. See for example git_buf creation in LibGit2Sharp and in jagged.

However the git_buf family of functions were written thinking that git_bufs would be initialized with GIT_BUF_INIT or git_buf_init, namely that the ptr would always be null-terminated (set to git_buf__initbuf), even when asize was 0. Indeed, this is documented in buffer.c:

Used as default value for git_buf->ptr so that people can always assume ptr is non-NULL and zero terminated even for new git_bufs.

For example git_buf_shorten will always null-terminate. On git_bufs provided from LibGit2Sharp or jagged, this will obviously try to dereference a null pointer.

This basically brings this function in line with the documentation (we accept NULL, converting that internally to a git_buf__initbuf). Obviously we could make more aggressive changes here - we could ensure that users always create git_bufs with some sort of init method, or we could drop the assumption that git_bufs are always null terminated, but those both seem unnecessary and this seems to me like a good middle ground.

@ethomson
Copy link
Member Author

ethomson commented Jan 8, 2014

Sheesh. Has anybody else noticed that my verbosity in the PR comments is inversely proportional to the length of the pull request?

@arthurschreiber
Copy link
Member

@ethomson Case in point: #1007

@@ -84,7 +84,7 @@
* time.
*
* @param blob pointer to the blob
* @return the pointer; NULL if the blob has no contents
Copy link
Member Author

Choose a reason for hiding this comment

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

Oh right. I also updated this comment because it is not accurate!

@arrbee
Copy link
Member

arrbee commented Jan 8, 2014

Looks good to me. I'm a little on the fence if we should be checking the user input using an assert in this case or if we should be using a regular check with giterr_set if the buf content are non-compliant, but it's probably fine.

@arrbee
Copy link
Member

arrbee commented Jan 8, 2014

I assume we'll use this anywhere that we take a buf from the user that they are responsible for having initialized, which I guess means that the filter code doesn't need it now because the buffers in use there are always initialized by libgit2 internally, I believe. Does that seem right?

@scunz
Copy link
Contributor

scunz commented Jan 8, 2014

Obviously we could make more aggressive changes here - we could ensure that users always create git_bufs with some sort of init method, or we could drop the assumption that git_bufs are always null terminated, but those both seem unnecessary and this seems to me like a good middle ground.

Please reconsider the idea of forcing users to initialise git_bufs in the same way other input-structs are initialised. Having lots of similar structured APIs decreases the learning curve a lot. This doesn't look like it's really worth to change the usage pattern here. In other words: writing git_buf buf = GIT_INIT_BUF; seems much more natural (than any other way to init it) in the context of libgit2 API.

@ethomson
Copy link
Member Author

ethomson commented Jan 8, 2014

@scunz The problem isn't git_buf buf = GIT_BUF_INIT for C / C++ users. We can expose that if you want, but it doesn't help authors of bindings that can't take advantage of C macros - in this case, LibGit2Sharp. They need a similar mechanism: to not accept NULL in ptr means that C# users would have to marshal an empty string just to use these functions, which is sort of crazy.

What I meant was an actual git_buf_init function. This is less onerous than the bindings knowing that they have to marshal an empty string for no seemingly good reason. But I would rather not need to do that at all, I would rather just pass a null.

@ethomson
Copy link
Member Author

ethomson commented Jan 8, 2014

I assume we'll use this anywhere that we take a buf from the user that they are responsible for having initialized, which I guess means that the filter code doesn't need it now because the buffers in use there are always initialized by libgit2 internally, I believe. Does that seem right?

This matches my thinking!

@ethomson
Copy link
Member Author

ethomson commented Jan 8, 2014

I like @scunz 's idea of exposing GIT_BUF_INIT to the big bad world. @arrbee any objections? If not, I'll add that to this PR.

@arrbee
Copy link
Member

arrbee commented Jan 8, 2014

My only concern is that will also require exposing git_buf__initbuf and we used to do something similar with attributes and it caused tons of linkage problems. I think there is some complexity with exporting data symbols in a portable manner.

@ethomson
Copy link
Member Author

ethomson commented Jan 8, 2014

Yeah. We could do it with NULL now, instead of with git_buf__initbuf... but only for consumers, and we'd have to have a separate macro for consumers and internal. Bluh. Let's not muddy the sweet, sweet waters of this PR with that quite yet.

vmg pushed a commit that referenced this pull request Jan 8, 2014
Handle git_buf's from users more liberally
@vmg vmg merged commit cc3d961 into libgit2:development Jan 8, 2014
@vmg
Copy link
Member

vmg commented Jan 8, 2014

Looks very clean. Exporting GIT_BUF_INIT is not an option (unfortunately) because git_buf__initbuf is linkage hell. However, we could export an alternative that sets NULL instead.

phatblat pushed a commit to phatblat/libgit2 that referenced this pull request Sep 13, 2014
Handle git_buf's from users more liberally
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.

5 participants