Commit d1bfe614aa20a0bdaf76c6d418176320ab11baf4

Julian Ganz 2018-08-04T19:30:40

parse: Do not initialize the content in context to NULL 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.

diff --git a/src/parse.c b/src/parse.c
index 6b8902c..b04fda3 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -8,12 +8,14 @@
 
 int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_len)
 {
-	if (content_len)
+	if (content && content_len) {
 		ctx->content = content;
-	else
-		ctx->content = NULL;
+		ctx->content_len = content_len;
+	} else {
+		ctx->content = "";
+		ctx->content_len = 0;
+	}
 
-	ctx->content_len = content_len;
 	ctx->remain = ctx->content;
 	ctx->remain_len = ctx->content_len;
 	ctx->line = ctx->remain;
@@ -26,6 +28,7 @@ int git_parse_ctx_init(git_parse_ctx *ctx, const char *content, size_t content_l
 void git_parse_ctx_clear(git_parse_ctx *ctx)
 {
 	memset(ctx, 0, sizeof(*ctx));
+	ctx->content = "";
 }
 
 void git_parse_advance_line(git_parse_ctx *ctx)