utils: make sure memchr() is not invoked with NULL#4733
Conversation
|
@stewid: let me know if you want to be named in a |
|
I’m interested in your analysis of this problem. When are we calling this function with a null buffer? Why should we change this and not the caller? |
|
As determined in the referenced issue, there are two callers, both in
Based on this, I considered three options:
If desired, I can either change this PR or file an alternative PR implementing the 2nd of those approaches rather then the 3rd. |
| char *nl = memchr(buffer, '\n', buffer_len); | ||
| char *nl; | ||
|
|
||
| if (!buffer) |
There was a problem hiding this comment.
I think this change is sensible. I'd love to have an assert(buffer || !buffer_len); here, though, such that we can catch programming errors in case anybody calls git__linenlen(NULL, n) with n > 0.
There was a problem hiding this comment.
I added an assertion.
Passing a null pointer as first argument to `memchr()` results in undefined behavior. In practice, this should not be a problem since, within libgit2, `git__linenlen()` will be either called with a non-null `buffer` or with both `buffer` and `buffer_len` being null. Any sane implementation of `memchr()` should return `NULL` in this case without causing any malicious or unintended effects. However, it is still an UB. It will be reported by both dynamic and static UB checkers. Hence, we add this additional check. And while we're at it, we also introduce an assertion to catch calls with a null `buffer` and a non-null `buffer_len`.
28f2749 to
6809f7d
Compare
|
One of the AppVeyor jobs failed due to network problems. It should be sufficient to simply restart the job. |
|
I've restarted the AppVeyor build |
|
Thanks for the analysis, @neithernut. The reason I asked is because few (none?) of our other string helper functions do a null check like this. (I didn't do an exhaustive analysis, I just quickly skimmed |
|
While most (all?) other string functions don't do So this all speaks against my previous thinking. So maybe we should make sure that a parser context is never being initialized with a |
That makes sense to me. |
|
In this case, I'll prepare patches implementing approach 2 (changing |
Passing a null pointer as first argument to
memchr()results inundefined behavior.
In practice, this should not be a problem since, within libgit2,
git__linenlen()will be either called with a non-nullbufferor withboth
bufferandbuffer_lenbeing null. Any sane implementation ofmemchr()should returnNULLin this case without causing anymalicious or unintended effects.
However, it is still an UB. It will be reported by both dynamic and
static UB checkers. Hence, we add this additional check.
Resolves #4726.