# [PATCH 1/2] notes: clean up confusing NULL checks in init_notes()

5 messages from 2023-04-22 to 2023-04-24. Participants: Jeff King, Junio C Hamano.
Thread: https://gitlist.dev/t/59634

## Jeff King, 2023-04-22 13:55

Subject: [PATCH 1/2] notes: clean up confusing NULL checks in init_notes()
Message-ID: <20230422135543.GA3942829@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20230422135543.GA3942829%40coredump.intra.peff.net
In-Reply-To: <20230422135455.GA3942740@coredump.intra.peff.net>

```
Coverity complains that we check whether "notes_ref" is NULL, but it was
already implied to be non-NULL earlier in the function. And this is
true; since b9342b3fd63 (refs: add array of ref namespaces, 2022-08-05),
we call xstrdup(notes_ref) unconditionally, which would segfault if it
was NULL.

But that commit is actually doing the right thing. Even if NULL is
passed into the function, we'll use default_notes_ref() as a fallback,
which will never return NULL (it tries a few options, but its last
resort is a string literal). Ironically, the "!notes_ref" check was
added by the same commit that added the fallback: 709f79b0894 (Notes
API: init_notes(): Initialize the notes tree from the given notes ref,
2010-02-13). So this check never did anything.

Signed-off-by: Jeff King <peff@peff.net>
---
 notes.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/notes.c b/notes.c
index 45fb7f22d1..cadb435056 100644
--- a/notes.c
+++ b/notes.c
@@ -1019,13 +1019,13 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
 	t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
 	t->first_non_note = NULL;
 	t->prev_non_note = NULL;
-	t->ref = xstrdup_or_null(notes_ref);
+	t->ref = xstrdup(notes_ref);
 	t->update_ref = (flags & NOTES_INIT_WRITABLE) ? t->ref : NULL;
 	t->combine_notes = combine_notes;
 	t->initialized = 1;
 	t->dirty = 0;
 
-	if (flags & NOTES_INIT_EMPTY || !notes_ref ||
+	if (flags & NOTES_INIT_EMPTY ||
 	    repo_get_oid_treeish(the_repository, notes_ref, &object_oid))
 		return;
 	if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid))
-- 
2.40.0.653.g15ca972062


```

## Jeff King, 2023-04-22 13:54

Subject: [PATCH 0/2] coverity null-check fixes
Message-ID: <20230422135455.GA3942740@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20230422135455.GA3942740%40coredump.intra.peff.net

```
Here are two cases I happened to notice via Coverity. Neither produces
a user-visible bug; it's just slightly misleading code which can be
cleaned up.

The first one is ancient, but since the nearby code changed, Coverity
considered it new. :)

The second one is actually recent; I noted it already on the list, but
it was already in 'next' at that point and is now in 'master'.

-Peff

```

## Jeff King, 2023-04-22 13:56

Subject: [PATCH 2/2] fetch_bundle_uri(): drop pointless NULL check
Message-ID: <20230422135646.GA3942917@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20230422135646.GA3942917%40coredump.intra.peff.net
In-Reply-To: <20230422135455.GA3942740@coredump.intra.peff.net>

```
We check if "uri" is NULL, but it cannot be since we'd have segfaulted
earlier in the function when we unconditionally called xstrdup() on it.

In theory we might want to soften that xstrdup() to handle this case,
but even before the code which added it via c23f592117 (bundle-uri:
fetch a list of bundles, 2022-10-12), we'd have fed NULL to
fetch_bundle_uri_internal(), which would also segfault.

The extra check isn't hurting anything, but it does cause Coverity to
complain, and it may mislead somebody reading the code into thinking
that a NULL uri is something we're prepared to handle.

Signed-off-by: Jeff King <peff@peff.net>
---
 bundle-uri.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bundle-uri.c b/bundle-uri.c
index e2b267cc02..f22490a2ca 100644
--- a/bundle-uri.c
+++ b/bundle-uri.c
@@ -795,10 +795,10 @@ int fetch_bundle_uri(struct repository *r, const char *uri,
 	init_bundle_list(&list);
 
 	/*
-	 * Do not fetch a NULL or empty bundle URI. An empty bundle URI
+	 * Do not fetch an empty bundle URI. An empty bundle URI
 	 * could signal that a configured bundle URI has been disabled.
 	 */
-	if (!uri || !*uri) {
+	if (!*uri) {
 		result = 0;
 		goto cleanup;
 	}
-- 
2.40.0.653.g15ca972062

```

