Skip to content

parse: Do not initialize the content in context to NULL#4749

Merged
pks-t merged 1 commit into
libgit2:masterfrom
neithernut:fix-git__linenlen-ub
Aug 16, 2018
Merged

parse: Do not initialize the content in context to NULL#4749
pks-t merged 1 commit into
libgit2:masterfrom
neithernut:fix-git__linenlen-ub

Conversation

@neithernut
Copy link
Copy Markdown
Contributor

@neithernut neithernut commented Aug 4, 2018

String operations in libgit2 are supposed to never receive NULL, e.g. they are not NULL-save. In the case of git__linenlen(), invocation with NULL leads to undefined behavior.

In a git_parse_ctx however, the content field used in these operations was initialized to NULL if the git_parse_ctx_init() was called with NULL for content or 0 for content_len. For the latter case, the initialization function even contained some logic for initializing content with NULL.

This commit mitigates triggering undefined behavior by rewriting the logic. Now content is always initialized to a non-null buffer. Instead of a null buffer, an empty string is used for denoting an empty buffer.

Supersedes #4733. Resolves #4726.

String operations in libgit2 are supposed to never receive `NULL`, e.g.
they are not `NULL`-save. In the case of `git__linenlen()`, invocation
with `NULL` leads to undefined behavior.

In a `git_parse_ctx` however, the `content` field used in these
operations was initialized to `NULL` if the `git_parse_ctx_init()` was
called with `NULL` for `content` or `0` for `content_len`. For the
latter case, the initialization function even contained some logic for
initializing `content` with `NULL`.

This commit mitigates triggering undefined behavior by rewriting the
logic. Now `content` is always initialized to a non-null buffer. Instead
of a null buffer, an empty string is used for denoting an empty buffer.
Comment thread src/parse.c
} else {
ctx->content = "";
ctx->content_len = 0;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, this fixes the issue. I'm wondering though if we should even make it a bug to pass in NULL to git_parse_ctx_init by adding an assert. That'd require us to review all callers, though

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That was my initial idea. In a (non-published) earlier version, I added an assertion for catching calls to git_parse_ctx_init with NULL for context. However, I quickly ran into places where this fails.

For example, functions for parsing stuff built upon git_parse_ctx would also happily pass NULL for context. I even run into a test case explicitly checking for the ability to parse a patch from an empty and a NULL buffer:

cl_git_fail(git_patch_from_buffer(&patch, NULL, 0, NULL));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Huh, so be it then. Thanks for clarifying!

@neithernut
Copy link
Copy Markdown
Contributor Author

Note (to self): from the approaches described in the original PR (#4733), I ended up implementing approach 1 rather than approach 2.

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.

2 participants