## Junio C Hamano, 2023-04-24 18:05

Subject: Re: [PATCH 1/2] notes: clean up confusing NULL checks in init_notes()
Message-ID: <xmqqttx5duki.fsf@gitster.g>
URL: https://gitlist.dev/e/xmqqttx5duki.fsf%40gitster.g
In-Reply-To: <20230422135543.GA3942829@coredump.intra.peff.net>

```
Jeff King <peff@peff.net> writes:

> Coverity complains that we check whether "notes_ref" is NULL, but it was
> already implied to be non-NULL earlier in the function. And this is
> true; since b9342b3fd63 (refs: add array of ref namespaces, 2022-08-05),
> we call xstrdup(notes_ref) unconditionally, which would segfault if it
> was NULL.
>
> But that commit is actually doing the right thing. Even if NULL is
> passed into the function, we'll use default_notes_ref() as a fallback,
> which will never return NULL (it tries a few options, but its last
> resort is a string literal). Ironically, the "!notes_ref" check was
> added by the same commit that added the fallback: 709f79b0894 (Notes
> API: init_notes(): Initialize the notes tree from the given notes ref,
> 2010-02-13). So this check never did anything.

I am impressed(?) that Coverity can complain at the "_or_null" part
in xstrdup_or_null().

It all makes sense.  Thanks.

> Signed-off-by: Jeff King <peff@peff.net>
> ---
>  notes.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/notes.c b/notes.c
> index 45fb7f22d1..cadb435056 100644
> --- a/notes.c
> +++ b/notes.c
> @@ -1019,13 +1019,13 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
>  	t->root = (struct int_node *) xcalloc(1, sizeof(struct int_node));
>  	t->first_non_note = NULL;
>  	t->prev_non_note = NULL;
> -	t->ref = xstrdup_or_null(notes_ref);
> +	t->ref = xstrdup(notes_ref);
>  	t->update_ref = (flags & NOTES_INIT_WRITABLE) ? t->ref : NULL;
>  	t->combine_notes = combine_notes;
>  	t->initialized = 1;
>  	t->dirty = 0;
>  
> -	if (flags & NOTES_INIT_EMPTY || !notes_ref ||
> +	if (flags & NOTES_INIT_EMPTY ||
>  	    repo_get_oid_treeish(the_repository, notes_ref, &object_oid))
>  		return;
>  	if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid))

```

## Jeff King, 2023-04-24 21:57

Subject: Re: [PATCH 1/2] notes: clean up confusing NULL checks in init_notes()
Message-ID: <20230424215719.GA3998354@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20230424215719.GA3998354%40coredump.intra.peff.net
In-Reply-To: <xmqqttx5duki.fsf@gitster.g>

```
On Mon, Apr 24, 2023 at 11:05:49AM -0700, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > Coverity complains that we check whether "notes_ref" is NULL, but it was
> > already implied to be non-NULL earlier in the function. And this is
> > true; since b9342b3fd63 (refs: add array of ref namespaces, 2022-08-05),
> > we call xstrdup(notes_ref) unconditionally, which would segfault if it
> > was NULL.
> >
> > But that commit is actually doing the right thing. Even if NULL is
> > passed into the function, we'll use default_notes_ref() as a fallback,
> > which will never return NULL (it tries a few options, but its last
> > resort is a string literal). Ironically, the "!notes_ref" check was
> > added by the same commit that added the fallback: 709f79b0894 (Notes
> > API: init_notes(): Initialize the notes tree from the given notes ref,
> > 2010-02-13). So this check never did anything.
> 
> I am impressed(?) that Coverity can complain at the "_or_null" part
> in xstrdup_or_null().

No, my human brain added that part while I was looking at the function.

Coverity is definitely clever enough to realize that the NULL check in
xstrdup_or_null() is not needed here (it's a static inline, but I think
Coverity can even look between translation units). But complaining about
it would yield lots of false positives. It's redundant in this instance,
but not in other callers of the function.

So it would have to realize: we called xstrdup_or_null(), but there is
another function xstrdup() which is exactly the same but without the
NULL check. And I think that is asking too much of even a very clever
static analyzer. :)

-Peff

```
